diff --git a/.codespell.ignorewords b/.codespell.ignorewords index 7303d5d652f..3345662f2c5 100644 --- a/.codespell.ignorewords +++ b/.codespell.ignorewords @@ -8,3 +8,4 @@ wit aks immediatedly te +NotIn diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0886364fb0b..677037e699a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -35,9 +35,9 @@ updates: patterns: - "actions/upload-artifact" - "actions/download-artifact" - + # release branch N targets -- target-branch: release-1.28 +- target-branch: release-1.30 package-ecosystem: "gomod" directory: "/" schedule: @@ -57,7 +57,7 @@ updates: k8s-dependencies: patterns: - "k8s.io/*" -- target-branch: release-1.28 +- target-branch: release-1.30 package-ecosystem: "github-actions" directory: "/" schedule: @@ -80,7 +80,7 @@ updates: - "actions/download-artifact" # release branch N-1 targets -- target-branch: release-1.27 +- target-branch: release-1.29 package-ecosystem: "gomod" directory: "/" schedule: @@ -100,7 +100,7 @@ updates: k8s-dependencies: patterns: - "k8s.io/*" -- target-branch: release-1.27 +- target-branch: release-1.29 package-ecosystem: "github-actions" directory: "/" schedule: @@ -123,7 +123,7 @@ updates: - "actions/download-artifact" # release branch N-2 targets -- target-branch: release-1.26 +- target-branch: release-1.28 package-ecosystem: "gomod" directory: "/" schedule: @@ -143,7 +143,7 @@ updates: k8s-dependencies: patterns: - "k8s.io/*" -- target-branch: release-1.26 +- target-branch: release-1.28 package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/workflows/build_daily.yaml b/.github/workflows/build_daily.yaml index 02352e572e6..1c39e731ef3 100644 --- a/.github/workflows/build_daily.yaml +++ b/.github/workflows/build_daily.yaml @@ -12,17 +12,16 @@ permissions: env: GOPROXY: https://proxy.golang.org/ - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - GO_VERSION: 1.22.1 + GO_VERSION: 1.22.5 jobs: e2e-contour-xds: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -32,7 +31,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -46,19 +45,13 @@ jobs: CONTOUR_E2E_XDS_SERVER_TYPE: contour run: | make setup-kind-cluster run-e2e cleanup-kind - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} e2e-envoy-deployment: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -68,7 +61,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -82,19 +75,13 @@ jobs: CONTOUR_E2E_ENVOY_DEPLOYMENT_MODE: deployment run: | make setup-kind-cluster run-e2e cleanup-kind - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} e2e-ipv6: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -104,7 +91,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -121,19 +108,13 @@ jobs: make setup-kind-cluster export CONTOUR_E2E_LOCAL_HOST=$(ifconfig | grep inet6 | grep global | head -n1 | awk '{print $2}') make run-e2e cleanup-kind - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} - e2e-endpoint-slices: + e2e-endpoints: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -143,7 +124,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -154,12 +135,6 @@ jobs: - name: e2e tests env: CONTOUR_E2E_IMAGE: ghcr.io/projectcontour/contour:main - CONTOUR_E2E_USE_ENDPOINT_SLICES: true + CONTOUR_E2E_USE_ENDPOINTS: true run: | make setup-kind-cluster run-e2e cleanup-kind - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} diff --git a/.github/workflows/build_main.yaml b/.github/workflows/build_main.yaml index 18d02090b80..ecf0917579d 100644 --- a/.github/workflows/build_main.yaml +++ b/.github/workflows/build_main.yaml @@ -8,24 +8,21 @@ on: permissions: contents: read -env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - jobs: build: runs-on: ubuntu-latest permissions: packages: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 with: version: latest - name: Log in to GHCR - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -38,9 +35,3 @@ jobs: PUSH_IMAGE: "true" run: | make multiarch-build - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: failure() diff --git a/.github/workflows/build_tag.yaml b/.github/workflows/build_tag.yaml index 5512a15626f..bd80d060200 100644 --- a/.github/workflows/build_tag.yaml +++ b/.github/workflows/build_tag.yaml @@ -18,8 +18,7 @@ permissions: env: GOPROXY: https://proxy.golang.org/ - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - GO_VERSION: 1.22.1 + GO_VERSION: 1.22.5 jobs: build: @@ -27,15 +26,15 @@ jobs: permissions: packages: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 with: version: latest - name: Log in to GHCR - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -46,20 +45,14 @@ jobs: TAG_LATEST: "false" run: | ./hack/actions/build-and-push-release-images.sh - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: failure() gateway-conformance-report: runs-on: ubuntu-latest needs: [build] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -69,7 +62,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -84,13 +77,7 @@ jobs: export CONTOUR_E2E_IMAGE="ghcr.io/projectcontour/contour:$(git describe --tags)" make setup-kind-cluster run-gateway-conformance cleanup-kind - name: Upload gateway conformance report - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: gateway-conformance-report path: gateway-conformance-report/projectcontour-contour-*.yaml - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b4d00c6e557..f21a9b275a5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -14,7 +14,7 @@ permissions: env: GOPROXY: https://proxy.golang.org/ - GO_VERSION: 1.22.1 + GO_VERSION: 1.22.5 jobs: CodeQL-Build: @@ -22,10 +22,10 @@ jobs: permissions: security-events: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -35,17 +35,17 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: languages: go # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - name: Autobuild - uses: github/codeql-action/autobuild@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/autobuild@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 diff --git a/.github/workflows/label_check.yaml b/.github/workflows/label_check.yaml index fb9f8203f7b..530793c92c1 100644 --- a/.github/workflows/label_check.yaml +++ b/.github/workflows/label_check.yaml @@ -11,7 +11,6 @@ permissions: env: GOPROXY: https://proxy.golang.org/ - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} jobs: # Ensures correct release-note labels are set: @@ -24,17 +23,17 @@ jobs: name: Check release-note label set runs-on: ubuntu-latest steps: - - uses: mheap/github-action-required-labels@132879b972cb7f2ac593006455875098e73cc7f2 # v5.4.0 + - uses: mheap/github-action-required-labels@d25134c992b943fb6ad00c25ea00eb5988c0a9dd # v5.4.2 with: mode: minimum count: 1 labels: "release-note/major, release-note/minor, release-note/small, release-note/docs, release-note/infra, release-note/deprecation, release-note/none-required" - - uses: mheap/github-action-required-labels@132879b972cb7f2ac593006455875098e73cc7f2 # v5.4.0 + - uses: mheap/github-action-required-labels@d25134c992b943fb6ad00c25ea00eb5988c0a9dd # v5.4.2 with: mode: maximum count: 1 labels: "release-note/major, release-note/minor, release-note/small, release-note/docs, release-note/infra, release-note/none-required" - - uses: mheap/github-action-required-labels@132879b972cb7f2ac593006455875098e73cc7f2 # v5.4.0 + - uses: mheap/github-action-required-labels@d25134c992b943fb6ad00c25ea00eb5988c0a9dd # v5.4.2 with: mode: maximum count: 1 @@ -44,10 +43,10 @@ jobs: needs: [check-label] runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -57,7 +56,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: 'stable' cache: false diff --git a/.github/workflows/openssf-scorecard.yaml b/.github/workflows/openssf-scorecard.yaml index eb58991e235..26c136a7317 100644 --- a/.github/workflows/openssf-scorecard.yaml +++ b/.github/workflows/openssf-scorecard.yaml @@ -22,21 +22,21 @@ jobs: security-events: write id-token: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + 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@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: sarif_file: results.sarif diff --git a/.github/workflows/prbuild.yaml b/.github/workflows/prbuild.yaml index 7f89ad3bfae..5933f1a0116 100644 --- a/.github/workflows/prbuild.yaml +++ b/.github/workflows/prbuild.yaml @@ -13,60 +13,46 @@ permissions: env: GOPROXY: https://proxy.golang.org/ - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - GO_VERSION: 1.22.1 + GO_VERSION: 1.22.5 + jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: golangci-lint - uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0 + uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: version: v1.56.2 - # TODO: re-enable linting tools package once https://github.com/projectcontour/contour/issues/5077 - # is resolved - args: --build-tags=e2e,conformance,gcp,oidc,none --out-format=colored-line-number - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} + args: --build-tags=e2e,conformance,tools,gcp,oidc,none --out-format=colored-line-number codespell: name: Codespell runs-on: ubuntu-latest timeout-minutes: 5 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Codespell - uses: codespell-project/actions-codespell@94259cd8be02ad2903ba34a22d9c13de21a74461 # v2.0 + uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 # v2.1 with: skip: .git,*.png,*.woff,*.woff2,*.eot,*.ttf,*.jpg,*.ico,*.svg,./site/themes/contour/static/fonts/README.md,./vendor,./site/public,./hack/actions/check-changefile-exists.go,go.mod,go.sum ignore_words_file: './.codespell.ignorewords' check_filenames: true check_hidden: true - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} codegen: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -76,7 +62,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -88,12 +74,6 @@ jobs: run: | make generate lint-yamllint lint-flags ./hack/actions/check-uncommitted-codegen.sh - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} build-image: needs: - lint @@ -101,11 +81,11 @@ jobs: - codegen runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 with: version: latest - name: Build image @@ -114,16 +94,10 @@ jobs: run: | make multiarch-build - name: Upload image - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: image path: image/contour-*.tar - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} e2e: runs-on: ubuntu-latest needs: [build-image] @@ -140,26 +114,26 @@ jobs: # image to use) for each kubernetes_version value. include: - kubernetes_version: "kubernetes:latest" - node_image: "docker.io/kindest/node:v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245" + node_image: "docker.io/kindest/node:v1.31.0@sha256:53df588e04085fd41ae12de0c3fe4c72f7013bba32a20e7325357a1ac94ba865" - kubernetes_version: "kubernetes:n-1" - node_image: "docker.io/kindest/node:v1.28.7@sha256:9bc6c451a289cf96ad0bbaf33d416901de6fd632415b076ab05f5fa7e4f65c58" + node_image: "docker.io/kindest/node:v1.30.4@sha256:976ea815844d5fa93be213437e3ff5754cd599b040946b5cca43ca45c2047114" - kubernetes_version: "kubernetes:n-2" - node_image: "docker.io/kindest/node:v1.27.11@sha256:681253009e68069b8e01aad36a1e0fa8cf18bb0ab3e5c4069b2e65cafdd70843" + node_image: "docker.io/kindest/node:v1.29.8@sha256:d46b7aa29567e93b27f7531d258c372e829d7224b25e3fc6ffdefed12476d3aa" - config_type: "ConfigmapConfiguration" use_config_crd: "false" - config_type: "ContourConfiguration" use_config_crd: "true" steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Download image - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: image path: image - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -169,7 +143,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -185,12 +159,6 @@ jobs: run: | export CONTOUR_E2E_IMAGE="ghcr.io/projectcontour/contour:$(ls ./image/contour-*.tar | sed -E 's/.*contour-(.*).tar/\1/')" make e2e - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} upgrade: runs-on: ubuntu-latest needs: [build-image] @@ -205,24 +173,24 @@ jobs: # image to use) for each kubernetes_version value. include: - kubernetes_version: "kubernetes:latest" - node_image: "docker.io/kindest/node:v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245" + node_image: "docker.io/kindest/node:v1.31.0@sha256:53df588e04085fd41ae12de0c3fe4c72f7013bba32a20e7325357a1ac94ba865" - kubernetes_version: "kubernetes:n-1" - node_image: "docker.io/kindest/node:v1.28.7@sha256:9bc6c451a289cf96ad0bbaf33d416901de6fd632415b076ab05f5fa7e4f65c58" + node_image: "docker.io/kindest/node:v1.30.4@sha256:976ea815844d5fa93be213437e3ff5754cd599b040946b5cca43ca45c2047114" - kubernetes_version: "kubernetes:n-2" - node_image: "docker.io/kindest/node:v1.27.11@sha256:681253009e68069b8e01aad36a1e0fa8cf18bb0ab3e5c4069b2e65cafdd70843" + node_image: "docker.io/kindest/node:v1.29.8@sha256:d46b7aa29567e93b27f7531d258c372e829d7224b25e3fc6ffdefed12476d3aa" steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false # Fetch history for all tags and branches so we can figure out most # recent release tag. fetch-depth: 0 - name: Download image - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: image path: image - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -232,7 +200,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -249,12 +217,6 @@ jobs: run: | export CONTOUR_E2E_IMAGE="ghcr.io/projectcontour/contour:$(ls ./image/contour-*.tar | sed -E 's/.*contour-(.*).tar/\1/')" make upgrade - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} test-linux: needs: - lint @@ -262,10 +224,10 @@ jobs: - codegen runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -275,7 +237,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -292,16 +254,10 @@ jobs: make check-coverage - name: codeCoverage if: ${{ success() }} - uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage.out - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} test-osx: needs: - lint @@ -309,10 +265,10 @@ jobs: - codegen runs-on: macos-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Windows) @@ -322,7 +278,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -337,25 +293,19 @@ jobs: run: | make install make check-coverage - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} gateway-conformance: runs-on: ubuntu-latest needs: [build-image] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Download image - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: image path: image - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: # * Module download cache # * Build cache (Linux) @@ -365,7 +315,7 @@ jobs: key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GO_VERSION }} cache: false @@ -379,9 +329,3 @@ jobs: run: | export CONTOUR_E2E_IMAGE="ghcr.io/projectcontour/contour:$(ls ./image/contour-*.tar | sed -E 's/.*contour-(.*).tar/\1/')" make gateway-conformance - - uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#contour-ci-notifications' - if: ${{ failure() && github.ref == 'refs/heads/main' }} diff --git a/.github/workflows/trivy-scan.yaml b/.github/workflows/trivy-scan.yaml index d102d09a7f6..4d3dfc99cca 100644 --- a/.github/workflows/trivy-scan.yaml +++ b/.github/workflows/trivy-scan.yaml @@ -16,18 +16,18 @@ jobs: matrix: branch: - main + - release-1.30 + - release-1.29 - release-1.28 - - release-1.27 - - release-1.26 runs-on: ubuntu-latest permissions: security-events: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false ref: ${{ matrix.branch }} - - uses: aquasecurity/trivy-action@062f2592684a31eb3aa050cc61e7ca1451cecd3d # 0.18.0 + - uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2 # 0.28.0 with: scanners: vuln scan-type: 'fs' @@ -35,6 +35,6 @@ jobs: output: 'trivy-results.sarif' ignore-unfixed: true severity: 'HIGH,CRITICAL' - - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: sarif_file: 'trivy-results.sarif' diff --git a/.yamllint b/.yamllint index 03656004e62..d624baac7fd 100644 --- a/.yamllint +++ b/.yamllint @@ -1,4 +1,11 @@ --- +ignore: | + .github/ + .mockery.yaml + codecov.yaml + examples/gateway/00-crds.yaml + site/data/docs/*-toc.yml + site/themes/contour/i18n/en.yaml rules: braces: diff --git a/Makefile b/Makefile index 76427d5d822..0159e911f2a 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,6 @@ PROJECT = contour MODULE = github.com/$(ORG)/$(PROJECT) REGISTRY ?= ghcr.io/projectcontour IMAGE := $(REGISTRY)/$(PROJECT) -SRCDIRS := ./cmd ./internal ./apis -LOCAL_BOOTSTRAP_CONFIG = localenvoyconfig.yaml -SECURE_LOCAL_BOOTSTRAP_CONFIG = securelocalenvoyconfig.yaml -ENVOY_IMAGE = docker.io/envoyproxy/envoy:v1.29.2 GATEWAY_API_VERSION ?= $(shell grep "sigs.k8s.io/gateway-api" go.mod | awk '{print $$2}') # Used to supply a local Envoy docker container an IP to connect to that is running @@ -44,7 +40,7 @@ endif IMAGE_PLATFORMS ?= linux/amd64,linux/arm64 # Base build image to use. -BUILD_BASE_IMAGE ?= golang:1.22.1@sha256:34ce21a9696a017249614876638ea37ceca13cdd88f582caad06f87a8aa45bf3 +BUILD_BASE_IMAGE ?= golang:1.22.5@sha256:829eff99a4b2abffe68f6a3847337bf6455d69d17e49ec1a97dac78834754bd6 # Enable build with CGO. BUILD_CGO_ENABLED ?= 0 @@ -195,17 +191,15 @@ lint-codespell: CODESPELL_SKIP := $(shell cat .codespell.skip | tr \\n ',') lint-codespell: @./hack/codespell.sh --skip $(CODESPELL_SKIP) --ignore-words .codespell.ignorewords --check-filenames --check-hidden -q2 -# TODO: re-enable linting tools package once https://github.com/projectcontour/contour/issues/5077 -# is resolved .PHONY: lint-golint lint-golint: @echo Running Go linter ... - @./hack/golangci-lint run --build-tags=e2e,conformance,gcp,oidc,none + @./hack/golangci-lint run --build-tags=e2e,conformance,tools,gcp,oidc,none .PHONY: lint-yamllint lint-yamllint: @echo Running YAML linter ... - @./hack/yamllint examples/ site/content/examples/ ./versions.yaml + @./hack/yamllint # Check that CLI flags are formatted consistently. We are checking # for calls to Kingpin Flags() and Command() APIs where the 2nd diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index 976795d6903..72ff28096d2 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -235,7 +235,6 @@ type ExtensionServiceReference struct { // // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names // - // +required // +kubebuilder:validation:MinLength=1 Name string `json:"name,omitempty" protobuf:"bytes,3,opt,name=name"` } diff --git a/apis/projectcontour/v1alpha1/ciphersuites.go b/apis/projectcontour/v1alpha1/ciphersuites.go index 27966a9191a..a879bb035bb 100644 --- a/apis/projectcontour/v1alpha1/ciphersuites.go +++ b/apis/projectcontour/v1alpha1/ciphersuites.go @@ -18,6 +18,9 @@ package v1alpha1 // - most of the clients that might need to use the commented ciphers are // unable to connect without TLS 1.0, which contour never enables. // +// Ciphers are listed in order of preference. +// [cipher1|cipher2|...] defines an equal-preference group of ciphers. +// // This list is ignored if the client and server negotiate TLS 1.3. // // The commented ciphers are left in place to simplify updating this list for future @@ -41,18 +44,18 @@ var DefaultTLSCiphers = []string{ // See: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlsparameters // Note: This list is a superset of what is valid for stock Envoy builds and those using BoringSSL FIPS. var ValidTLSCiphers = map[string]struct{}{ - "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]": {}, - "[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]": {}, - "ECDHE-ECDSA-AES128-GCM-SHA256": {}, - "ECDHE-RSA-AES128-GCM-SHA256": {}, - "ECDHE-ECDSA-AES128-SHA": {}, - "ECDHE-RSA-AES128-SHA": {}, - "AES128-GCM-SHA256": {}, - "AES128-SHA": {}, - "ECDHE-ECDSA-AES256-GCM-SHA384": {}, - "ECDHE-RSA-AES256-GCM-SHA384": {}, - "ECDHE-ECDSA-AES256-SHA": {}, - "ECDHE-RSA-AES256-SHA": {}, - "AES256-GCM-SHA384": {}, - "AES256-SHA": {}, + "ECDHE-ECDSA-CHACHA20-POLY1305": {}, + "ECDHE-RSA-CHACHA20-POLY1305": {}, + "ECDHE-ECDSA-AES128-GCM-SHA256": {}, + "ECDHE-RSA-AES128-GCM-SHA256": {}, + "ECDHE-ECDSA-AES128-SHA": {}, + "ECDHE-RSA-AES128-SHA": {}, + "AES128-GCM-SHA256": {}, + "AES128-SHA": {}, + "ECDHE-ECDSA-AES256-GCM-SHA384": {}, + "ECDHE-RSA-AES256-GCM-SHA384": {}, + "ECDHE-ECDSA-AES256-SHA": {}, + "ECDHE-RSA-AES256-SHA": {}, + "AES256-GCM-SHA384": {}, + "AES256-SHA": {}, } diff --git a/apis/projectcontour/v1alpha1/contourconfig.go b/apis/projectcontour/v1alpha1/contourconfig.go index e967051d7dc..0af7a50e08a 100644 --- a/apis/projectcontour/v1alpha1/contourconfig.go +++ b/apis/projectcontour/v1alpha1/contourconfig.go @@ -87,9 +87,9 @@ type ContourConfigurationSpec struct { // FeatureFlags defines toggle to enable new contour features. // Available toggles are: - // useEndpointSlices - configures contour to fetch endpoint data - // from k8s endpoint slices. defaults to false and reading endpoint - // data from the k8s endpoints. + // useEndpointSlices - Configures contour to fetch endpoint data + // from k8s endpoint slices. defaults to true, + // If false then reads endpoint data from the k8s endpoints. FeatureFlags FeatureFlags `json:"featureFlags,omitempty"` } @@ -107,7 +107,7 @@ const ( EnvoyServerType XDSServerType = "envoy" ) -type GlobalCircuitBreakerDefaults struct { +type CircuitBreakers struct { // The maximum number of connections that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. // +optional MaxConnections uint32 `json:"maxConnections,omitempty" yaml:"max-connections,omitempty"` @@ -120,6 +120,10 @@ type GlobalCircuitBreakerDefaults struct { // The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3. // +optional MaxRetries uint32 `json:"maxRetries,omitempty" yaml:"max-retries,omitempty"` + + // PerHostMaxConnections is the maximum number of connections + // that Envoy will allow to each individual host in a cluster. + PerHostMaxConnections uint32 `json:"perHostMaxConnections,omitempty" yaml:"per-host-max-connections,omitempty"` } // XDSServerConfig holds the config for the Contour xDS server. @@ -129,6 +133,9 @@ type XDSServerConfig struct { // Values: `envoy` (default), `contour (deprecated)`. // // Other values will produce an error. + // + // Deprecated: this field will be removed in a future release when + // the `contour` xDS server implementation is removed. // +optional Type XDSServerType `json:"type,omitempty"` @@ -704,7 +711,7 @@ type ClusterParameters struct { // If defined, this will be used as the default for all services. // // +optional - GlobalCircuitBreakerDefaults *GlobalCircuitBreakerDefaults `json:"circuitBreakers,omitempty"` + GlobalCircuitBreakerDefaults *CircuitBreakers `json:"circuitBreakers,omitempty"` // UpstreamTLS contains the TLS policy parameters for upstream connections // diff --git a/apis/projectcontour/v1alpha1/contourconfig_helpers.go b/apis/projectcontour/v1alpha1/contourconfig_helpers.go index babadc5bc09..4969279bc65 100644 --- a/apis/projectcontour/v1alpha1/contourconfig_helpers.go +++ b/apis/projectcontour/v1alpha1/contourconfig_helpers.go @@ -15,18 +15,16 @@ package v1alpha1 import ( "fmt" - "slices" "strconv" + "strings" "k8s.io/apimachinery/pkg/util/sets" ) -const ( - featureFlagUseEndpointSlices string = "useEndpointSlices" -) +const featureFlagUseEndpointSlices string = "useEndpointSlices" -var featureFlagsMap = map[string]bool{ - featureFlagUseEndpointSlices: true, +var featureFlagsMap = map[string]struct{}{ + featureFlagUseEndpointSlices: {}, } // Validate configuration that is not already covered by CRD validation. @@ -187,6 +185,27 @@ func ValidateTLSProtocolVersions(min, max string) error { return nil } +// isValidTLSCipher parses a cipher string and returns true if it is valid. +// We do not support the full syntax defined in the BoringSSL documentation, +// see https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Cipher-suite-configuration +func isValidTLSCipher(cipherSpec string) bool { + // Equal-preference group: [cipher1|cipher2|...] + if strings.HasPrefix(cipherSpec, "[") && strings.HasSuffix(cipherSpec, "]") { + for _, cipher := range strings.Split(strings.Trim(cipherSpec, "[]"), "|") { + if _, ok := ValidTLSCiphers[cipher]; !ok { + return false + } + } + return true + } + + if _, ok := ValidTLSCiphers[cipherSpec]; !ok { + return false + } + + return true +} + // Validate ensures EnvoyTLS configuration is valid. func (e *EnvoyTLS) Validate() error { if err := ValidateTLSProtocolVersions(e.MinimumProtocolVersion, e.MaximumProtocolVersion); err != nil { @@ -195,7 +214,7 @@ func (e *EnvoyTLS) Validate() error { var invalidCipherSuites []string for _, c := range e.CipherSuites { - if _, ok := ValidTLSCiphers[c]; !ok { + if !isValidTLSCipher(c) { invalidCipherSuites = append(invalidCipherSuites, c) } } @@ -226,16 +245,26 @@ func (e *EnvoyTLS) SanitizedCipherSuites() []string { func (f FeatureFlags) Validate() error { for _, featureFlag := range f { - if _, found := featureFlagsMap[featureFlag]; !found { + fields := strings.Split(featureFlag, "=") + if _, found := featureFlagsMap[fields[0]]; !found { return fmt.Errorf("invalid contour configuration, unknown feature flag:%s", featureFlag) } } - return nil } func (f FeatureFlags) IsEndpointSliceEnabled() bool { - return slices.Contains(f, featureFlagUseEndpointSlices) + // only when the flag: 'useEndpointSlices=false' is exists, return false + for _, flag := range f { + if !strings.HasPrefix(flag, featureFlagUseEndpointSlices) { + continue + } + fields := strings.Split(flag, "=") + if len(fields) == 2 && strings.ToLower(fields[1]) == "false" { + return false + } + } + return true } // Validate ensures that GatewayRef namespace/name is specified. diff --git a/apis/projectcontour/v1alpha1/contourconfig_helpers_test.go b/apis/projectcontour/v1alpha1/contourconfig_helpers_test.go index 1b6fdbcb116..d4713df4c8e 100644 --- a/apis/projectcontour/v1alpha1/contourconfig_helpers_test.go +++ b/apis/projectcontour/v1alpha1/contourconfig_helpers_test.go @@ -141,8 +141,10 @@ func TestContourConfigurationSpecValidate(t *testing.T) { c.Envoy.Listener.TLS.CipherSuites = []string{ "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]", "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305", "[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]", "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-CHACHA20-POLY1305", "ECDHE-ECDSA-AES128-SHA", "AES128-GCM-SHA256", "AES128-SHA", @@ -161,6 +163,20 @@ func TestContourConfigurationSpecValidate(t *testing.T) { "AES128-GCM-SHA256", } require.Error(t, c.Validate()) + + // Equal-preference group with invalid cipher. + c.Envoy.Listener.TLS.CipherSuites = []string{ + "[ECDHE-ECDSA-AES128-GCM-SHA256|NOTAVALIDCIPHER]", + "ECDHE-ECDSA-AES128-GCM-SHA256", + } + require.Error(t, c.Validate()) + + // Unmatched brackets. + c.Envoy.Listener.TLS.CipherSuites = []string{ + "[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305", + "ECDHE-ECDSA-AES128-GCM-SHA256", + } + require.Error(t, c.Validate()) }) t.Run("gateway validation", func(t *testing.T) { @@ -303,10 +319,26 @@ func TestFeatureFlagsValidate(t *testing.T) { expected error }{ { - name: "valid flag", + name: "valid flag: no value", flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices"}, expected: nil, }, + { + name: "valid flag2: empty", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices="}, + expected: nil, + }, + { + name: "valid flag: true", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices=true"}, + expected: nil, + }, + { + name: "valid flag: false", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices=false"}, + expected: nil, + }, + { name: "invalid flag", flags: contour_v1alpha1.FeatureFlags{"invalidFlag"}, @@ -331,3 +363,68 @@ func TestFeatureFlagsValidate(t *testing.T) { }) } } + +func TestFeatureFlagsIsEndpointSliceEnabled(t *testing.T) { + tests := []struct { + name string + flags contour_v1alpha1.FeatureFlags + expected bool + }{ + { + name: "valid flag: no value", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices"}, + expected: true, + }, + { + name: "valid flag2: empty", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices="}, + expected: true, + }, + { + name: "valid flag: true", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices=true"}, + expected: true, + }, + { + name: "valid flag: ANY", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices=ANY"}, + expected: true, + }, + + { + name: "empty flags", + flags: contour_v1alpha1.FeatureFlags{}, + expected: true, + }, + { + name: "empty string", + flags: contour_v1alpha1.FeatureFlags{""}, + expected: true, + }, + + { + name: "multi-flags", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices", "otherFlag"}, + expected: true, + }, + + { + name: "valid flag: false", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices=false"}, + expected: false, + }, + + { + name: "valid flag: FALSE", + flags: contour_v1alpha1.FeatureFlags{"useEndpointSlices=FALSE"}, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.flags.IsEndpointSliceEnabled() + assert.Equal(t, tt.expected, err) + }) + } +} diff --git a/apis/projectcontour/v1alpha1/extensionservice.go b/apis/projectcontour/v1alpha1/extensionservice.go index 20c53058b54..c074de546e7 100644 --- a/apis/projectcontour/v1alpha1/extensionservice.go +++ b/apis/projectcontour/v1alpha1/extensionservice.go @@ -104,6 +104,11 @@ type ExtensionServiceSpec struct { // +optional // +kubebuilder:validation:Enum=v3 ProtocolVersion ExtensionProtocolVersion `json:"protocolVersion,omitempty"` + + // CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. + // If defined this overrides the global circuit breaker budget. + // +optional + CircuitBreakerPolicy *CircuitBreakers `json:"circuitBreakerPolicy,omitempty"` } // ExtensionServiceStatus defines the observed state of an diff --git a/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go b/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go index eaa1576bfce..394c22dff6e 100644 --- a/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go +++ b/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go @@ -47,6 +47,21 @@ func (in AccessLogJSONFields) DeepCopy() AccessLogJSONFields { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CircuitBreakers) DeepCopyInto(out *CircuitBreakers) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CircuitBreakers. +func (in *CircuitBreakers) DeepCopy() *CircuitBreakers { + if in == nil { + return nil + } + out := new(CircuitBreakers) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterParameters) DeepCopyInto(out *ClusterParameters) { *out = *in @@ -62,7 +77,7 @@ func (in *ClusterParameters) DeepCopyInto(out *ClusterParameters) { } if in.GlobalCircuitBreakerDefaults != nil { in, out := &in.GlobalCircuitBreakerDefaults, &out.GlobalCircuitBreakerDefaults - *out = new(GlobalCircuitBreakerDefaults) + *out = new(CircuitBreakers) **out = **in } if in.UpstreamTLS != nil { @@ -813,6 +828,11 @@ func (in *ExtensionServiceSpec) DeepCopyInto(out *ExtensionServiceSpec) { *out = new(v1.TimeoutPolicy) **out = **in } + if in.CircuitBreakerPolicy != nil { + in, out := &in.CircuitBreakerPolicy, &out.CircuitBreakerPolicy + *out = new(CircuitBreakers) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionServiceSpec. @@ -897,21 +917,6 @@ func (in *GatewayConfig) DeepCopy() *GatewayConfig { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GlobalCircuitBreakerDefaults) DeepCopyInto(out *GlobalCircuitBreakerDefaults) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalCircuitBreakerDefaults. -func (in *GlobalCircuitBreakerDefaults) DeepCopy() *GlobalCircuitBreakerDefaults { - if in == nil { - return nil - } - out := new(GlobalCircuitBreakerDefaults) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPProxyConfig) DeepCopyInto(out *HTTPProxyConfig) { *out = *in diff --git a/changelogs/CHANGELOG-v1.26.3.md b/changelogs/CHANGELOG-v1.26.3.md new file mode 100644 index 00000000000..c5df25a9f6d --- /dev/null +++ b/changelogs/CHANGELOG-v1.26.3.md @@ -0,0 +1,25 @@ +We are delighted to present version v1.26.3 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.27.4. See the release notes for v1.27.4 [here](https://www.envoyproxy.io/docs/envoy/v1.27.4/version_history/v1.27/v1.27.4). +- Updates Go to v1.20.14. See the release notes for v1.20.14 [here](https://go.dev/doc/devel/release#go1.20.minor). + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.26.3 is tested against Kubernetes 1.26 through 1.28. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.27.2.md b/changelogs/CHANGELOG-v1.27.2.md new file mode 100644 index 00000000000..92efc440d71 --- /dev/null +++ b/changelogs/CHANGELOG-v1.27.2.md @@ -0,0 +1,25 @@ +We are delighted to present version v1.27.2 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.28.2. See the release notes for v1.28.2 [here](https://www.envoyproxy.io/docs/envoy/v1.28.2/version_history/v1.28/v1.28.2). +- Updates Go to v1.21.9. See the release notes for v1.21.9 [here](https://go.dev/doc/devel/release#go1.21.minor). + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.27.2 is tested against Kubernetes 1.26 through 1.28. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.27.3.md b/changelogs/CHANGELOG-v1.27.3.md new file mode 100644 index 00000000000..be1776bc258 --- /dev/null +++ b/changelogs/CHANGELOG-v1.27.3.md @@ -0,0 +1,24 @@ +We are delighted to present version v1.27.3 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.28.3. See the release notes for v1.28.3 [here](https://www.envoyproxy.io/docs/envoy/v1.28.3/version_history/v1.28/v1.28.3). + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.27.3 is tested against Kubernetes 1.26 through 1.28. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.27.4.md b/changelogs/CHANGELOG-v1.27.4.md new file mode 100644 index 00000000000..fd4ae33b1de --- /dev/null +++ b/changelogs/CHANGELOG-v1.27.4.md @@ -0,0 +1,25 @@ +We are delighted to present version v1.27.4 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.28.4. See the release notes for v1.28.4 [here](https://www.envoyproxy.io/docs/envoy/v1.28.4/version_history/v1.28/v1.28.4) ([#6486](https://github.com/projectcontour/contour/pull/6486)). + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.27.4 is tested against Kubernetes 1.26 through 1.28. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.28.3.md b/changelogs/CHANGELOG-v1.28.3.md new file mode 100644 index 00000000000..f12d9c79398 --- /dev/null +++ b/changelogs/CHANGELOG-v1.28.3.md @@ -0,0 +1,34 @@ +We are delighted to present version v1.28.3 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +## Update Envoy to v1.29.3 + +See the release notes for v1.29.3 [here](https://www.envoyproxy.io/docs/envoy/v1.29.3/version_history/v1.29/v1.29.3). + +Note that this Envoy version retains the hop-by-hop TE header when set to `trailers`, fixing a regression seen in v1.29.0-v1.29.2 for HTTP/2, particularly gRPC. +However, this version of Contour continues to set the `envoy.reloadable_features.sanitize_te` Envoy runtime setting to `false` to ensure seamless upgrades. +This runtime setting will be removed in Contour v1.29.0. + +## Update Go to v1.21.9 + +See the release notes for v1.21.9 [here](https://go.dev/doc/devel/release#go1.21.minor). + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.28.3 is tested against Kubernetes 1.27 through 1.29. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.28.4.md b/changelogs/CHANGELOG-v1.28.4.md new file mode 100644 index 00000000000..35e560dc015 --- /dev/null +++ b/changelogs/CHANGELOG-v1.28.4.md @@ -0,0 +1,27 @@ +We are delighted to present version v1.28.4 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.29.4. See the release notes for v1.29.4 [here](https://www.envoyproxy.io/docs/envoy/v1.29.4/version_history/v1.29/v1.29.4) ([#6377](https://github.com/projectcontour/contour/pull/6377)). +- Gateway API: an HTTPRoute timeout of `0s` now disables the timeout ([#6379](https://github.com/projectcontour/contour/pull/6379)). +- Gateway provisioner: disabled features are now correctly applied to the Contour controller ([#6414](https://github.com/projectcontour/contour/pull/6414)). + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.28.4 is tested against Kubernetes 1.27 through 1.29. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.28.5.md b/changelogs/CHANGELOG-v1.28.5.md new file mode 100644 index 00000000000..0c989b0bb4a --- /dev/null +++ b/changelogs/CHANGELOG-v1.28.5.md @@ -0,0 +1,25 @@ +We are delighted to present version v1.28.5 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.29.5. See the release notes for v1.29.5 [here](https://www.envoyproxy.io/docs/envoy/v1.29.5/version_history/v1.29/v1.29.5) ([#6485](https://github.com/projectcontour/contour/pull/6485)). + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.28.5 is tested against Kubernetes 1.27 through 1.29. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.28.6.md b/changelogs/CHANGELOG-v1.28.6.md new file mode 100644 index 00000000000..b8d9f91a668 --- /dev/null +++ b/changelogs/CHANGELOG-v1.28.6.md @@ -0,0 +1,26 @@ +We are delighted to present version v1.28.6 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.29.7. See the release notes [here](https://www.envoyproxy.io/docs/envoy/v1.29.7/version_history/v1.29/v1.29.7). +- Updates Go to v1.21.12. See the release notes [here](https://go.dev/doc/devel/release#go1.21.minor). + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.28.6 is tested against Kubernetes 1.27 through 1.29. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.29.0.md b/changelogs/CHANGELOG-v1.29.0.md new file mode 100644 index 00000000000..c40077fbb02 --- /dev/null +++ b/changelogs/CHANGELOG-v1.29.0.md @@ -0,0 +1,144 @@ +We are delighted to present version v1.29.0 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +A big thank you to everyone who contributed to the release. + + +- [Major Changes](#major-changes) +- [Minor Changes](#minor-changes) +- [Other Changes](#other-changes) +- [Docs Changes](#docs-changes) +- [Deprecations/Removals](#deprecation-and-removal-notices) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) +- [Community Thanks!](#community-thanks) + +# Major Changes + +## Default xDS Server Implementation is now Envoy + +As of this release, Contour now uses the `envoy` xDS server implementation by default. +This xDS server implementation is based on Envoy's [go-control-plane project](https://github.com/envoyproxy/go-control-plane) and will eventually be the only supported xDS server implementation in Contour. +This change is expected to be transparent to users. + +### I'm seeing issues after upgrading, how to I revert to the contour xDS server? + +If you encounter any issues, you can easily revert to the `contour` xDS server with the following configuration: + +(if using Contour config file) +```yaml +server: + xds-server-type: contour +``` + +(if using ContourConfiguration CRD) +```yaml +... +spec: + xdsServer: + type: contour +``` + +You will need to restart Contour for the changes to take effect. + +(#6146, @skriss) + +## Gateway API: Inform on v1 types + +Contour no longer informs on v1beta1 resources that have graduated to v1. +This includes the "core" resources GatewayClass, Gateway, and HTTPRoute. +This means that users should ensure they have updated CRDs to Gateway API v1.0.0 or newer, which introduced the v1 version with compatibility with v1beta1. + +(#6153, @sunjayBhatia) + + +# Minor Changes + +## Use EndpointSlices by default + +Contour now uses the Kubernetes EndpointSlices API by default to determine the endpoints to configure Envoy, instead of the Endpoints API. +Note: if you need to continue using the Endpoints API, you can disable the feature flag via `featureFlags: ["useEndpointSlices=false"]` in the Contour config file or ContourConfiguration CRD. + +(#6149, @izturn) + +## Gateway API: handle Route conflicts with HTTPRoute.Matches + +It's possible that multiple HTTPRoutes will define the same Match conditions. In this case the following logic is applied to resolve the conflict: + +- 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 a Route with a creation timestamp of “2020-09-08 01:02:04”. +- The Route appearing first in alphabetical order (namespace/name) for example, foo/bar is given precedence over foo/baz. + +With above ordering, any HTTPRoute that ranks lower, will be marked with below conditions accordingly +1. If only partial rules under this HTTPRoute are conflicted, it's marked with `Accepted: True` and `PartiallyInvalid: true` Conditions and Reason: `RuleMatchPartiallyConflict`. +2. If all the rules under this HTTPRoute are conflicted, it's marked with `Accepted: False` Condition and Reason `RuleMatchConflict`. + +(#6188, @lubronzhan) + +## Spawn Upstream Span is now enabled in tracing + +As described in [Envoy documentations](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-tracing), ```spawn_upstream_span``` should be true when envoy is working as an independent proxy and from now on contour tracing spans will show up as a parent span to upstream spans. + +(#6271, @SamMHD) + + +# Other Changes +- Fix data race in BackendTLSPolicy status update logic. (#6185, @sunjayBhatia) +- Fix for specifying a health check port with an ExternalName Service. (#6230, @yangyy93) +- Updates the example `envoyproxy/ratelimit` image tag to `19f2079f`, for multi-arch support and other improvements. (#6246, @skriss) +- In the `envoy` go-control-plane xDS server, use a separate snapshot cache for Endpoints, to minimize the amount of unnecessary xDS traffic generated. (#6250, @skriss) +- If there were no relevant resources for Contour in the watched namespaces during the startup of a follower instance of Contour, it did not reach a ready state. (#6295, @tsaarni) +- Added support for enabling circuit breaker statistics tracking. (#6297, @rajatvig) +- Updates to Go 1.22.2. See the [Go release notes](https://go.dev/doc/devel/release#go1.22.minor) for more information. (#6327, @skriss) +- Gateway API: add support for HTTPRoute's Timeouts.BackendRequest field. (#6335, @skriss) +- Updates Envoy to v1.30.1. See the v1.30.0 release notes [here](https://www.envoyproxy.io/docs/envoy/v1.30.1/version_history/v1.30/v1.30.0) and the v1.30.1 release notes [here](https://www.envoyproxy.io/docs/envoy/v1.30.1/version_history/v1.30/v1.30.1). (#6353, @tico88612) +- Gateway API: a timeout value of `0s` disables the timeout. (#6375, @skriss) +- Fix provisioner to use separate `--disable-feature` flags on Contour Deployment for each disabled feature. Previously a comma separated list was passed which was incorrect. (#6413, @sunjayBhatia) + + +# Deprecation and Removal Notices + +## Configuring Contour with a GatewayClass controller name is no longer supported + +Contour can no longer be configured with a GatewayClass controller name (gateway.controllerName in the config file or ContourConfiguration CRD), as the config field has been removed. +Instead, either use a specific Gateway reference (gateway.gatewayRef), or use the Gateway provisioner. + +(#6145, @skriss) + +## Contour xDS server implementation is now deprecated + +As of this release, the `contour` xDS server implementation is now deprecated. +Once the go-control-plane based `envoy` xDS server has had sufficient production bake time, the `contour` implementation will be removed from Contour. +Notification of removal will occur at least one release in advance. + +(#6146, @skriss) + +## Use of Endpoints API is deprecated + +Contour now uses the EndpointSlices API by default, and its usage of the Endpoints API is deprecated as of this release. Support for Endpoints, and the associated `useEndpointSlices` feature flag, will be removed in a future release. + +(#6149, @izturn) + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.29.0 is tested against Kubernetes 1.27 through 1.29. + +# Community Thanks! +We’re immensely grateful for all the community contributions that help make Contour even better! For this release, special thanks go out to the following contributors: + +- @SamMHD +- @izturn +- @lubronzhan +- @rajatvig +- @tico88612 +- @yangyy93 + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.29.1.md b/changelogs/CHANGELOG-v1.29.1.md new file mode 100644 index 00000000000..46f6841c4e2 --- /dev/null +++ b/changelogs/CHANGELOG-v1.29.1.md @@ -0,0 +1,25 @@ +We are delighted to present version v1.29.1 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.30.2. See the release notes for v1.30.2 [here](https://www.envoyproxy.io/docs/envoy/v1.30.2/version_history/v1.30/v1.30.2) ([#6484](https://github.com/projectcontour/contour/pull/6484)). + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.29.1 is tested against Kubernetes 1.27 through 1.29. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.29.2.md b/changelogs/CHANGELOG-v1.29.2.md new file mode 100644 index 00000000000..5656ad6b0e8 --- /dev/null +++ b/changelogs/CHANGELOG-v1.29.2.md @@ -0,0 +1,26 @@ +We are delighted to present version v1.29.2 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +- [All Changes](#all-changes) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) + +# All Changes + +- Updates Envoy to v1.30.4. See the release notes [here](https://www.envoyproxy.io/docs/envoy/v1.30.4/version_history/v1.30/v1.30.4). +- Updates Go to v1.22.5. See the release notes [here](https://go.dev/doc/devel/release#go1.22.minor). + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.29.2 is tested against Kubernetes 1.27 through 1.29. + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/CHANGELOG-v1.30.0.md b/changelogs/CHANGELOG-v1.30.0.md new file mode 100644 index 00000000000..85e1a7dfc69 --- /dev/null +++ b/changelogs/CHANGELOG-v1.30.0.md @@ -0,0 +1,120 @@ +We are delighted to present version v1.30.0 of Contour, our layer 7 HTTP reverse proxy for Kubernetes clusters. + +A big thank you to everyone who contributed to the release. + +- [Minor Changes](#minor-changes) +- [Other Changes](#other-changes) +- [Deprecations/Removals](#deprecation-and-removal-notices) +- [Installing/Upgrading](#installing-and-upgrading) +- [Compatible Kubernetes Versions](#compatible-kubernetes-versions) +- [Community Thanks!](#community-thanks) + +# Minor Changes + +## Gateway API: Implement Listener/Route hostname isolation + +Gateway API spec update in this [GEP](https://github.com/kubernetes-sigs/gateway-api/pull/2465). +Updates logic on finding intersecting route and Listener hostnames to factor in the other Listeners on a Gateway that the route in question may not actually be attached to. +Requests should be "isolated" to the most specific Listener and it's attached routes. + +(#6162, @sunjayBhatia) + +## Update examples for monitoring Contour and Envoy + +Updates the [documentation](https://projectcontour.io/docs/main/guides/prometheus/) and examples for deploying a monitoring stack (Prometheus and Grafana) to scrape metrics from Contour and Envoy. +Adds a metrics port to the Envoy DaemonSet/Deployment in the example YAMLs to expose port `8002` so that `PodMonitor` resources can be used to find metrics endpoints. + +(#6269, @sunjayBhatia) + +## Update to Gateway API v1.1.0 + +Gateway API CRD compatibility has been updated to release v1.1.0. + +Notable changes for Contour include: +- The `BackendTLSPolicy` resource has undergone some breaking changes and has been updated to the `v1alpha3` API version. This will require any existing users of this policy to uninstall the v1alpha2 version before installing this newer version. +- `GRPCRoute` has graduated to GA and is now in the `v1` API version. + +Full release notes for this Gateway API release can be found [here](https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.1.0). + +(#6398, @sunjayBhatia) + +## Add Circuit Breaker support for Extension Services + +This change enables the user to configure the Circuit breakers for extension services either via the global Contour config or on an individual Extension Service. + +**NOTE**: The `PerHostMaxConnections` is now also configurable via the global settings. + +(#6539, @clayton-gonsalves) + +## Fallback Certificate: Add Global Ext Auth support + +Applies Global Auth filters to Fallback certificate + +(#6558, @erikflores7) + +## Gateway API: handle Route conflicts with GRPCRoute.Matches + +It's possible that multiple GRPCRoutes will define the same Match conditions. In this case the following logic is applied to resolve the conflict: + +- 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 a Route with a creation timestamp of “2020-09-08 01:02:04”. +- The Route appearing first in alphabetical order (namespace/name) for example, foo/bar is given precedence over foo/baz. + +With above ordering, any GRPCRoute that ranks lower, will be marked with below conditions accordingly: +1. If only partial rules under this GRPCRoute are conflicted, it's marked with `Accepted: True` and `PartiallyInvalid: true` Conditions and Reason: `RuleMatchPartiallyConflict`. +2. If all the rules under this GRPCRoute are conflicted, it's marked with `Accepted: False` Condition and Reason `RuleMatchConflict`. + +(#6566, @lubronzhan) + + +# Other Changes +- Fixes bug where external authorization policy was ignored on HTTPProxy direct response routes. (#6426, @shadialtarsha) +- Updates to Kubernetes 1.30. Supported/tested Kubernetes versions are now 1.28, 1.29, and 1.30. (#6444, @sunjayBhatia) +- Enforce `deny-by-default` approach on the `admin` listener by matching on exact paths and on `GET` requests (#6447, @davinci26) +- Add support for defining equal-preference cipher groups ([cipher1|cipher2|...]) and permit `ECDHE-ECDSA-CHACHA20-POLY1305` and `ECDHE-RSA-CHACHA20-POLY1305` to be used separately. (#6461, @tsaarni) +- allow `/stats/prometheus` route on the `admin` listener. (#6503, @clayton-gonsalves) +- Improve shutdown manager query to the Envoy stats endpoint for active connections by utilizing a regex filter query param. (#6523, @therealak12) +- Updates to Go 1.22.5. See the [Go release notes](https://go.dev/doc/devel/release#go1.22.minor) for more information. (#6563, @sunjayBhatia) +- Updates Envoy to v1.31.0. See the [Envoy release notes](https://www.envoyproxy.io/docs/envoy/v1.31.0/version_history/v1.31/v1.31.0) for more information about the content of the release. (#6569, @skriss) + +# Deprecation and Removal Notices + + +## Contour sample YAML manifests no longer use `prometheus.io/` annotations + +The annotations for notifying a Prometheus instance on how to scrape metrics from Contour and Envoy pods have been removed from the deployment YAMLs and the Gateway provisioner. +The suggested mechanism for doing so now is to use [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) and the [`PodMonitor`](https://prometheus-operator.dev/docs/operator/design/#podmonitor) resource. + +(#6269, @sunjayBhatia) + +## xDS server type fields in config file and ContourConfiguration CRD are deprecated + +These fields are officially deprecated now that the `contour` xDS server implementation is deprecated. +They are planned to be removed in the 1.31 release, along with the `contour` xDS server implementation. + +(#6561, @skriss) + + +# Installing and Upgrading + +For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). + +To upgrade an existing Contour installation, please consult the [upgrade documentation](https://projectcontour.io/resources/upgrading/). + + +# Compatible Kubernetes Versions + +Contour v1.30.0 is tested against Kubernetes 1.28 through 1.30. + +# Community Thanks! +We’re immensely grateful for all the community contributions that help make Contour even better! For this release, special thanks go out to the following contributors: + +- @clayton-gonsalves +- @davinci26 +- @erikflores7 +- @lubronzhan +- @shadialtarsha +- @therealak12 + + +# Are you a Contour user? We would love to know! +If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://projectcontour.io/resources/adopters/). If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269). diff --git a/changelogs/unreleased/6145-skriss-deprecation.md b/changelogs/unreleased/6145-skriss-deprecation.md deleted file mode 100644 index 168e7666284..00000000000 --- a/changelogs/unreleased/6145-skriss-deprecation.md +++ /dev/null @@ -1,4 +0,0 @@ -## Configuring Contour with a GatewayClass controller name is no longer supported - -Contour can no longer be configured with a GatewayClass controller name (gateway.controllerName in the config file or ContourConfiguration CRD), as the config field has been removed. -Instead, either use a specific Gateway reference (gateway.gatewayRef), or use the Gateway provisioner. diff --git a/changelogs/unreleased/6146-skriss-deprecation.md b/changelogs/unreleased/6146-skriss-deprecation.md deleted file mode 100644 index 3390cab7e85..00000000000 --- a/changelogs/unreleased/6146-skriss-deprecation.md +++ /dev/null @@ -1,5 +0,0 @@ -## Contour xDS server implementation is now deprecated - -As of this release, the `contour` xDS server implementation is now deprecated. -Once the go-control-plane based `envoy` xDS server has had sufficient production bake time, the `contour` implementation will be removed from Contour. -Notification of removal will occur at least one release in advance. diff --git a/changelogs/unreleased/6146-skriss-major.md b/changelogs/unreleased/6146-skriss-major.md deleted file mode 100644 index 5340d272fc7..00000000000 --- a/changelogs/unreleased/6146-skriss-major.md +++ /dev/null @@ -1,25 +0,0 @@ -## Default xDS Server Implementation is now Envoy - -As of this release, Contour now uses the `envoy` xDS server implementation by default. -This xDS server implementation is based on Envoy's [go-control-plane project](https://github.com/envoyproxy/go-control-plane) and will eventually be the only supported xDS server implementation in Contour. -This change is expected to be transparent to users. - -### I'm seeing issues after upgrading, how to I revert to the contour xDS server? - -If you encounter any issues, you can easily revert to the `contour` xDS server with the following configuration: - -(if using Contour config file) -```yaml -server: - xds-server-type: contour -``` - -(if using ContourConfiguration CRD -```yaml -... -spec: - xdsServer: - type: contour -``` - -You will need to restart Contour for the changes to take effect. diff --git a/changelogs/unreleased/6153-sunjayBhatia-major.md b/changelogs/unreleased/6153-sunjayBhatia-major.md deleted file mode 100644 index c35c6e25bbe..00000000000 --- a/changelogs/unreleased/6153-sunjayBhatia-major.md +++ /dev/null @@ -1,5 +0,0 @@ -## Gateway API: Inform on v1 types - -Contour no longer informs on v1beta1 resources that have graduated to v1. -This includes the "core" resources GatewayClass, Gateway, and HTTPRoute. -This means that users should ensure they have updated CRDs to Gateway API v1.0.0 or newer, which introduced the v1 version with compatibility with v1beta1. diff --git a/changelogs/unreleased/6185-sunjayBhatia-small.md b/changelogs/unreleased/6185-sunjayBhatia-small.md deleted file mode 100644 index ef1bb0a8169..00000000000 --- a/changelogs/unreleased/6185-sunjayBhatia-small.md +++ /dev/null @@ -1 +0,0 @@ -Fix data race in BackendTLSPolicy status update logic. diff --git a/changelogs/unreleased/6230-yangyy93-small.md b/changelogs/unreleased/6230-yangyy93-small.md deleted file mode 100644 index bc07a9b327f..00000000000 --- a/changelogs/unreleased/6230-yangyy93-small.md +++ /dev/null @@ -1 +0,0 @@ -Fix for specifying a health check port with an ExternalName Service. diff --git a/changelogs/unreleased/6246-skriss-small.md b/changelogs/unreleased/6246-skriss-small.md deleted file mode 100644 index be0bf9fa7d1..00000000000 --- a/changelogs/unreleased/6246-skriss-small.md +++ /dev/null @@ -1 +0,0 @@ -Updates the example `envoyproxy/ratelimit` image tag to `19f2079f`, for multi-arch support and other improvements. \ No newline at end of file diff --git a/changelogs/unreleased/6250-skriss-small.md b/changelogs/unreleased/6250-skriss-small.md deleted file mode 100644 index 9a93efe2d60..00000000000 --- a/changelogs/unreleased/6250-skriss-small.md +++ /dev/null @@ -1 +0,0 @@ -In the `envoy` go-control-plane xDS server, use a separate snapshot cache for Endpoints, to minimize the amount of unnecessary xDS traffic generated. \ No newline at end of file diff --git a/changelogs/unreleased/6265-sunjayBhatia-small.md b/changelogs/unreleased/6265-sunjayBhatia-small.md deleted file mode 100644 index 4da8bf71353..00000000000 --- a/changelogs/unreleased/6265-sunjayBhatia-small.md +++ /dev/null @@ -1 +0,0 @@ -Updates to Go 1.22.1. See the [Go release notes](https://go.dev/doc/devel/release#go1.22.minor) for more information. diff --git a/changelogs/unreleased/6283-sunjayBhatia-minor.md b/changelogs/unreleased/6283-sunjayBhatia-minor.md deleted file mode 100644 index 3541f49c0fe..00000000000 --- a/changelogs/unreleased/6283-sunjayBhatia-minor.md +++ /dev/null @@ -1,5 +0,0 @@ -## Update Envoy to v1.29.2 - -See the release notes [here](https://www.envoyproxy.io/docs/envoy/v1.29.2/version_history/v1.29/v1.29.2). - -Note that this Envoy version reverts the HTTP/2 codec back to `nghttp2` from `oghttp2`. diff --git a/changelogs/unreleased/6288-sunjayBhatia-minor.md b/changelogs/unreleased/6288-sunjayBhatia-minor.md deleted file mode 100644 index 32563f9f707..00000000000 --- a/changelogs/unreleased/6288-sunjayBhatia-minor.md +++ /dev/null @@ -1,7 +0,0 @@ -## Disable Envoy removing TE header - -As of version v1.29.0, Envoy removes the hop-by-hop TE header. -However, this causes issues with HTTP/2, particularly gRPC, with implementations expecting the header to be present (and set to `trailers`). -Contour disables this via Envoy runtime setting and reverts to the v1.28.x and prior behavior of allowing the header to be proxied. - -Once [this Envoy PR that enables the TE header including `trailers` to be forwarded](https://github.com/envoyproxy/envoy/pull/32255) is backported to a release or a new minor is cut, Contour will no longer set the aforementioned runtime key. diff --git a/changelogs/unreleased/6614-tsaarni-small.md b/changelogs/unreleased/6614-tsaarni-small.md new file mode 100644 index 00000000000..1eac9f3117a --- /dev/null +++ b/changelogs/unreleased/6614-tsaarni-small.md @@ -0,0 +1 @@ +Fixed a bug where follower Contour instance occasionally got stuck in a non-ready state when using `--watch-namespaces` flag. diff --git a/changelogs/unreleased/6616-Krast76-small.md b/changelogs/unreleased/6616-Krast76-small.md new file mode 100644 index 00000000000..b44b28c7263 --- /dev/null +++ b/changelogs/unreleased/6616-Krast76-small.md @@ -0,0 +1 @@ +Contour, support http and https as AppProtocol in k8s' services diff --git a/changelogs/unreleased/6643-sunjayBhatia-small.md b/changelogs/unreleased/6643-sunjayBhatia-small.md new file mode 100644 index 00000000000..4d60cf2cafe --- /dev/null +++ b/changelogs/unreleased/6643-sunjayBhatia-small.md @@ -0,0 +1 @@ +Updates kind node image for e2e tests to Kubernetes 1.31. Supported/tested Kubernetes versions are now 1.31, 1.30, and 1.29. diff --git a/changelogs/unreleased/6714-tsaarni-small.md b/changelogs/unreleased/6714-tsaarni-small.md new file mode 100644 index 00000000000..7628057f739 --- /dev/null +++ b/changelogs/unreleased/6714-tsaarni-small.md @@ -0,0 +1 @@ +Updates Envoy to v1.32.0. See the [Envoy release notes](https://www.envoyproxy.io/docs/envoy/v1.32.0/version_history/v1.32/v1.32.0) for more information about the content of the release. diff --git a/cmd/contour/cli.go b/cmd/contour/cli.go index 0f7ae7ca4af..66281679882 100644 --- a/cmd/contour/cli.go +++ b/cmd/contour/cli.go @@ -109,7 +109,7 @@ func (c *Client) dial() *grpc.ClientConn { options = append(options, grpc.WithTransportCredentials(insecure.NewCredentials())) } - conn, err := grpc.Dial(c.ContourAddr, options...) + conn, err := grpc.NewClient(c.ContourAddr, options...) if err != nil { c.Log.WithError(err).Fatal("failed connecting Contour Server") } diff --git a/cmd/contour/gatewayprovisioner.go b/cmd/contour/gatewayprovisioner.go index 4fa733ab27d..efc0816b21f 100644 --- a/cmd/contour/gatewayprovisioner.go +++ b/cmd/contour/gatewayprovisioner.go @@ -36,7 +36,7 @@ func registerGatewayProvisioner(app *kingpin.Application) (*kingpin.CmdClause, * provisionerConfig := &gatewayProvisionerConfig{ contourImage: "ghcr.io/projectcontour/contour:main", - envoyImage: "docker.io/envoyproxy/envoy:v1.29.2", + envoyImage: "docker.io/envoyproxy/envoy:v1.32.0", metricsBindAddress: ":8080", leaderElection: false, leaderElectionID: "0d879e31.projectcontour.io", diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go index 0697b45a2f8..1c48f9fce88 100644 --- a/cmd/contour/serve.go +++ b/cmd/contour/serve.go @@ -44,6 +44,7 @@ import ( controller_runtime_metrics_server "sigs.k8s.io/controller-runtime/pkg/metrics/server" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -508,6 +509,7 @@ func (s *Server) doServe() error { // the contents of the Contour xDS caches after the DAG is built. var snapshotHandler *xdscache_v3.SnapshotHandler + // nolint:staticcheck if contourConfiguration.XDSServer.Type == contour_v1alpha1.EnvoyServerType { snapshotHandler = xdscache_v3.NewSnapshotHandler(resources, s.log.WithField("context", "snapshotHandler")) @@ -922,6 +924,7 @@ func (x *xdsServer) Start(ctx context.Context) error { grpcServer := xds.NewServer(x.registry, grpcOptions(log, x.config.TLS)...) + // nolint:staticcheck switch x.config.Type { case contour_v1alpha1.EnvoyServerType: contour_xds_v3.RegisterServer(envoy_server_v3.NewServer(ctx, x.snapshotHandler.GetCache(), contour_xds_v3.NewRequestLoggingCallbacks(log)), grpcServer) @@ -929,6 +932,7 @@ func (x *xdsServer) Start(ctx context.Context) error { contour_xds_v3.RegisterServer(contour_xds_v3.NewContourServer(log, xdscache.ResourcesOf(x.resources)...), grpcServer) default: // This can't happen due to config validation. + // nolint:staticcheck log.Fatalf("invalid xDS server type %q", x.config.Type) } @@ -943,6 +947,7 @@ func (x *xdsServer) Start(ctx context.Context) error { log = log.WithField("insecure", true) } + // nolint:staticcheck log.Infof("started xDS server type: %q", x.config.Type) defer log.Info("stopped xDS server") @@ -1018,9 +1023,9 @@ func (s *Server) setupGatewayAPI(contourConfiguration contour_v1alpha1.ContourCo "referencegrants": &gatewayapi_v1beta1.ReferenceGrant{}, "namespaces": &core_v1.Namespace{}, "tlsroutes": &gatewayapi_v1alpha2.TLSRoute{}, - "grpcroutes": &gatewayapi_v1alpha2.GRPCRoute{}, + "grpcroutes": &gatewayapi_v1.GRPCRoute{}, "tcproutes": &gatewayapi_v1alpha2.TCPRoute{}, - "backendtlspolicies": &gatewayapi_v1alpha2.BackendTLSPolicy{}, + "backendtlspolicies": &gatewayapi_v1alpha3.BackendTLSPolicy{}, "configmaps": &core_v1.ConfigMap{}, } @@ -1063,7 +1068,7 @@ type dagBuilderConfig struct { maxRequestsPerConnection *uint32 perConnectionBufferLimitBytes *uint32 globalRateLimitService *contour_v1alpha1.RateLimitServiceConfig - globalCircuitBreakerDefaults *contour_v1alpha1.GlobalCircuitBreakerDefaults + globalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers upstreamTLS *dag.UpstreamTLS } @@ -1140,10 +1145,10 @@ func (s *Server) getDAGBuilder(dbc dagBuilderConfig) *dag.Builder { &dag.ExtensionServiceProcessor{ // Note that ExtensionService does not support ExternalName, if it does get added, // need to bring EnableExternalNameService in here too. - FieldLogger: s.log.WithField("context", "ExtensionServiceProcessor"), - ClientCertificate: dbc.clientCert, - ConnectTimeout: dbc.connectTimeout, - UpstreamTLS: dbc.upstreamTLS, + FieldLogger: s.log.WithField("context", "ExtensionServiceProcessor"), + ClientCertificate: dbc.clientCert, + ConnectTimeout: dbc.connectTimeout, + GlobalCircuitBreakerDefaults: dbc.globalCircuitBreakerDefaults, }, &dag.HTTPProxyProcessor{ EnableExternalNameService: dbc.enableExternalNameService, diff --git a/cmd/contour/serve_test.go b/cmd/contour/serve_test.go index 248e9bc17c4..f7846e5dffb 100644 --- a/cmd/contour/serve_test.go +++ b/cmd/contour/serve_test.go @@ -125,7 +125,7 @@ func TestGetDAGBuilder(t *testing.T) { }) t.Run("GlobalCircuitBreakerDefaults specified for all processors", func(t *testing.T) { - g := contour_v1alpha1.GlobalCircuitBreakerDefaults{ + g := contour_v1alpha1.CircuitBreakers{ MaxConnections: 100, } diff --git a/cmd/contour/servecontext.go b/cmd/contour/servecontext.go index 3a1057b6479..51a6c3a726a 100644 --- a/cmd/contour/servecontext.go +++ b/cmd/contour/servecontext.go @@ -24,6 +24,7 @@ import ( "time" "github.com/sirupsen/logrus" + "golang.org/x/net/http2" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/keepalive" @@ -209,6 +210,7 @@ func tlsconfig(log logrus.FieldLogger, contourXDSTLS *contour_v1alpha1.TLS) *tls ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: certPool, MinVersion: tls.VersionTLS13, + NextProtos: []string{http2.NextProtoTLS}, }, nil } diff --git a/cmd/contour/servecontext_test.go b/cmd/contour/servecontext_test.go index 766a2f0af83..5187bcc090d 100644 --- a/cmd/contour/servecontext_test.go +++ b/cmd/contour/servecontext_test.go @@ -14,6 +14,7 @@ package main import ( + "context" "crypto/tls" "crypto/x509" "net" @@ -24,8 +25,11 @@ import ( "testing" "time" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/tsaarni/certyaml" + "golang.org/x/net/http2" "google.golang.org/grpc" "k8s.io/utils/ptr" @@ -152,7 +156,7 @@ func TestServeContextCertificateHandling(t *testing.T) { caCertPool := x509.NewCertPool() ca, err := trustedCACert.X509Certificate() - checkFatalErr(t, err) + require.NoError(t, err) caCertPool.AddCert(&ca) tests := map[string]struct { @@ -184,7 +188,7 @@ func TestServeContextCertificateHandling(t *testing.T) { // Create temporary directory to store certificates and key for the server. configDir, err := os.MkdirTemp("", "contour-testdata-") - checkFatalErr(t, err) + require.NoError(t, err) defer os.RemoveAll(configDir) contourTLS := &contour_v1alpha1.TLS{ @@ -197,25 +201,24 @@ func TestServeContextCertificateHandling(t *testing.T) { // Initial set of credentials must be written into temp directory before // starting the tests to avoid error at server startup. err = trustedCACert.WritePEM(contourTLS.CAFile, filepath.Join(configDir, "CAkey.pem")) - checkFatalErr(t, err) + require.NoError(t, err) err = contourCertBeforeRotation.WritePEM(contourTLS.CertFile, contourTLS.KeyFile) - checkFatalErr(t, err) + require.NoError(t, err) // Start a dummy server. log := fixture.NewTestLogger(t) opts := grpcOptions(log, contourTLS) g := grpc.NewServer(opts...) - if g == nil { - t.Error("failed to create server") - } + require.NotNil(t, g) - address := "localhost:8001" - l, err := net.Listen("tcp", address) - checkFatalErr(t, err) + l, err := net.Listen("tcp", "localhost:") + require.NoError(t, err) + address := l.Addr().String() go func() { - err := g.Serve(l) - checkFatalErr(t, err) + // If server fails to start, connecting to it below will fail so + // can ignore the error. + _ = g.Serve(l) }() defer g.GracefulStop() @@ -223,15 +226,16 @@ func TestServeContextCertificateHandling(t *testing.T) { t.Run(name, func(t *testing.T) { // Store certificate and key to temp dir used by serveContext. err = tc.serverCredentials.WritePEM(contourTLS.CertFile, contourTLS.KeyFile) - checkFatalErr(t, err) - clientCert, _ := tc.clientCredentials.TLSCertificate() + require.NoError(t, err) + clientCert, err := tc.clientCredentials.TLSCertificate() + require.NoError(t, err) receivedCert, err := tryConnect(address, clientCert, caCertPool) - gotError := err != nil - if gotError != tc.expectError { - t.Errorf("Unexpected result when connecting to the server: %s", err) - } - if err == nil { - expectedCert, _ := tc.serverCredentials.X509Certificate() + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + expectedCert, err := tc.serverCredentials.X509Certificate() + require.NoError(t, err) assert.Equal(t, &expectedCert, receivedCert) } }) @@ -242,7 +246,7 @@ func TestTlsVersionDeprecation(t *testing.T) { // To get tls.Config for the gRPC XDS server, we need to arrange valid TLS certificates and keys. // Create temporary directory to store them for the server. configDir, err := os.MkdirTemp("", "contour-testdata-") - checkFatalErr(t, err) + require.NoError(t, err) defer os.RemoveAll(configDir) caCert := certyaml.Certificate{ @@ -261,9 +265,9 @@ func TestTlsVersionDeprecation(t *testing.T) { } err = caCert.WritePEM(contourTLS.CAFile, filepath.Join(configDir, "CAkey.pem")) - checkFatalErr(t, err) + require.NoError(t, err) err = contourCert.WritePEM(contourTLS.CertFile, contourTLS.KeyFile) - checkFatalErr(t, err) + require.NoError(t, err) // Get preliminary TLS config from the serveContext. log := fixture.NewTestLogger(t) @@ -271,36 +275,33 @@ func TestTlsVersionDeprecation(t *testing.T) { // Get actual TLS config that will be used during TLS handshake. tlsConfig, err := preliminaryTLSConfig.GetConfigForClient(nil) - checkFatalErr(t, err) + require.NoError(t, err) assert.Equal(t, tlsConfig.MinVersion, uint16(tls.VersionTLS13)) } -func checkFatalErr(t *testing.T, err error) { - t.Helper() - if err != nil { - t.Fatal(err) - } -} - // tryConnect tries to establish TLS connection to the server. // If successful, return the server certificate. func tryConnect(address string, clientCert tls.Certificate, caCertPool *x509.CertPool) (*x509.Certificate, error) { + rawConn, err := net.Dial("tcp", address) + if err != nil { + rawConn.Close() + return nil, errors.Wrapf(err, "error dialing %s", address) + } + clientConfig := &tls.Config{ ServerName: "localhost", MinVersion: tls.VersionTLS13, Certificates: []tls.Certificate{clientCert}, RootCAs: caCertPool, + NextProtos: []string{http2.NextProtoTLS}, } - conn, err := tls.Dial("tcp", address, clientConfig) - if err != nil { - return nil, err - } + + conn := tls.Client(rawConn, clientConfig) defer conn.Close() - err = peekError(conn) - if err != nil { - return nil, err + if err := peekError(conn); err != nil { + return nil, errors.Wrap(err, "error peeking TLS alert") } return conn.ConnectionState().PeerCertificates[0], nil @@ -311,12 +312,12 @@ func tryConnect(address string, clientCert tls.Certificate, caCertPool *x509.Cer // To receive alert for bad certificate, this function tries to read one byte. // Adapted from https://golang.org/src/crypto/tls/handshake_client_test.go func peekError(conn net.Conn) error { - _ = conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) + if err := conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + return err + } _, err := conn.Read(make([]byte, 1)) - if err != nil { - if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() { - return err - } + if err != nil && !errors.Is(err, context.DeadlineExceeded) { + return err } return nil } @@ -767,7 +768,7 @@ func TestConvertServeContext(t *testing.T) { }, "global circuit breaker defaults": { getServeContext: func(ctx *serveContext) *serveContext { - ctx.Config.Cluster.GlobalCircuitBreakerDefaults = &contour_v1alpha1.GlobalCircuitBreakerDefaults{ + ctx.Config.Cluster.GlobalCircuitBreakerDefaults = &contour_v1alpha1.CircuitBreakers{ MaxConnections: 4, MaxPendingRequests: 5, MaxRequests: 6, @@ -776,7 +777,7 @@ func TestConvertServeContext(t *testing.T) { return ctx }, getContourConfiguration: func(cfg contour_v1alpha1.ContourConfigurationSpec) contour_v1alpha1.ContourConfigurationSpec { - cfg.Envoy.Cluster.GlobalCircuitBreakerDefaults = &contour_v1alpha1.GlobalCircuitBreakerDefaults{ + cfg.Envoy.Cluster.GlobalCircuitBreakerDefaults = &contour_v1alpha1.CircuitBreakers{ MaxConnections: 4, MaxPendingRequests: 5, MaxRequests: 6, diff --git a/cmd/contour/shutdownmanager.go b/cmd/contour/shutdownmanager.go index 305a5303903..fc22a473ba0 100644 --- a/cmd/contour/shutdownmanager.go +++ b/cmd/contour/shutdownmanager.go @@ -31,7 +31,9 @@ import ( ) const ( - prometheusURL = "http://unix/stats/prometheus" + // The prometheusURL is used to fetch the envoy metrics. Note that the filter + // value matches Envoy's raw stat names (i.e. those on the `/stats/` endpoint). + prometheusURL = "http://unix/stats/prometheus?filter=^http\\..*\\.downstream_cx_active$" healthcheckFailURL = "http://unix/healthcheck/fail" prometheusStat = "envoy_http_downstream_cx_active" ) diff --git a/docs/README.md b/docs/README.md index 7ee7f907e6d..1c0c91bdcd8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,5 @@ # Contour Documentation -The contents of this directory have moved to [projectcontour.io](https://projectcontour.io/). -Specifically; +The contents of this directory have moved to corresponding directories in [../site/content](../site/content). -* Guides and How-to's have moved to [projectcontour.io/guides](https://projectcontour.io/guides) -* Versioned release documentation has moved to [projectcontour.io/docs](https://projectcontour.io/docs) -* Project related and non-versioned documentation has moved to [projectcontour.io/resources](https://projectcontour.io/resources/) - -For more about how we're thinking of Contour's future, check out [the design docs](../design/). +For more information on how to contribute to the Contour documentation, see the [Contour Technical Documentation Contributing Guide](https://projectcontour.io/resources/contributing-docs/). diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index 0666bd83e57..a6bf34783a2 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourconfigurations.projectcontour.io spec: preserveUnknownFields: false @@ -120,6 +120,12 @@ spec: defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -600,9 +606,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -872,6 +878,8 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -894,6 +902,9 @@ spec: the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -987,10 +998,14 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -1143,6 +1158,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -1273,12 +1290,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 @@ -1360,7 +1372,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourdeployments.projectcontour.io spec: preserveUnknownFields: false @@ -1425,9 +1437,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: @@ -1594,6 +1603,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 @@ -1676,12 +1691,8 @@ spec: use to replace existing DaemonSet pods with new pods. 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: @@ -1752,9 +1763,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: @@ -1814,6 +1822,8 @@ spec: to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). type: string name: description: This must match the Name of a Volume. @@ -1823,6 +1833,21 @@ spec: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. type: boolean + recursiveReadOnly: + description: |- + 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 + field is set to Enabled, the mount is made recursively read-only if it is + 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: description: |- Path within the volume from which the container's volume should be mounted. @@ -1858,7 +1883,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: |- @@ -1898,6 +1922,7 @@ spec: 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. @@ -1911,6 +1936,7 @@ spec: to shared' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -1950,6 +1976,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic path: description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' @@ -1971,10 +1998,13 @@ spec: More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2010,10 +2040,13 @@ spec: to OpenStack. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2078,11 +2111,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the ConfigMap @@ -2115,10 +2152,13 @@ spec: secret object contains more than one secret, all secret references are passed. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2162,8 +2202,8 @@ spec: properties: fieldRef: description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' + pod: only annotations, labels, name, namespace + and uid are supported.' properties: apiVersion: description: Version of the schema the FieldPath @@ -2222,6 +2262,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object emptyDir: description: |- @@ -2313,6 +2354,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -2457,11 +2499,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2489,8 +2533,8 @@ spec: If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be 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/persistent-volumes#volumeattributesclass - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). type: string volumeMode: description: |- @@ -2516,7 +2560,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 lun number' @@ -2533,6 +2576,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic wwids: description: |- wwids Optional: FC volume world wide identifiers (wwids) @@ -2540,6 +2584,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object flexVolume: description: |- @@ -2576,10 +2621,13 @@ spec: scripts. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2613,7 +2661,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: |- @@ -2694,9 +2741,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: |- @@ -2713,6 +2757,39 @@ 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 @@ -2733,7 +2810,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: |- @@ -2745,6 +2821,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -2760,6 +2837,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic readOnly: description: |- readOnly here will force the ReadOnly setting in VolumeMounts. @@ -2770,10 +2848,13 @@ spec: target and initiator authentication properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2892,10 +2973,13 @@ 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: |- @@ -2944,11 +3028,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3027,11 +3113,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the @@ -3054,7 +3144,7 @@ spec: fieldRef: description: 'Required: Selects a field of the pod: only annotations, labels, - name and namespace are supported.' + name, namespace and uid are supported.' properties: apiVersion: description: Version of the schema @@ -3118,6 +3208,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object secret: description: secret information about the secret @@ -3161,11 +3252,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional field specify whether @@ -3204,6 +3299,7 @@ spec: type: object type: object type: array + x-kubernetes-list-type: atomic type: object quobyte: description: quobyte represents a Quobyte mount on the host @@ -3254,7 +3350,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: |- @@ -3262,6 +3357,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. @@ -3274,7 +3370,9 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -3294,14 +3392,18 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -3316,6 +3418,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -3341,10 +3444,13 @@ spec: sensitive information. If this is not provided, Login operation will fail. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3353,6 +3459,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: |- storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. @@ -3429,6 +3536,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic optional: description: optional field specify whether the Secret or its keys must be defined @@ -3460,10 +3568,13 @@ spec: credentials. If not specified, default values will be attempted. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3677,6 +3788,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 @@ -3805,6 +3922,12 @@ spec: Service; defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -4285,9 +4408,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -4558,6 +4681,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -4580,6 +4705,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -4673,10 +4801,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -4830,6 +4962,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -4842,16 +4976,8 @@ spec: description: Conditions describe the current conditions of the ContourDeployment resource. 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: |- @@ -4892,12 +5018,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 @@ -4923,7 +5044,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: extensionservices.projectcontour.io spec: preserveUnknownFields: false @@ -4968,6 +5089,39 @@ spec: description: ExtensionServiceSpec defines the desired state of an ExtensionService resource. properties: + circuitBreakerPolicy: + description: |- + CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. + If defined this overrides the global circuit breaker budget. + properties: + maxConnections: + description: The maximum number of connections that a single Envoy + instance allows to the Kubernetes Service; defaults to 1024. + format: int32 + type: integer + maxPendingRequests: + description: The maximum number of pending requests that a single + Envoy instance allows to the Kubernetes Service; defaults to + 1024. + format: int32 + type: integer + maxRequests: + description: The maximum parallel requests a single Envoy instance + allows to the Kubernetes Service; defaults to 1024 + format: int32 + type: integer + maxRetries: + description: The maximum number of parallel retries a single Envoy + instance allows to the Kubernetes Service; defaults to 3. + format: int32 + type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer + type: object loadBalancerPolicy: description: |- The policy for load balancing GRPC service requests. Note that the @@ -5005,6 +5159,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -5019,6 +5175,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -5286,12 +5444,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 @@ -5371,7 +5524,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: httpproxies.projectcontour.io spec: preserveUnknownFields: false @@ -6063,6 +6216,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6077,6 +6232,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -6177,6 +6334,8 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -6200,6 +6359,9 @@ spec: the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -6293,10 +6455,14 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -6941,6 +7107,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6955,6 +7123,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -7621,6 +7791,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -7643,6 +7815,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -7736,10 +7911,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -8078,12 +8257,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 @@ -8202,8 +8376,6 @@ spec: CamelCase names - cloud provider specific error values must have names that comply with the format foo.example.com/CamelCase. - --- - 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 @@ -8213,12 +8385,12 @@ spec: format: int32 type: integer protocol: - default: TCP description: |- Protocol is the protocol of the service port of which status is recorded here The supported values are: "TCP", "UDP", "SCTP" type: string required: + - error - port - protocol type: object @@ -8226,6 +8398,7 @@ spec: x-kubernetes-list-type: atomic type: object type: array + x-kubernetes-list-type: atomic type: object type: object required: @@ -8241,7 +8414,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: tlscertificatedelegations.projectcontour.io spec: preserveUnknownFields: false @@ -8442,12 +8615,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/examples/contour/03-contour.yaml b/examples/contour/03-contour.yaml index a49c3851e4a..2db6109d01d 100644 --- a/examples/contour/03-contour.yaml +++ b/examples/contour/03-contour.yaml @@ -19,9 +19,6 @@ spec: app: contour template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8000" labels: app: contour spec: diff --git a/examples/contour/03-envoy.yaml b/examples/contour/03-envoy.yaml index 60fdd185f94..b9c71f39ba8 100644 --- a/examples/contour/03-envoy.yaml +++ b/examples/contour/03-envoy.yaml @@ -16,10 +16,6 @@ spec: app: envoy template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8002" - prometheus.io/path: "/stats/prometheus" labels: app: envoy spec: @@ -50,7 +46,7 @@ spec: - --log-level info command: - envoy - image: docker.io/envoyproxy/envoy:v1.29.2 + image: docker.io/envoyproxy/envoy:v1.32.0 imagePullPolicy: IfNotPresent name: envoy env: @@ -73,6 +69,10 @@ spec: hostPort: 443 name: https protocol: TCP + - containerPort: 8002 + hostPort: 8002 + name: metrics + protocol: TCP readinessProbe: httpGet: path: /ready diff --git a/examples/deployment/03-envoy-deployment.yaml b/examples/deployment/03-envoy-deployment.yaml index e0b0ba34d4c..265e70e844e 100644 --- a/examples/deployment/03-envoy-deployment.yaml +++ b/examples/deployment/03-envoy-deployment.yaml @@ -19,10 +19,6 @@ spec: app: envoy template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8002" - prometheus.io/path: "/stats/prometheus" labels: app: envoy spec: @@ -62,7 +58,7 @@ spec: - --log-level info command: - envoy - image: docker.io/envoyproxy/envoy:v1.29.2 + image: docker.io/envoyproxy/envoy:v1.32.0 imagePullPolicy: IfNotPresent name: envoy env: @@ -85,6 +81,10 @@ spec: hostPort: 443 name: https protocol: TCP + - containerPort: 8002 + hostPort: 8002 + name: metrics + protocol: TCP readinessProbe: httpGet: path: /ready diff --git a/examples/gateway-provisioner/01-roles.yaml b/examples/gateway-provisioner/01-roles.yaml index e48893105d6..3aee795aef8 100644 --- a/examples/gateway-provisioner/01-roles.yaml +++ b/examples/gateway-provisioner/01-roles.yaml @@ -13,8 +13,6 @@ rules: - configmaps - endpoints - namespaces - - secrets - - services verbs: - get - list @@ -103,22 +101,6 @@ rules: - tlsroutes/status verbs: - update -- apiGroups: - - gateway.networking.k8s.io - resources: - - gatewayclasses - - gateways - verbs: - - get - - list - - watch -- apiGroups: - - gateway.networking.k8s.io - resources: - - gatewayclasses/status - - gateways/status - verbs: - - update - apiGroups: - networking.k8s.io resources: @@ -146,17 +128,6 @@ rules: - list - update - watch -- apiGroups: - - projectcontour.io - resources: - - contourconfigurations - - extensionservices - - httpproxies - - tlscertificatedelegations - verbs: - - get - - list - - watch - apiGroups: - projectcontour.io resources: @@ -171,6 +142,9 @@ rules: - projectcontour.io resources: - contourdeployments + - extensionservices + - httpproxies + - tlscertificatedelegations verbs: - get - list diff --git a/examples/gateway/00-crds.yaml b/examples/gateway/00-crds.yaml index bbb71f11f65..8a50a1fa26a 100644 --- a/examples/gateway/00-crds.yaml +++ b/examples/gateway/00-crds.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 The Kubernetes Authors. +# Copyright 2024 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,30 +17,28 @@ # --- # -# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendlbpolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - labels: - gateway.networking.k8s.io/policy: Direct - name: backendtlspolicies.gateway.networking.k8s.io + name: backendlbpolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: BackendTLSPolicy - listKind: BackendTLSPolicyList - plural: backendtlspolicies + kind: BackendLBPolicy + listKind: BackendLBPolicyList + plural: backendlbpolicies shortNames: - - btlspolicy - singular: backendtlspolicy + - blbpolicy + singular: backendlbpolicy scope: Namespaced versions: - additionalPrinterColumns: @@ -50,332 +48,400 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: BackendTLSPolicy provides a way to configure how a Gateway connects - to a Backend via TLS. + description: |- + BackendLBPolicy provides a way to define load balancing rules + for a backend. 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' + 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' + 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 BackendTLSPolicy. + description: Spec defines the desired state of BackendLBPolicy. properties: - targetRef: - description: "TargetRef identifies an API object to apply the policy - to. Only Services have Extended support. Implementations MAY support - additional objects, with Implementation Specific support. Note that - this config applies to the entire referenced resource by default, - but this default may change in the future to provide a more granular - application of the policy. \n Support: Extended for Kubernetes Service - \n Support: Implementation-specific for any other resource" + sessionPersistence: + description: |- + SessionPersistence defines and configures session persistence + for the backend. + + + Support: Extended properties: - group: - description: Group is the group of the target resource. - 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 target resource. - 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 target resource. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace is the namespace of the referent. When - unspecified, the local namespace is inferred. Even when policy - targets a resource in a different namespace, it MUST only apply - to traffic originating from the same namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 - sectionName: - description: "SectionName is the name of a section within the - target resource. When unspecified, this targetRef targets the - entire resource. In the following resources, SectionName is - interpreted as the following: \n * Gateway: Listener Name * - Service: Port Name \n 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." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + 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 - required: - - group - - kind - - name - type: object - tls: - description: TLS contains backend TLS policy configuration. - properties: - caCertRefs: - description: "CACertRefs contains one or more references to Kubernetes - objects that contain a PEM-encoded TLS CA certificate bundle, - which is used to validate a TLS handshake between the Gateway - and backend Pod. \n If CACertRefs is empty or unspecified, then - WellKnownCACerts must be specified. Only one of CACertRefs or - WellKnownCACerts may be specified, not both. If CACertRefs is - empty or unspecified, the configuration for WellKnownCACerts - MUST be honored instead. \n References to a resource in a different - namespace are invalid for the moment, although we will revisit - this in the future. \n A single CACertRef 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. \n Support: Core - An optional single - reference to a Kubernetes ConfigMap, with the CA certificate - in a key named `ca.crt`. \n Support: Implementation-specific - (More than one reference, or other kinds of resources)." - items: - description: "LocalObjectReference identifies an API object - within the namespace of the referrer. 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. \n 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." - 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 - maxItems: 8 - type: array - hostname: - description: "Hostname is used for two purposes in the connection - between Gateways and backends: \n 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. \n 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])?)*$ + 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 - wellKnownCACerts: - description: "WellKnownCACerts specifies whether system CA certificates - may be used in the TLS handshake between the gateway and backend - pod. \n If WellKnownCACerts is unspecified or empty (\"\"), - then CACertRefs must be specified with at least one entry for - a valid configuration. Only one of CACertRefs or WellKnownCACerts - may be specified, not both. \n Support: Core for \"System\"" + 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: - - System + - Cookie + - Header type: string - required: - - hostname type: object x-kubernetes-validations: - - message: must not contain both CACertRefs and WellKnownCACerts - rule: '!(has(self.caCertRefs) && size(self.caCertRefs) > 0 && has(self.wellKnownCACerts) - && self.wellKnownCACerts != "")' - - message: must specify either CACertRefs or WellKnownCACerts - rule: (has(self.caCertRefs) && size(self.caCertRefs) > 0 || has(self.wellKnownCACerts) - && self.wellKnownCACerts != "") + - message: AbsoluteTimeout must be specified when cookie lifetimeType + is Permanent + rule: '!has(self.cookieConfig.lifetimeType) || self.cookieConfig.lifetimeType + != ''Permanent'' || has(self.absoluteTimeout)' + targetRefs: + description: |- + TargetRef identifies an API object to apply policy to. + Currently, Backends (i.e. Service, ServiceImport, or any + implementation-specific backendRef) are the only valid API + target references. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + 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 target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - group + - kind + - name + x-kubernetes-list-type: map required: - - targetRef - - tls + - targetRefs type: object status: - description: Status defines the current state of BackendTLSPolicy. + description: Status defines the current state of BackendLBPolicy. properties: ancestors: - description: "Ancestors is a list of ancestor resources (usually Gateways) - that are associated with the policy, and the status of the policy - with respect to each ancestor. When this policy attaches to a parent, - the controller that manages the parent and the ancestors MUST add - an entry to this list when the controller first sees the policy - and SHOULD update the entry as appropriate when the relevant ancestor - is modified. \n 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. \n 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. \n 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. \n A maximum of 16 ancestors will be represented - in this list. An empty list means the Policy is not relevant for - any ancestors. \n 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 here. For example, if this list was full on - BackendTLSPolicy, no additional Gateways would be able to reference - the Service targeted by the BackendTLSPolicy." + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + 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 + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. items: - description: "PolicyAncestorStatus describes the status of a route - with respect to an associated Ancestor. \n 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 the GatewayClass. Almost always, in - this hierarchy, the Gateway will be the most useful object to - place Policy status on, so we recommend that implementations SHOULD - use Gateway as the PolicyAncestorStatus object unless the designers - have a _very_ good reason otherwise. \n 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. \n 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. \n 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. \n 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. \n 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." + description: |- + 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 + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + 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: ancestorRef: - description: AncestorRef corresponds with a ParentRef in the - spec that this PolicyAncestorStatus struct describes the status - of. + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -388,46 +454,45 @@ spec: respect to the given Ancestor. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -441,12 +506,12 @@ 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. + --- + 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 @@ -464,16 +529,23 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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\/\-._~%!$&'()*+,;=:]+$ @@ -502,490 +574,594 @@ status: storedVersions: null --- # -# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - name: gatewayclasses.gateway.networking.k8s.io + labels: + gateway.networking.k8s.io/policy: Direct + name: backendtlspolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: GatewayClass - listKind: GatewayClassList - plural: gatewayclasses + kind: BackendTLSPolicy + listKind: BackendTLSPolicyList + plural: backendtlspolicies shortNames: - - gc - singular: gatewayclass - scope: Cluster + - btlspolicy + singular: backendtlspolicy + scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1 + name: v1alpha3 schema: openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n 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 propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n 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. \n GatewayClass is - a Cluster level resource." + description: |- + BackendTLSPolicy provides a way to configure how a Gateway + connects to a Backend via TLS. 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' + 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' + 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 GatewayClass. + description: Spec defines the desired state of BackendTLSPolicy. properties: - controllerName: - description: "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. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n 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. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. - 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. - 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 referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - name - type: object - required: - - controllerName - type: object - status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." - properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + targetRefs: + description: |- + TargetRefs identifies an API object to apply the policy to. + Only Services have Extended support. Implementations MAY support + additional objects, with Implementation Specific support. + Note that this config applies to the entire referenced resource + 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: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a + direct policy to. This should be used as part of Policy resources that can + target single resources. For more information on how this policy attachment + 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. 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 + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ 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 + kind: + description: Kind is kind of the target resource. + maxLength: 63 minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + 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 + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 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])$ + sectionName: + description: |- + SectionName is the name of a section within the target resource. When + 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. + 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: - - lastTransitionTime - - message - - reason - - status - - type + - group + - kind + - name type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 + maxItems: 16 + minItems: 1 type: array - x-kubernetes-list-type: set - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n 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 propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n 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. \n GatewayClass is - a Cluster level resource." - 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 GatewayClass. - properties: - controllerName: - description: "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. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n 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. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" + validation: + description: Validation contains backend TLS validation configuration. properties: - group: - description: Group is the group of the referent. - 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. - 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. + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to Kubernetes objects that + 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: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + 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. + 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 + maxItems: 8 + type: array + hostname: + description: |- + 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. + + + 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 - namespace: - description: Namespace is the namespace of the referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 + implementation does not support the WellKnownCACertificates field or the value + 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 type: string required: - - group - - kind - - name + - hostname type: object + x-kubernetes-validations: + - message: must not contain both CACertificateRefs and WellKnownCACertificates + rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs) + > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates + != "")' + - message: must specify either CACertificateRefs or WellKnownCACertificates + rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs) + > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates + != "") required: - - controllerName + - targetRefs + - validation type: object status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." + description: Status defines the current state of BackendTLSPolicy. properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + 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 + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + 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 + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + 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: - 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 + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus 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 + conditions: + 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}" + 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-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])$ + 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 required: - - lastTransitionTime - - message - - reason - - status - - type + - ancestorRef + - controllerName type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 + maxItems: 16 type: array - x-kubernetes-list-type: set + required: + - ancestors type: object required: - spec @@ -1002,723 +1178,236 @@ status: storedVersions: null --- # -# config/crd/experimental/gateway.networking.k8s.io_gateways.yaml +# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - name: gateways.gateway.networking.k8s.io + name: gatewayclasses.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: Gateway - listKind: GatewayList - plural: gateways + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses shortNames: - - gtw - singular: gateway - scope: Namespaced + - gc + singular: gatewayclass + scope: Cluster versions: - additionalPrinterColumns: - - jsonPath: .spec.gatewayClassName - name: Class - type: string - - jsonPath: .status.addresses[*].value - name: Address + - jsonPath: .spec.controllerName + name: Controller type: string - - jsonPath: .status.conditions[?(@.type=="Programmed")].status - name: Programmed + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted type: string - jsonPath: .metadata.creationTimestamp name: Age type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string name: v1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + 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 + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + 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: - 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' + 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' + 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 Gateway. + description: Spec defines the desired state of GatewayClass. properties: - addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n 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. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " - items: - description: GatewayAddress describes an address that can be bound - to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: IPAddress values must be unique - rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, - a2.type == a1.type && a2.value == a1.value) : true )' - - 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 )' - gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + controllerName: + description: |- + 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 + 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 - infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + 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. + + + 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: - annotations: - 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: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - 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 - minLength: 0 - type: string - description: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n 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 \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n 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. \n For example, the following - Listener scenarios are distinct: \n 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 \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n 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. \n 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. \n 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. \n 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 `\"\"`. \n 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. \n 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\"`. \n 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\". \n 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 accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n 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 indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 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. \n 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. \n 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. - \n 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 to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" - items: - description: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. - properties: - allowedRoutes: - default: - namespaces: - from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n 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: \n * 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 a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - 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, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" - properties: - kinds: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n 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. \n Support: Core" - items: - description: RouteGroupKind indicates the group and kind - of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - namespaces: - default: - from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" - properties: - from: - default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * 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. \n Support: - Core" - enum: - - All - - Selector - - Same - type: string - selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - type: object - hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * 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 protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n 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. \n 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`. \n 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 - name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n 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 - port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n 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]+$ - type: string - tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" - properties: - certificateRefs: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n 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. - \n 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. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" - items: - description: "SecretObjectReference identifies an API - object including its namespace, defaulting to Secret. - \n 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. \n 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." - 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. \n 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. - \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - name - type: object - maxItems: 64 - type: array - mode: - default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" - enum: - - Terminate - - Passthrough - type: string - 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. \n 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. \n Support: Implementation-specific" - maxProperties: 16 - type: object - type: object - x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType - is Terminate - rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' - required: - - name - - port - - protocol - type: object - maxItems: 64 - minItems: 1 - type: array - x-kubernetes-list-map-keys: + group: + description: Group is the group of the referent. + 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. + 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 referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind - name - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - - message: tls must not be specified for protocols ['HTTP', 'TCP', - 'UDP'] - rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? - !has(l.tls) : true)' - - message: hostname must not be specified for protocols ['TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) - || l.hostname == '''') : true)' - - message: Listener name must be unique within the Gateway - rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) - - message: Combination of port, protocol and hostname must be unique - for each listener - rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol - == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname - == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + type: object required: - - gatewayClassName - - listeners + - controllerName type: object status: default: conditions: - lastTransitionTime: "1970-01-01T00:00:00Z" message: Waiting for controller - reason: Pending + reason: Waiting status: Unknown type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: Status defines the current state of Gateway. + description: |- + Status defines the current state of GatewayClass. + + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. properties: - addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * 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) \n " - items: - description: GatewayStatusAddress describes a network address that - is bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n 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. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + 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. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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. + 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. + 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. + 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. + 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 @@ -1732,11 +1421,12 @@ 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. + --- + 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 @@ -1752,965 +1442,4907 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map - listeners: - description: Listeners provide status for each unique listener port - defined in the Spec. + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. items: - description: ListenerStatus is the status associated with a Listener. - properties: - attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n 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 a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." - format: int32 - type: integer - conditions: - 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. --- This struct - is intended for direct use as an array at the field path - .status.conditions. For example, \n type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" - 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 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - name: - description: Name is the name of the Listener that this status - corresponds to. - 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 - supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n 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 and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." - items: - description: RouteGroupKind indicates the group and kind of - a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - required: - - attachedRoutes - - conditions - - name - - supportedKinds - type: object + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string maxItems: 64 type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map + x-kubernetes-list-type: set type: object required: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: - - jsonPath: .spec.gatewayClassName - name: Class - type: string - - jsonPath: .status.addresses[*].value - name: Address + - jsonPath: .spec.controllerName + name: Controller type: string - - jsonPath: .status.conditions[?(@.type=="Programmed")].status - name: Programmed + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted type: string - jsonPath: .metadata.creationTimestamp name: Age type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string name: v1beta1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + 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 + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + 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: - 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' + 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' + 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 Gateway. + description: Spec defines the desired state of GatewayClass. properties: - addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n 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. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " - items: - description: GatewayAddress describes an address that can be bound - to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: IPAddress values must be unique - rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, - a2.type == a1.type && a2.value == a1.value) : true )' - - 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 )' - gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + controllerName: + description: |- + 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 + 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 - infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + 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. + + + 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: - annotations: - 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: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - 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 - minLength: 0 - type: string - description: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" - maxProperties: 8 - type: object + group: + description: Group is the group of the referent. + 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. + 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 referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n 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 \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n 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. \n For example, the following - Listener scenarios are distinct: \n 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 \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n 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. \n 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. \n 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. \n 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 `\"\"`. \n 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. \n 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\"`. \n 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\". \n 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 accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n 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 indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 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. \n 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. \n 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. - \n 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 to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + 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: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + 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: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. + 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: - allowedRoutes: - default: - namespaces: - from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n 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: \n * 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 a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - 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, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" - properties: - kinds: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n 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. \n Support: Core" - items: - description: RouteGroupKind indicates the group and kind - of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - namespaces: - default: - from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" - properties: - from: - default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * 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. \n Support: - Core" - enum: - - All - - Selector - - Same - type: string - selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - type: object - hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * 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 protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n 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. \n 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`. \n 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])?)*$ + 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 - name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n 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])?)*$ + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 type: string - port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" - format: int32 - maximum: 65535 - minimum: 1 + 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 - protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n Support: Core" - maxLength: 255 + 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-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-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ type: string - tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" - properties: - certificateRefs: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n 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. - \n 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. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" - items: - description: "SecretObjectReference identifies an API - object including its namespace, defaulting to Secret. - \n 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. \n 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." - 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])?$ + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. + items: + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_gateways.yaml +# +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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: gateways.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gtw + singular: gateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + 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. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + 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 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - 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 )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + + Support: Core + + + properties: + annotations: + 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: |- + 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 + 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 + minLength: 0 + 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. + + + Support: Extended + maxProperties: 8 + type: object + 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: + description: Group is the group of the referent. + 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. + 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 + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + 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 + "Listeners in a single Gateway" because implementations MAY merge configuration + 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 + "TLS" Protocol that all have unique Hostname values. + 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 + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + 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 + indicate in the Message which Listeners are conflicted, and which are + 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 + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + 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: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + 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 + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + 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, + support for that Route rule should be dropped to ensure consistency. For + 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: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + 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 + of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + 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: + default: Same + description: |- + 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 + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + 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: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + 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 + protocol layers as described above. If an implementation does not + 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 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + 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]+$ + type: string + tls: + description: |- + TLS is the TLS configuration for the Listener. This field is required if + 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: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + 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. + 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 + maxItems: 64 + type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + 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: |- + 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 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 + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + 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. + 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 "ConfigMap" 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 + 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: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object + mode: + default: Terminate + description: |- + 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 + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + 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 + type: object + x-kubernetes-validations: + - message: certificateRefs or options must be specified when + mode is Terminate + rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) + > 0 || size(self.options) > 0 : true' + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: tls must not be specified for protocols ['HTTP', 'TCP', + 'UDP'] + rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? + !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' + - message: hostname must not be specified for protocols ['TCP', 'UDP'] + rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) + || l.hostname == '''') : true)' + - message: Listener name must be unique within the Gateway + rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) + - message: Combination of port, protocol and hostname must be unique + for each listener + rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol + == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname + == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + 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. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + 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 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + 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}" + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port + defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: |- + 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 + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + 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 + type: integer + conditions: + 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}" + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status + corresponds to. + 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 + supportedKinds: + description: |- + SupportedKinds is the list indicating the Kinds supported by this + 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 + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. + items: + description: RouteGroupKind indicates the group and kind of + a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + 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 Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + 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. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + 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 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - 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 )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + + Support: Core + + + properties: + annotations: + 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: |- + 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 + 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 + minLength: 0 + 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. + + + Support: Extended + maxProperties: 8 + type: object + 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: + description: Group is the group of the referent. + 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. + 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 + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + 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 + "Listeners in a single Gateway" because implementations MAY merge configuration + 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 + "TLS" Protocol that all have unique Hostname values. + 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 + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + 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 + indicate in the Message which Listeners are conflicted, and which are + 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 + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + 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: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + 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 + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + 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, + support for that Route rule should be dropped to ensure consistency. For + 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: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + 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 + of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + 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: + default: Same + description: |- + 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 + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + 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: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + 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 + protocol layers as described above. If an implementation does not + 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 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + 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]+$ + type: string + tls: + description: |- + TLS is the TLS configuration for the Listener. This field is required if + 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: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + 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. + 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 + maxItems: 64 + type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + 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: |- + 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 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 + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + 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. + 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 "ConfigMap" 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 + 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: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object + mode: + default: Terminate + description: |- + 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 + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + + Support: Core + enum: + - Terminate + - Passthrough + type: string + 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 + type: object + x-kubernetes-validations: + - message: certificateRefs or options must be specified when + mode is Terminate + rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) + > 0 || size(self.options) > 0 : true' + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: tls must not be specified for protocols ['HTTP', 'TCP', + 'UDP'] + rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? + !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' + - message: hostname must not be specified for protocols ['TCP', 'UDP'] + rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) + || l.hostname == '''') : true)' + - message: Listener name must be unique within the Gateway + rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) + - message: Combination of port, protocol and hostname must be unique + for each listener + rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol + == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname + == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + 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. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + 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 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + 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}" + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port + defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: |- + 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 + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + 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 + type: integer + conditions: + 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}" + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status + corresponds to. + 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 + supportedKinds: + description: |- + SupportedKinds is the list indicating the Kinds supported by this + 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 + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. + items: + description: RouteGroupKind indicates the group and kind of + a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml +# +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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: grpcroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GRPCRoute + listKind: GRPCRouteList + plural: grpcroutes + singular: grpcroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + 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 - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 + 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 - namespace: - description: "Namespace is the namespace of the referenced - object. When unspecified, the local namespace is - inferred. \n 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. - \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 - required: - - name type: object - maxItems: 64 - type: array - mode: - default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" - enum: - - Terminate - - Passthrough + 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 - 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. \n 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. \n Support: Implementation-specific" - maxProperties: 16 + 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: certificateRefs must be specified when TLSModeType - is Terminate - rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' - required: - - name - - port - - protocol + - 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: 64 - minItems: 1 + maxItems: 16 type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - - message: tls must not be specified for protocols ['HTTP', 'TCP', - 'UDP'] - rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? - !has(l.tls) : true)' - - message: hostname must not be specified for protocols ['TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) - || l.hostname == '''') : true)' - - message: Listener name must be unique within the Gateway - rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) - - message: Combination of port, protocol and hostname must be unique - for each listener - rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol - == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname - == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' - required: - - gatewayClassName - - listeners type: object status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: Status defines the current state of Gateway. + description: Status defines the current state of GRPCRoute. properties: - addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * 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) \n " - items: - description: GatewayStatusAddress describes a network address that - is bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching - ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): - true' - maxItems: 16 - type: array - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n 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. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - 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 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - listeners: - description: Listeners provide status for each unique listener port - defined in the Spec. + 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: ListenerStatus is the status associated with a Listener. + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. properties: - attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n 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 a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." - format: int32 - type: integer conditions: - description: Conditions describe the current condition of this - listener. + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -2724,12 +6356,12 @@ 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. + --- + 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 @@ -2741,138 +6373,254 @@ spec: - type type: object maxItems: 8 + minItems: 1 type: array x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map - name: - description: Name is the name of the Listener that this status - corresponds to. + 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])?)*$ + 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 - supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n 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 and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." - items: - description: RouteGroupKind indicates the group and kind of - a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - 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 Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array + 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: - - attachedRoutes - - conditions - - name - - supportedKinds + - controllerName + - parentRef type: object - maxItems: 64 + maxItems: 32 type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map + required: + - parents type: object - required: - - spec type: object served: true storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null ---- -# -# config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: grpcroutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: GRPCRoute - listKind: GRPCRouteList - plural: grpcroutes - singular: grpcroute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.hostnames - name: Hostnames - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date + - 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. \n 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. - \n 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. \n 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\". + 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." + 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' + 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' + 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 @@ -2880,56 +6628,86 @@ 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: \n 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. \n 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: - \n * 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`. + 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. - \n 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`. \n 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. \n 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. \n 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: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n The rejected Route MUST raise an 'Accepted' condition with a - status of 'False' in the corresponding RouteParentStatus. \n Support: - Core" + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -2937,165 +6715,246 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -3131,82 +6990,117 @@ spec: 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). + 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. - \n See the GRPCBackendRef definition for the rules about what - makes a single GRPCBackendRef invalid. \n 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. \n 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. \n Support: Core for Kubernetes - Service \n Support: Implementation-specific for any other - resource \n Support for weight: Core" + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in GRPCRouteRule.)" + 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. + 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. \n Support: Implementation-specific \n - This filter can be used multiple times within - the same rule." + 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. + 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 @@ -3228,35 +7122,50 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -3277,44 +7186,68 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -3336,64 +7269,80 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -3404,29 +7353,29 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -3442,35 +7391,50 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -3491,44 +7455,68 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -3550,32 +7538,38 @@ spec: 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: \n - - 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. - \n - Extended: Filter types and their corresponding - configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - - 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. - \n Implementers are encouraged to define custom - implementation types to extend the core API with - implementation-specific behavior. \n 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. \n " + 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 @@ -3626,25 +7620,33 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -3655,43 +7657,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -3706,44 +7716,63 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. - \n Specifying the same filter multiple times is not supported - unless explicitly indicated in the filter. \n If an implementation - can not support a combination of filters, it must clearly + 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. \n Support: Core" + 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. + 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. \n Support: Implementation-specific \n This - filter can be used multiple times within the same rule." + 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. + 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 @@ -3765,32 +7794,49 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -3811,40 +7857,67 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -3866,60 +7939,80 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -3930,25 +8023,28 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -3965,32 +8061,49 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -4011,40 +8124,67 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -4066,29 +8206,38 @@ spec: 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: \n - 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. \n - Extended: Filter types and their - corresponding configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - 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. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n " + 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 @@ -4137,60 +8286,110 @@ spec: 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. \n For example, take the following matches configuration: - \n ``` matches: - method: service: foo.bar headers: values: - version: 2 - method: service: foo.bar.v2 ``` \n For a request - to match against this rule, it MUST satisfy EITHER of the - two conditions: \n - service of foo.bar AND contains the header - `version: 2` - service of foo.bar.v2 \n See the documentation - for GRPCRouteMatch on how to specify multiple match conditions - to be ANDed together. \n If no matches are specified, the - implementation MUST match every gRPC request. \n 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: \n * Characters in a matching non-wildcard hostname. * - Characters in a matching hostname. * Characters in a matching - service. * Characters in a matching method. * Header matches. - \n If ties still exist across multiple Routes, matching precedence - MUST be determined in order of the following criteria, continuing - on ties: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n 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." + 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. \n For example, the match - below will match a gRPC request only if its service is `foo` - AND it contains the `version: v1` header: \n ``` matches: - - method: type: Exact service: \"foo\" headers: - name: - \"version\" value \"v1\" \n ```" + 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. + 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. + 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. \n 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." + 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|~]+$ @@ -4219,31 +8418,39 @@ spec: - 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. + 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. - \n At least one of Service and Method MUST be a - non-empty string." + 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. - \n At least one of Service and Method MUST be a - non-empty string." + 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) \n Support: Implementation-specific - (Exact with method specified but no service specified) - \n Support: Implementation-specific (RegularExpression)" + 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 @@ -4267,6 +8474,106 @@ spec: 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 @@ -4275,81 +8582,94 @@ spec: 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -4363,12 +8683,12 @@ 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. + --- + 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 @@ -4386,131 +8706,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -4529,9 +8893,7 @@ spec: type: object type: object served: true - storage: true - subresources: - status: {} + storage: false status: acceptedNames: kind: "" @@ -4546,8 +8908,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: httproutes.gateway.networking.k8s.io @@ -4572,20 +8934,26 @@ spec: name: v1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -4593,57 +8961,90 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: - \n * 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`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + 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`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n 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`. \n 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. \n 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. \n 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: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -4651,165 +9052,246 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -4850,81 +9332,120 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n 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. - \n 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. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + 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 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. + + + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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 should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + 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: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + 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. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -4946,35 +9467,50 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -4995,44 +9531,68 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -5054,64 +9614,80 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -5122,29 +9698,29 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -5160,84 +9736,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -5263,95 +9843,128 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * 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 well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -5372,44 +9985,68 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -5431,37 +10068,46 @@ spec: 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: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n 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. \n + 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 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` 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. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -5471,79 +10117,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -5641,25 +10292,33 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -5670,43 +10329,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -5721,46 +10388,77 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n 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 + description: |- + 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 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. \n Support: Core" + 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: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + 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. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -5782,32 +10480,49 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -5828,40 +10543,67 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -5883,60 +10625,80 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -5947,25 +10709,28 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -5982,77 +10747,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -6078,88 +10854,127 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * 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 - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -6180,40 +10995,67 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -6235,33 +11077,46 @@ spec: 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: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + 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 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` 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -6271,73 +11126,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -6430,86 +11296,134 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n 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: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n 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. \n 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." + description: |- + Matches define conditions used for matching the rule against incoming + 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: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + 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 action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + 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 + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n 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. - \n 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: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, 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: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". 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. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n 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 determine the supported dialect." + 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 + determine the supported dialect. enum: - Exact - RegularExpression @@ -6530,9 +11444,13 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended enum: - GET - HEAD @@ -6548,15 +11466,20 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -6615,48 +11538,60 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n 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. \n 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 match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + 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 + match against the first value of the param if the data plane supports it, + 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 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + 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 + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -6679,39 +11614,168 @@ spec: 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)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + + Support: Extended + + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway 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. \n 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. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + 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. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n 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. - \n 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. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + 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. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -6769,81 +11833,94 @@ spec: description: Status defines the current state of HTTPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -6857,12 +11934,12 @@ 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. + --- + 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 @@ -6880,131 +11957,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -7025,7 +12146,7 @@ spec: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: @@ -7038,20 +12159,26 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -7059,57 +12186,90 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: - \n * 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`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + 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`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n 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`. \n 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. \n 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. \n 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: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -7117,165 +12277,246 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -7316,81 +12557,120 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n 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. - \n 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. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + 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 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. + + + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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 should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + 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: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + 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. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -7412,35 +12692,50 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -7461,44 +12756,68 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -7520,64 +12839,80 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -7588,29 +12923,29 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -7626,84 +12961,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -7729,95 +13068,128 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * 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 well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -7838,44 +13210,68 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -7897,37 +13293,46 @@ spec: 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: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n 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. \n + 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 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` 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. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -7937,79 +13342,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -8107,25 +13517,33 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -8136,43 +13554,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -8187,46 +13613,77 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n 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 + description: |- + 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 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. \n Support: Core" + 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: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + 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. + + + This filter can be used multiple times within the same rule. + + + Support: Implementation-specific 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. + 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 @@ -8248,32 +13705,49 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -8294,40 +13768,67 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -8349,60 +13850,80 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -8413,25 +13934,28 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -8448,77 +13972,88 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -8544,88 +14079,127 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * 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 - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -8646,40 +14220,67 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -8701,33 +14302,46 @@ spec: 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: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + 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 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` 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -8737,73 +14351,84 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + + 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -8896,86 +14521,134 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n 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: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n 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. \n 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." + description: |- + Matches define conditions used for matching the rule against incoming + 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: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + 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 action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + 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 + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n 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. - \n 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: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, 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: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". 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. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n 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 determine the supported dialect." + 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 + determine the supported dialect. enum: - Exact - RegularExpression @@ -8996,9 +14669,13 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + + Support: Extended enum: - GET - HEAD @@ -9014,15 +14691,20 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + + Support: Core (Exact, PathPrefix) + + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -9081,48 +14763,60 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n 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. \n 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 match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + 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 + match against the first value of the param if the data plane supports it, + 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 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + 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 + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -9145,39 +14839,168 @@ spec: 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)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + + Support: Extended + + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway 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. \n 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. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + 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. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n 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. - \n 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. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + 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. + + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -9235,81 +15058,94 @@ spec: description: Status defines the current state of HTTPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -9323,12 +15159,12 @@ 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. + --- + 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 @@ -9346,131 +15182,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -9491,7 +15371,7 @@ spec: - spec type: object served: true - storage: true + storage: false subresources: status: {} status: @@ -9508,8 +15388,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: referencegrants.gateway.networking.k8s.io @@ -9536,32 +15416,45 @@ spec: 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. \n 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. \n 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. \n 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." + 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' + 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' + 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 @@ -9569,35 +15462,59 @@ 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. \n Support: Core" + 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. \n Support: Core" + 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. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + 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. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -9611,35 +15528,47 @@ spec: 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. - \n Support: Core" + 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. + 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. \n Support: Core" + 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: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + 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. + 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 @@ -9665,28 +15594,41 @@ spec: name: v1beta1 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. \n 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. \n All cross-namespace references in Gateway API - (with the exception of cross-namespace Gateway-route attachment) require - a ReferenceGrant. \n 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." + 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. + + + 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 + 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' + 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' + 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 @@ -9694,35 +15636,59 @@ 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. \n Support: Core" + 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. \n Support: Core" + 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. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + 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. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -9736,35 +15702,47 @@ spec: 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. - \n Support: Core" + 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. + 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. \n Support: Core" + 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: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + 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. + 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 @@ -9797,8 +15775,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tcproutes.gateway.networking.k8s.io @@ -9820,19 +15798,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: TCPRoute provides a way to route TCP requests. When combined - with a Gateway listener, it can be used to forward connections on the port - specified by the listener to a set of backends specified by the TCPRoute. + description: |- + TCPRoute provides a way to route TCP requests. When combined with a Gateway + listener, it can be used to forward connections on the port specified by the + listener to a set of backends specified by the TCPRoute. 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' + 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' + 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 @@ -9840,165 +15824,246 @@ spec: description: Spec defines the desired state of TCPRoute. properties: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -10037,62 +16102,94 @@ spec: description: TCPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Connection rejections must respect - weight; if an invalid backend is requested to have 80% of + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Connection rejections must + respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Extended" + + + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -10103,43 +16200,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -10165,81 +16270,94 @@ spec: description: Status defines the current state of TCPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -10253,12 +16371,12 @@ 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. + --- + 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 @@ -10276,131 +16394,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -10438,8 +16600,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tlsroutes.gateway.networking.k8s.io @@ -10461,21 +16623,29 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: "The TLSRoute resource is similar to TCPRoute, but can be configured - to match against TLS-specific metadata. This allows more flexibility in - matching streams for a given TLS listener. \n 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." + description: |- + The TLSRoute resource is similar to TCPRoute, but can be configured + 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: 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' + 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' + 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 @@ -10483,43 +16653,65 @@ spec: description: Spec defines the desired state of TLSRoute. properties: hostnames: - description: "Hostnames defines a set of SNI names that should match - against the SNI attribute of TLS ClientHello message in TLS handshake. - This matches the RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: \n * 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`. * A Listener with `*.example.com` as the hostname - matches TLSRoutes 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. \n 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. \n 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. \n Support: Core" + description: |- + Hostnames defines a set of SNI names that should match against the + 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`. + * A Listener with `*.example.com` as the hostname matches TLSRoutes + 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. + + + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -10527,165 +16719,246 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -10724,65 +16997,97 @@ spec: description: TLSRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the rule performs no forwarding; if no filters are specified - that would result in a response being sent, the underlying - implementation must actively reject request attempts to this - backend, by rejecting the connection or returning a 500 status - code. Request rejections must respect weight; if an invalid - backend is requested to have 80% of requests, then 80% of - requests must be rejected instead. \n Support: Core for Kubernetes - Service \n Support: Extended for Kubernetes ServiceImport - \n Support: Implementation-specific for any other resource - \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or + a Service with no endpoints), the rule performs no forwarding; if no + filters are specified that would result in a response being sent, the + underlying implementation must actively reject request attempts to this + backend, by rejecting the connection or returning a 500 status code. + Request rejections must respect weight; if an invalid backend is + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -10793,43 +17098,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -10855,81 +17168,94 @@ spec: description: Status defines the current state of TLSRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -10943,12 +17269,12 @@ 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. + --- + 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 @@ -10966,131 +17292,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -11128,8 +17498,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: udproutes.gateway.networking.k8s.io @@ -11151,19 +17521,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: UDPRoute provides a way to route UDP traffic. When combined with - a Gateway listener, it can be used to forward traffic on the port specified - by the listener to a set of backends specified by the UDPRoute. + description: |- + UDPRoute provides a way to route UDP traffic. When combined with a Gateway + listener, it can be used to forward traffic on the port specified by the + listener to a set of backends specified by the UDPRoute. 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' + 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' + 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 @@ -11171,165 +17547,246 @@ spec: description: Spec defines the desired state of UDPRoute. properties: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -11368,62 +17825,94 @@ spec: description: UDPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Packet drops must respect weight; - if an invalid backend is requested to have 80% of the packets, - then 80% of packets must be dropped instead. \n Support: Core - for Kubernetes Service \n Support: Extended for Kubernetes - ServiceImport \n Support: Implementation-specific for any - other resource \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Packet drops must + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -11434,43 +17923,51 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -11496,81 +17993,94 @@ spec: description: Status defines the current state of UDPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -11584,12 +18094,12 @@ 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. + --- + 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 @@ -11607,131 +18117,175 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ diff --git a/examples/grafana/01-namespace.yaml b/examples/grafana/01-namespace.yaml deleted file mode 100644 index 113151fc0a0..00000000000 --- a/examples/grafana/01-namespace.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: projectcontour-monitoring - labels: - app: projectcontour-monitoring diff --git a/examples/grafana/03-grafana-deployment.yaml b/examples/grafana/03-grafana-deployment.yaml deleted file mode 100644 index a8bf7614158..00000000000 --- a/examples/grafana/03-grafana-deployment.yaml +++ /dev/null @@ -1,79 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: grafana - name: grafana - namespace: projectcontour-monitoring -spec: - selector: - matchLabels: - app: grafana - replicas: 1 - template: - metadata: - labels: - app: grafana - spec: - containers: - - name: grafana - image: grafana/grafana:5.0.4 - imagePullPolicy: Always - env: - - name: GF_SECURITY_ADMIN_USER - valueFrom: - secretKeyRef: - name: grafana - key: grafana-admin-user - - name: GF_SECURITY_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: grafana - key: grafana-admin-password - ports: - - containerPort: 3000 - readinessProbe: - httpGet: - path: /api/health - port: 3000 - initialDelaySeconds: 30 - timeoutSeconds: 30 - resources: - requests: - cpu: 100m - memory: 100Mi - volumeMounts: - - name: config-volume - mountPath: /etc/grafana - - name: dashboards-volume - mountPath: /var/lib/grafana/dashboards - - name: storage-volume - mountPath: /var/lib/grafana - - name: dashboard-provider - mountPath: /etc/grafana/provisioning/dashboards - - name: datasources-provider - mountPath: /etc/grafana/provisioning/datasources - terminationGracePeriodSeconds: 300 - volumes: - - name: config-volume - configMap: - name: grafana-config - - name: dashboards-volume - configMap: - name: grafana-dashs - - name: storage-volume - emptyDir: {} - - name: dashboard-provider - configMap: - name: grafana-dash-provider - items: - - key: providers.yaml - path: providers.yaml - - name: datasources-provider - configMap: - name: grafana-datasources-provider - items: - - key: providers.yaml - path: providers.yaml ---- diff --git a/examples/grafana/03-grafana-service.yaml b/examples/grafana/03-grafana-service.yaml deleted file mode 100644 index 628b3e8188d..00000000000 --- a/examples/grafana/03-grafana-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: grafana - name: grafana - namespace: projectcontour-monitoring -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: 3000 - selector: - app: grafana - type: "ClusterIP" ---- diff --git a/examples/grafana/02-grafana-configmap.yaml b/examples/grafana/dashboards.yaml similarity index 96% rename from examples/grafana/02-grafana-configmap.yaml rename to examples/grafana/dashboards.yaml index 2a0a2605129..57ea9f76126 100644 --- a/examples/grafana/02-grafana-configmap.yaml +++ b/examples/grafana/dashboards.yaml @@ -1,12 +1,10 @@ apiVersion: v1 kind: ConfigMap metadata: - labels: - app: grafana - name: grafana-dashs - namespace: projectcontour-monitoring + name: grafana-dashboard-contour-httpproxies + namespace: monitoring data: - contour-proxy.json: | + contour-httpproxies.json: | { "__inputs": [{ "name": "DS_PROMETHEUS", @@ -809,7 +807,14 @@ data: "uid": "KYcCfvKik", "version": 1 } - envoy.json: | +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-dashboard-contour-envoy + namespace: monitoring +data: + contour-envoy.json: | { "annotations": { "list": [ @@ -2912,7 +2917,14 @@ data: "uid": "khVnG8iiz", "version": 7 } - apiserver.json: | +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-dashboard-contour-api + namespace: monitoring +data: + contour-api.json: | { "annotations": { "list": [ @@ -3246,174 +3258,3 @@ data: "uid": "u4C2S-QZz", "version": 8 } - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app: grafana - name: grafana-config - namespace: projectcontour-monitoring -data: - grafana.ini: | - ; instance_name = ${HOSTNAME} - [paths] - data = /var/lib/grafana/data - logs = /var/log/grafana - plugins = /var/lib/grafana/plugins - - [server] - ;protocol = http - ;http_addr = - ;http_port = 3000 - ;domain = localhost - ;enforce_domain = false - ;root_url = %(protocol)s://%(domain)s:%(http_port)s/ - ;router_logging = false - ;static_root_path = public - ;enable_gzip = false - ;cert_file = - ;cert_key = - - [database] - ;type = sqlite3 - ;host = 127.0.0.1:3306 - ;name = grafana - ;user = root - ;password = - ;ssl_mode = disable - ;path = grafana.db - - [session] - ;provider = file - ;provider_config = sessions - ;cookie_name = grafana_sess - ;cookie_secure = false - ;session_life_time = 86400 - - [analytics] - ;reporting_enabled = true - check_for_updates = true - ;google_analytics_ua_id = - - [security] - ;admin_user = admin - ;admin_password = - ;secret_key = - ;login_remember_days = 7 - ;cookie_username = grafana_user - ;cookie_remember_name = grafana_remember - ;disable_gravatar = false - ;data_source_proxy_whitelist = - - [snapshots] - ;external_enabled = true - ;external_snapshot_url = https://snapshots-origin.raintank.io - ;external_snapshot_name = Publish to snapshot.raintank.io - - [users] - ;allow_sign_up = true - ;allow_org_create = true - ;auto_assign_org = true - ;auto_assign_org_role = Viewer - ;login_hint = email or username - ;default_theme = dark - - [auth.anonymous] - ;enabled = false - ;org_name = Main Org. - ;org_role = Viewer - - [auth.proxy] - ;enabled = false - ;header_name = X-WEBAUTH-USER - ;header_property = username - ;auto_sign_up = true - - [auth.basic] - ;enabled = true - - [auth.ldap] - ;enabled = false - ;config_file = /etc/grafana/ldap.toml - - [smtp] - ;enabled = false - ;host = localhost:25 - ;user = - ;password = - ;cert_file = - ;key_file = - ;skip_verify = false - ;from_address = admin@grafana.localhost - - [emails] - ;welcome_email_on_sign_up = false - - [log] - mode = console - level = info - - [log.console] - ;level = - ;format = console - - [event_publisher] - ;enabled = false - ;rabbitmq_url = amqp://localhost/ - ;exchange = grafana_events - - [dashboards.json] - enabled = true - path = /var/lib/grafana/dashboards - - [metrics] - ;enabled = true - ;interval_seconds = 10 - - ; [metrics.graphite] - ; address = localhost:2003 - ; prefix = prod.grafana.%(instance_name)s. - - [grafana_net] - url = https://grafana.net ---- -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app: grafana - name: grafana-dash-provider - namespace: projectcontour-monitoring -data: - providers.yaml: | - apiVersion: 1 - providers: - - name: 'default' - orgId: 1 - folder: '' - type: file - disableDeletion: false - editable: false - options: - path: /var/lib/grafana/dashboards ---- -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app: grafana - name: grafana-datasources-provider - namespace: projectcontour-monitoring -data: - providers.yaml: | - apiVersion: 1 - datasources: - - name: 'prometheus' - type: prometheus - access: proxy - orgId: 1 - url: http://prometheus:9090 - isDefault: true - editable: false diff --git a/examples/grafana/deployment-patch.json b/examples/grafana/deployment-patch.json new file mode 100644 index 00000000000..cfbbeb7239b --- /dev/null +++ b/examples/grafana/deployment-patch.json @@ -0,0 +1,59 @@ +[ + { + "op": "add", + "path": "/spec/template/spec/volumes/-", + "value": { + "configMap": { + "defaultMode": 420, + "name": "grafana-dashboard-contour-httpproxies" + }, + "name": "grafana-dashboard-contour-httpproxies" + } + }, + { + "op": "add", + "path": "/spec/template/spec/volumes/-", + "value": { + "configMap": { + "defaultMode": 420, + "name": "grafana-dashboard-contour-envoy" + }, + "name": "grafana-dashboard-contour-envoy" + } + }, + { + "op": "add", + "path": "/spec/template/spec/volumes/-", + "value": { + "configMap": { + "defaultMode": 420, + "name": "grafana-dashboard-contour-api" + }, + "name": "grafana-dashboard-contour-api" + } + }, + { + "op": "add", + "path": "/spec/template/spec/containers/0/volumeMounts/-", + "value": { + "mountPath": "/grafana-dashboard-definitions/0/contour-httpproxies", + "name": "grafana-dashboard-contour-httpproxies" + } + }, + { + "op": "add", + "path": "/spec/template/spec/containers/0/volumeMounts/-", + "value": { + "mountPath": "/grafana-dashboard-definitions/0/contour-envoy", + "name": "grafana-dashboard-contour-envoy" + } + }, + { + "op": "add", + "path": "/spec/template/spec/containers/0/volumeMounts/-", + "value": { + "mountPath": "/grafana-dashboard-definitions/0/contour-api", + "name": "grafana-dashboard-contour-api" + } + } +] \ No newline at end of file diff --git a/examples/grafana/httpproxy.yaml b/examples/grafana/httpproxy.yaml new file mode 100644 index 00000000000..bcc42593be2 --- /dev/null +++ b/examples/grafana/httpproxy.yaml @@ -0,0 +1,14 @@ +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: grafana + namespace: monitoring +spec: + virtualhost: + fqdn: grafana-example.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: grafana + port: 3000 diff --git a/examples/prometheus/01-namespace.yaml b/examples/prometheus/01-namespace.yaml deleted file mode 100644 index 113151fc0a0..00000000000 --- a/examples/prometheus/01-namespace.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: projectcontour-monitoring - labels: - app: projectcontour-monitoring diff --git a/examples/prometheus/02-prometheus-alertmanager-configmap.yaml b/examples/prometheus/02-prometheus-alertmanager-configmap.yaml deleted file mode 100644 index 9699c5779b7..00000000000 --- a/examples/prometheus/02-prometheus-alertmanager-configmap.yaml +++ /dev/null @@ -1,104 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: prometheus-alertmanager - namespace: projectcontour-monitoring -data: - alertmanager.yml: |- - global: - - ## - # tool to help visualize where your alerts are going - # https://prometheus.io/webtools/alerting/routing-tree-editor/ - ## - - # The directory from which notification templates are read. - templates: - - '/etc/alertmanager/templates/*.tmpl' - - # The root route on which each incoming alert enters. - route: - # The labels by which incoming alerts are grouped together. For example, - # multiple alerts coming in for cluster=A and alertname=LatencyHigh would - # be batched into a single group. - group_by: ['alertname', 'cluster', 'service'] - - # When a new group of alerts is created by an incoming alert, wait at - # least 'group_wait' to send the initial notification. - # This way ensures that you get multiple alerts for the same group that start - # firing shortly after another are batched together on the first - # notification. - group_wait: 30s - - # When the first notification was sent, wait 'group_interval' to send a batch - # of new alerts that started firing for that group. - group_interval: 5m - - # If an alert has successfully been sent, wait 'repeat_interval' to - # resend them. - repeat_interval: 3h - - # A default receiver - receiver: default-receiver - - # All the above attributes are inherited by all child routes and can - # overwritten on each. - - # The child route trees. - routes: - # This routes performs a regular expression match on alert labels to - # catch alerts that are related to a list of services. - # - match_re: - # service: ^(foo1|foo2|baz)$ - # receiver: team-X-mails - # # The service has a sub-route for critical alerts, any alerts - # # that do not match, i.e. severity != critical, fall-back to the - # # parent node and are sent to 'team-X-mails' - # routes: - # - match: - # severity: critical - # receiver: team-X-pager - # - match: - # severity: critical - # receiver: critical_alert - - # - match: - # severity: warning - # receiver: slack_prometheus - - # Inhibition rules allow to mute a set of alerts given that another alert is - # firing. - # We use this to mute any warning-level notifications if the same alert is - # already critical. - inhibit_rules: - - source_match: - severity: 'critical' - target_match: - severity: 'warning' - # Apply inhibition if the alertname is the same. - equal: ['cluster', 'service'] - - - receivers: - - name: default-receiver - # # receivers for critical alerts. For example Sends to pager duty _and_ slack - # - name: critical_alert - # pagerduty_configs: - # - send_resolved: true - # service_key: '' - - # slack_configs: - # - send_resolved: true - # api_url: '' - # channel: '#' - # text: '{{ template "slack.default.text" . }}' - # title: "{{ range .Alerts }}{{ .Annotations.summary }}\n{{ end }}" - - # # send to a slack channel. This is being used by the warning severity - # - name: 'slack_prometheus' - # slack_configs: - # - send_resolved: true - # api_url: '' - # channel: '#' - # title: "{{ range .Alerts }}{{ .Annotations.summary }}\n{{ end }}" - # text: "{{ range .Alerts }}{{ .Annotations.description }}\n{{ end }}" diff --git a/examples/prometheus/02-prometheus-alertrules-configmap.yaml b/examples/prometheus/02-prometheus-alertrules-configmap.yaml deleted file mode 100644 index 7052983ff4d..00000000000 --- a/examples/prometheus/02-prometheus-alertrules-configmap.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: prometheus-alert-rules - namespace: projectcontour-monitoring -data: - alert.rules: |- - groups: - # This alert can be enabled to test the Alerting pipeline. - - name: allrules - rules: - - alert: DeadMansSwitch - expr: vector(1) - labels: - severity: deadman - annotations: - description: This is a Dead Man's Switch alert meant to ensure that the Alerting pipeline is functional. diff --git a/examples/prometheus/02-prometheus-configmap.yaml b/examples/prometheus/02-prometheus-configmap.yaml deleted file mode 100644 index e4cb7a0762a..00000000000 --- a/examples/prometheus/02-prometheus-configmap.yaml +++ /dev/null @@ -1,329 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: prometheus - namespace: projectcontour-monitoring -data: - prometheus.yml: |- - # A scrape configuration for running Prometheus on a Kubernetes cluster. - # This uses separate scrape configs for cluster components (i.e. API server, node) - # and services to allow each to use different authentication configs. - # - # Kubernetes labels will be added as Prometheus labels on metrics via the - # `labelmap` relabeling action. - # - # If you are using Kubernetes 1.7.2 or earlier, please take note of the comments - # for the kubernetes-cadvisor job; you will need to edit or remove this job. - - rule_files: - - '/etc/prometheus-rules/*.rules' - - # Scrape config for API servers. - # - # Kubernetes exposes API servers as endpoints to the default/kubernetes - # service so this uses `endpoints` role and uses relabelling to only keep - # the endpoints associated with the default/kubernetes service using the - # default named port `https`. This works for single API server deployments as - # well as HA API server deployments. - scrape_configs: - - job_name: 'kubernetes-apiservers' - scrape_interval: 30s - - kubernetes_sd_configs: - - role: endpoints - - # Default to scraping over https. If required, just disable this or change to - # `http`. - scheme: https - - # This TLS & bearer token file config is used to connect to the actual scrape - # endpoints for cluster components. This is separate to discovery auth - # configuration because discovery & scraping are two separate concerns in - # Prometheus. The discovery auth config is automatic if Prometheus runs inside - # the cluster. Otherwise, more config options have to be provided within the - # . - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - # If your node certificates are self-signed or use a different CA to the - # master CA, then disable certificate verification below. Note that - # certificate verification is an integral part of a secure infrastructure - # so this should only be disabled in a controlled environment. You can - # disable certificate verification by uncommenting the line below. - # - # insecure_skip_verify: true - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - - # Keep only the default/kubernetes service endpoints for the https port. This - # will add targets for each API server which Kubernetes adds an endpoint to - # the default/kubernetes service. - relabel_configs: - - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] - action: keep - regex: default;kubernetes;https - - # Scrape config for nodes (kubelet). - # - # Rather than connecting directly to the node, the scrape is proxied though the - # Kubernetes apiserver. This means it will work if Prometheus is running out of - # cluster, or can't connect to nodes for some other reason (e.g. because of - # firewalling). - - job_name: 'kubernetes-nodes' - scrape_interval: 30s - - # Default to scraping over https. If required, just disable this or change to - # `http`. - scheme: https - - # This TLS & bearer token file config is used to connect to the actual scrape - # endpoints for cluster components. This is separate to discovery auth - # configuration because discovery & scraping are two separate concerns in - # Prometheus. The discovery auth config is automatic if Prometheus runs inside - # the cluster. Otherwise, more config options have to be provided within the - # . - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - - kubernetes_sd_configs: - - role: node - - relabel_configs: - - action: labelmap - regex: __meta_kubernetes_node_label_(.+) - - target_label: __address__ - replacement: kubernetes.default.svc:443 - - source_labels: [__meta_kubernetes_node_name] - regex: (.+) - target_label: __metrics_path__ - replacement: /api/v1/nodes/${1}/proxy/metrics - - # Scrape config for Kubelet cAdvisor. - # - # This is required for Kubernetes 1.7.3 and later, where cAdvisor metrics - # (those whose names begin with 'container_') have been removed from the - # Kubelet metrics endpoint. This job scrapes the cAdvisor endpoint to - # retrieve those metrics. - # - # In Kubernetes 1.7.0-1.7.2, these metrics are only exposed on the cAdvisor - # HTTP endpoint; use "replacement: /api/v1/nodes/${1}:4194/proxy/metrics" - # in that case (and ensure cAdvisor's HTTP server hasn't been disabled with - # the --cadvisor-port=0 Kubelet flag). - # - # This job is not necessary and should be removed in Kubernetes 1.6 and - # earlier versions, or it will cause the metrics to be scraped twice. - - job_name: 'kubernetes-cadvisor' - scrape_interval: 30s - - # Default to scraping over https. If required, just disable this or change to - # `http`. - scheme: https - - # This TLS & bearer token file config is used to connect to the actual scrape - # endpoints for cluster components. This is separate to discovery auth - # configuration because discovery & scraping are two separate concerns in - # Prometheus. The discovery auth config is automatic if Prometheus runs inside - # the cluster. Otherwise, more config options have to be provided within the - # . - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - - kubernetes_sd_configs: - - role: node - - relabel_configs: - - action: labelmap - regex: __meta_kubernetes_node_label_(.+) - - target_label: __address__ - replacement: kubernetes.default.svc:443 - - source_labels: [__meta_kubernetes_node_name] - regex: (.+) - target_label: __metrics_path__ - replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor - - # Scrape config for service endpoints. - # - # The relabeling allows the actual service scrape endpoint to be configured - # via the following annotations: - # - # * `prometheus.io/scrape`: Only scrape services that have a value of `true` - # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need - # to set this to `https` & most likely set the `tls_config` of the scrape config. - # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. - # * `prometheus.io/port`: If the metrics are exposed on a different port to the - # service then set this appropriately. - - job_name: 'kubernetes-service-endpoints' - scrape_interval: 30s - - kubernetes_sd_configs: - - role: endpoints - - relabel_configs: - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] - action: keep - regex: true - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] - action: replace - target_label: __scheme__ - regex: (https?) - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] - action: replace - target_label: __metrics_path__ - regex: (.+) - - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] - action: replace - target_label: __address__ - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - - action: labelmap - regex: __meta_kubernetes_service_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - action: replace - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_service_name] - action: replace - target_label: kubernetes_name - - # Example scrape config for probing services via the Blackbox Exporter. - # - # The relabeling allows the actual service scrape endpoint to be configured - # via the following annotations: - # - # * `prometheus.io/probe`: Only probe services that have a value of `true` - - job_name: 'kubernetes-services' - scrape_interval: 30s - - metrics_path: /probe - params: - module: [http_2xx] - - kubernetes_sd_configs: - - role: service - - relabel_configs: - - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] - action: keep - regex: true - - source_labels: [__address__] - target_label: __param_target - - target_label: __address__ - replacement: blackbox-exporter.example.com:9115 - - source_labels: [__param_target] - target_label: instance - - action: labelmap - regex: __meta_kubernetes_service_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_service_name] - target_label: kubernetes_name - - # Example scrape config for probing ingresses via the Blackbox Exporter. - # - # The relabeling allows the actual ingress scrape endpoint to be configured - # via the following annotations: - # - # * `prometheus.io/probe`: Only probe services that have a value of `true` - - job_name: 'kubernetes-ingresses' - scrape_interval: 30s - - metrics_path: /probe - params: - module: [http_2xx] - - kubernetes_sd_configs: - - role: ingress - - relabel_configs: - - source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe] - action: keep - regex: true - - source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path] - regex: (.+);(.+);(.+) - replacement: ${1}://${2}${3} - target_label: __param_target - - target_label: __address__ - replacement: blackbox-exporter.example.com:9115 - - source_labels: [__param_target] - target_label: instance - - action: labelmap - regex: __meta_kubernetes_ingress_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_ingress_name] - target_label: kubernetes_name - - # Example scrape config for pods - # - # The relabeling allows the actual pod scrape endpoint to be configured via the - # following annotations: - # - # * `prometheus.io/scrape`: Only scrape pods that have a value of `true` - # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. - # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the - # pod's declared ports (default is a port-free target if none are declared). - - job_name: 'kubernetes-pods' - scrape_interval: 30s - - kubernetes_sd_configs: - - role: pod - - relabel_configs: - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] - action: keep - regex: true - - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] - action: replace - target_label: __metrics_path__ - regex: (.+) - - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] - action: replace - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - target_label: __address__ - - action: labelmap - regex: __meta_kubernetes_pod_label_(.+) - - source_labels: [__meta_kubernetes_namespace] - action: replace - target_label: kubernetes_namespace - - source_labels: [__meta_kubernetes_pod_name] - action: replace - target_label: kubernetes_pod_name - metric_relabel_configs: - - source_labels: [envoy_cluster_name] - regex: '(.+?)_(.+?)_(.*)' - action: replace - target_label: namespace - replacement: '$1' - - source_labels: [envoy_cluster_name] - regex: '(.+?)_(.+?)_(.*)' - action: replace - target_label: service - replacement: '$2' - - source_labels: [envoy_cluster_name] - regex: '(.+?)_(.+?)_(.*)' - action: replace - target_label: port - replacement: '$3' - - alerting: - alertmanagers: - # Discover alert manager instances using K8s service discovery - - kubernetes_sd_configs: - - role: pod - scheme: http - tls_config: - ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token - relabel_configs: - - source_labels: [__meta_kubernetes_namespace] - regex: projectcontour-monitoring - action: keep - - source_labels: [__meta_kubernetes_pod_label_app] - regex: prometheus - action: keep - - source_labels: [__meta_kubernetes_pod_label_component] - regex: alertmanager - action: keep - - source_labels: [__meta_kubernetes_pod_container_port_number] - regex: - action: drop diff --git a/examples/prometheus/03-prometheus-alertmanager-deployment.yaml b/examples/prometheus/03-prometheus-alertmanager-deployment.yaml deleted file mode 100644 index db9c8d9ab82..00000000000 --- a/examples/prometheus/03-prometheus-alertmanager-deployment.yaml +++ /dev/null @@ -1,86 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app: prometheus - component: alertmanager - namespace: projectcontour-monitoring - name: prometheus-alertmanager ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: prometheus - component: alertmanager - name: prometheus-alertmanager - namespace: projectcontour-monitoring -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: 9093 - selector: - app: prometheus - component: alertmanager - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: prometheus - component: alertmanager - name: prometheus-alertmanager - namespace: projectcontour-monitoring -spec: - selector: - matchLabels: - app: prometheus - component: alertmanager - replicas: 1 - template: - metadata: - labels: - app: prometheus - component: alertmanager - spec: - serviceAccountName: prometheus-alertmanager - containers: - - name: prometheus-alertmanager - image: prom/alertmanager:v0.13.0 - imagePullPolicy: Always - args: - - --config.file=/etc/config/alertmanager.yml - - --storage.path=/data - - --web.external-url=/ - ports: - - containerPort: 9093 - readinessProbe: - httpGet: - path: /#/status - port: 9093 - initialDelaySeconds: 30 - timeoutSeconds: 30 - volumeMounts: - - name: config-volume - mountPath: /etc/config - - name: storage-volume - mountPath: /data - - name: prometheus-alertmanager-configmap-reload - image: jimmidyson/configmap-reload:v0.1 - imagePullPolicy: Always - args: - - --volume-dir=/etc/config - - --webhook-url=http://localhost:9093/-/reload - volumeMounts: - - name: config-volume - mountPath: /etc/config - readOnly: true - volumes: - - name: config-volume - configMap: - name: prometheus-alertmanager - - name: storage-volume - emptyDir: {} diff --git a/examples/prometheus/03-prometheus-deployment.yaml b/examples/prometheus/03-prometheus-deployment.yaml deleted file mode 100644 index c794d058889..00000000000 --- a/examples/prometheus/03-prometheus-deployment.yaml +++ /dev/null @@ -1,125 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: prometheus -rules: -- apiGroups: [""] - resources: - - nodes - - nodes/proxy - - services - - endpoints - - pods - verbs: ["get", "list", "watch"] -- apiGroups: - - extensions - resources: - - ingresses - verbs: ["get", "list", "watch"] -- nonResourceURLs: ["/metrics"] - verbs: ["get"] ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: prometheus - namespace: projectcontour-monitoring ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: prometheus -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: prometheus -subjects: -- kind: ServiceAccount - name: prometheus - namespace: projectcontour-monitoring ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - prometheus.io/scrape: 'true' - name: prometheus - namespace: projectcontour-monitoring -spec: - ports: - - protocol: TCP - name: prometheus - port: 9090 - selector: - app: prometheus - component: server ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: prometheus - namespace: projectcontour-monitoring - labels: - app: prometheus - component: server -spec: - replicas: 1 - selector: - matchLabels: - app: prometheus - component: server - template: - metadata: - name: prometheus - labels: - app: prometheus - component: server - spec: - serviceAccountName: prometheus - containers: - - name: prometheus - image: prom/prometheus:v2.2.1 - imagePullPolicy: Always - args: - - '--storage.tsdb.retention=24h' - - '--config.file=/etc/prometheus/prometheus.yml' - ports: - - containerPort: 9090 - volumeMounts: - - name: config-volume - mountPath: /etc/prometheus - - name: config-volume-alert-rules - mountPath: /etc/prometheus-rules - - name: cert-file - mountPath: /etc/ssl/etcd.pem - - name: key-file - mountPath: /etc/ssl/etcd-key.pem - - # blackbox exporter - # - name: blackbox - # image: quay.io/prometheus/blackbox-exporter:v0.11.0 - # args: - # - --config.file=/config/blackbox.yml - # ports: - # - containerPort: 9115 - # volumeMounts: - # - name: blackbox-config - # mountPath: /config - # black box exporter - # - name: blackbox-config - # configMap: - # name: prometheus-blackbox - - volumes: - - name: config-volume - configMap: - name: prometheus - - name: cert-file - hostPath: - path: /etc/kubernetes/ssl/etcd.pem - - name: key-file - hostPath: - path: /etc/kubernetes/ssl/etcd-key.pem - - name: config-volume-alert-rules - configMap: - name: prometheus-alert-rules diff --git a/examples/prometheus/03-prometheus-node-exporter.yaml b/examples/prometheus/03-prometheus-node-exporter.yaml deleted file mode 100644 index 26253689a7e..00000000000 --- a/examples/prometheus/03-prometheus-node-exporter.yaml +++ /dev/null @@ -1,71 +0,0 @@ ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - labels: - app: prometheus - component: node-exporter - name: prometheus-node-exporter - namespace: projectcontour-monitoring -spec: - selector: - matchLabels: - app: prometheus - component: node-exporter - updateStrategy: - type: OnDelete - template: - metadata: - labels: - app: prometheus - component: node-exporter - spec: - containers: - - name: prometheus-node-exporter - image: prom/node-exporter:v0.15.2 - imagePullPolicy: Always - args: - - --path.procfs=/host/proc - - --path.sysfs=/host/sys - ports: - - name: metrics - containerPort: 9100 - hostPort: 9100 - volumeMounts: - - name: proc - mountPath: /host/proc - readOnly: true - - name: sys - mountPath: /host/sys - readOnly: true - hostNetwork: true - hostPID: true - volumes: - - name: proc - hostPath: - path: /proc - - name: sys - hostPath: - path: /sys ---- -apiVersion: v1 -kind: Service -metadata: - name: prometheus-node-exporter - namespace: projectcontour-monitoring - annotations: - prometheus.io/scrape: "true" - labels: - app: prometheus - component: node-exporter -spec: - type: ClusterIP - clusterIP: None - ports: - - name: metrics - port: 9100 - protocol: TCP - targetPort: 9100 - selector: - app: prometheus - component: node-exporter diff --git a/examples/prometheus/httpproxy.yaml b/examples/prometheus/httpproxy.yaml new file mode 100644 index 00000000000..a5a37cd8e86 --- /dev/null +++ b/examples/prometheus/httpproxy.yaml @@ -0,0 +1,14 @@ +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: prometheus + namespace: monitoring +spec: + virtualhost: + fqdn: prometheus-example.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: prometheus-k8s + port: 9090 diff --git a/examples/prometheus/podmonitors.yaml b/examples/prometheus/podmonitors.yaml new file mode 100644 index 00000000000..9535f0bf7a8 --- /dev/null +++ b/examples/prometheus/podmonitors.yaml @@ -0,0 +1,31 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: contour-pods + namespace: monitoring +spec: + selector: + matchLabels: + app: contour + namespaceSelector: + matchNames: + - projectcontour + podMetricsEndpoints: + - port: metrics + path: /metrics +--- +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: envoy-pods + namespace: monitoring +spec: + selector: + matchLabels: + app: envoy + namespaceSelector: + matchNames: + - projectcontour + podMetricsEndpoints: + - port: metrics + path: /stats/prometheus diff --git a/examples/prometheus/rbac.yaml b/examples/prometheus/rbac.yaml new file mode 100644 index 00000000000..32d5eeef7bd --- /dev/null +++ b/examples/prometheus/rbac.yaml @@ -0,0 +1,26 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: prometheus + namespace: projectcontour +rules: +- apiGroups: [""] + resources: ["pods", "services", "endpoints"] + verbs: ["get", "list", "watch"] +- apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: prometheus + namespace: projectcontour +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: prometheus diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index c5fe223017e..e389f1820bc 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -223,7 +223,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourconfigurations.projectcontour.io spec: preserveUnknownFields: false @@ -340,6 +340,12 @@ spec: defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -820,9 +826,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -1092,6 +1098,8 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -1114,6 +1122,9 @@ spec: the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -1207,10 +1218,14 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -1363,6 +1378,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -1493,12 +1510,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 @@ -1580,7 +1592,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourdeployments.projectcontour.io spec: preserveUnknownFields: false @@ -1645,9 +1657,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: @@ -1814,6 +1823,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 @@ -1896,12 +1911,8 @@ spec: use to replace existing DaemonSet pods with new pods. 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: @@ -1972,9 +1983,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: @@ -2034,6 +2042,8 @@ spec: to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). type: string name: description: This must match the Name of a Volume. @@ -2043,6 +2053,21 @@ spec: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. type: boolean + recursiveReadOnly: + description: |- + 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 + field is set to Enabled, the mount is made recursively read-only if it is + 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: description: |- Path within the volume from which the container's volume should be mounted. @@ -2078,7 +2103,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: |- @@ -2118,6 +2142,7 @@ spec: 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. @@ -2131,6 +2156,7 @@ spec: to shared' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -2170,6 +2196,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic path: description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' @@ -2191,10 +2218,13 @@ spec: More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2230,10 +2260,13 @@ spec: to OpenStack. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2298,11 +2331,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the ConfigMap @@ -2335,10 +2372,13 @@ spec: secret object contains more than one secret, all secret references are passed. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2382,8 +2422,8 @@ spec: properties: fieldRef: description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' + pod: only annotations, labels, name, namespace + and uid are supported.' properties: apiVersion: description: Version of the schema the FieldPath @@ -2442,6 +2482,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object emptyDir: description: |- @@ -2533,6 +2574,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -2677,11 +2719,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2709,8 +2753,8 @@ spec: If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be 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/persistent-volumes#volumeattributesclass - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). type: string volumeMode: description: |- @@ -2736,7 +2780,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 lun number' @@ -2753,6 +2796,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic wwids: description: |- wwids Optional: FC volume world wide identifiers (wwids) @@ -2760,6 +2804,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object flexVolume: description: |- @@ -2796,10 +2841,13 @@ spec: scripts. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2833,7 +2881,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: |- @@ -2914,9 +2961,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: |- @@ -2933,6 +2977,39 @@ 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 @@ -2953,7 +3030,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: |- @@ -2965,6 +3041,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -2980,6 +3057,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic readOnly: description: |- readOnly here will force the ReadOnly setting in VolumeMounts. @@ -2990,10 +3068,13 @@ spec: target and initiator authentication properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3112,10 +3193,13 @@ 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: |- @@ -3164,11 +3248,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3247,11 +3333,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the @@ -3274,7 +3364,7 @@ spec: fieldRef: description: 'Required: Selects a field of the pod: only annotations, labels, - name and namespace are supported.' + name, namespace and uid are supported.' properties: apiVersion: description: Version of the schema @@ -3338,6 +3428,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object secret: description: secret information about the secret @@ -3381,11 +3472,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional field specify whether @@ -3424,6 +3519,7 @@ spec: type: object type: object type: array + x-kubernetes-list-type: atomic type: object quobyte: description: quobyte represents a Quobyte mount on the host @@ -3474,7 +3570,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: |- @@ -3482,6 +3577,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. @@ -3494,7 +3590,9 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -3514,14 +3612,18 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -3536,6 +3638,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -3561,10 +3664,13 @@ spec: sensitive information. If this is not provided, Login operation will fail. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3573,6 +3679,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: |- storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. @@ -3649,6 +3756,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic optional: description: optional field specify whether the Secret or its keys must be defined @@ -3680,10 +3788,13 @@ spec: credentials. If not specified, default values will be attempted. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3897,6 +4008,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 @@ -4025,6 +4142,12 @@ spec: Service; defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -4505,9 +4628,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -4778,6 +4901,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -4800,6 +4925,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -4893,10 +5021,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -5050,6 +5182,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -5062,16 +5196,8 @@ spec: description: Conditions describe the current conditions of the ContourDeployment resource. 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: |- @@ -5112,12 +5238,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 @@ -5143,7 +5264,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: extensionservices.projectcontour.io spec: preserveUnknownFields: false @@ -5188,6 +5309,39 @@ spec: description: ExtensionServiceSpec defines the desired state of an ExtensionService resource. properties: + circuitBreakerPolicy: + description: |- + CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. + If defined this overrides the global circuit breaker budget. + properties: + maxConnections: + description: The maximum number of connections that a single Envoy + instance allows to the Kubernetes Service; defaults to 1024. + format: int32 + type: integer + maxPendingRequests: + description: The maximum number of pending requests that a single + Envoy instance allows to the Kubernetes Service; defaults to + 1024. + format: int32 + type: integer + maxRequests: + description: The maximum parallel requests a single Envoy instance + allows to the Kubernetes Service; defaults to 1024 + format: int32 + type: integer + maxRetries: + description: The maximum number of parallel retries a single Envoy + instance allows to the Kubernetes Service; defaults to 3. + format: int32 + type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer + type: object loadBalancerPolicy: description: |- The policy for load balancing GRPC service requests. Note that the @@ -5225,6 +5379,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -5239,6 +5395,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -5506,12 +5664,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 @@ -5591,7 +5744,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: httpproxies.projectcontour.io spec: preserveUnknownFields: false @@ -6283,6 +6436,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6297,6 +6452,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -6397,6 +6554,8 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -6420,6 +6579,9 @@ spec: the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -6513,10 +6675,14 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -7161,6 +7327,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -7175,6 +7343,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -7841,6 +8011,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -7863,6 +8035,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -7956,10 +8131,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -8298,12 +8477,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 @@ -8422,8 +8596,6 @@ spec: CamelCase names - cloud provider specific error values must have names that comply with the format foo.example.com/CamelCase. - --- - 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 @@ -8433,12 +8605,12 @@ spec: format: int32 type: integer protocol: - default: TCP description: |- Protocol is the protocol of the service port of which status is recorded here The supported values are: "TCP", "UDP", "SCTP" type: string required: + - error - port - protocol type: object @@ -8446,6 +8618,7 @@ spec: x-kubernetes-list-type: atomic type: object type: array + x-kubernetes-list-type: atomic type: object type: object required: @@ -8461,7 +8634,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: tlscertificatedelegations.projectcontour.io spec: preserveUnknownFields: false @@ -8662,12 +8835,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 @@ -9031,9 +9199,6 @@ spec: app: contour template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8000" labels: app: contour spec: @@ -9135,10 +9300,6 @@ spec: app: envoy template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8002" - prometheus.io/path: "/stats/prometheus" labels: app: envoy spec: @@ -9178,7 +9339,7 @@ spec: - --log-level info command: - envoy - image: docker.io/envoyproxy/envoy:v1.29.2 + image: docker.io/envoyproxy/envoy:v1.32.0 imagePullPolicy: IfNotPresent name: envoy env: @@ -9201,6 +9362,10 @@ spec: hostPort: 443 name: https protocol: TCP + - containerPort: 8002 + hostPort: 8002 + name: metrics + protocol: TCP readinessProbe: httpGet: path: /ready diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 396d8c87dc7..bddb47171e8 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -14,7 +14,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourconfigurations.projectcontour.io spec: preserveUnknownFields: false @@ -131,6 +131,12 @@ spec: defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -611,9 +617,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -883,6 +889,8 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -905,6 +913,9 @@ spec: the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -998,10 +1009,14 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -1154,6 +1169,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -1284,12 +1301,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 @@ -1371,7 +1383,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourdeployments.projectcontour.io spec: preserveUnknownFields: false @@ -1436,9 +1448,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: @@ -1605,6 +1614,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 @@ -1687,12 +1702,8 @@ spec: use to replace existing DaemonSet pods with new pods. 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: @@ -1763,9 +1774,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: @@ -1825,6 +1833,8 @@ spec: to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). type: string name: description: This must match the Name of a Volume. @@ -1834,6 +1844,21 @@ spec: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. type: boolean + recursiveReadOnly: + description: |- + 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 + field is set to Enabled, the mount is made recursively read-only if it is + 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: description: |- Path within the volume from which the container's volume should be mounted. @@ -1869,7 +1894,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: |- @@ -1909,6 +1933,7 @@ spec: 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. @@ -1922,6 +1947,7 @@ spec: to shared' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -1961,6 +1987,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic path: description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' @@ -1982,10 +2009,13 @@ spec: More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2021,10 +2051,13 @@ spec: to OpenStack. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2089,11 +2122,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the ConfigMap @@ -2126,10 +2163,13 @@ spec: secret object contains more than one secret, all secret references are passed. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2173,8 +2213,8 @@ spec: properties: fieldRef: description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' + pod: only annotations, labels, name, namespace + and uid are supported.' properties: apiVersion: description: Version of the schema the FieldPath @@ -2233,6 +2273,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object emptyDir: description: |- @@ -2324,6 +2365,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -2468,11 +2510,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2500,8 +2544,8 @@ spec: If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be 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/persistent-volumes#volumeattributesclass - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). type: string volumeMode: description: |- @@ -2527,7 +2571,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 lun number' @@ -2544,6 +2587,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic wwids: description: |- wwids Optional: FC volume world wide identifiers (wwids) @@ -2551,6 +2595,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object flexVolume: description: |- @@ -2587,10 +2632,13 @@ spec: scripts. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2624,7 +2672,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: |- @@ -2705,9 +2752,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: |- @@ -2724,6 +2768,39 @@ 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 @@ -2744,7 +2821,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: |- @@ -2756,6 +2832,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -2771,6 +2848,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic readOnly: description: |- readOnly here will force the ReadOnly setting in VolumeMounts. @@ -2781,10 +2859,13 @@ spec: target and initiator authentication properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2903,10 +2984,13 @@ 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: |- @@ -2955,11 +3039,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3038,11 +3124,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the @@ -3065,7 +3155,7 @@ spec: fieldRef: description: 'Required: Selects a field of the pod: only annotations, labels, - name and namespace are supported.' + name, namespace and uid are supported.' properties: apiVersion: description: Version of the schema @@ -3129,6 +3219,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object secret: description: secret information about the secret @@ -3172,11 +3263,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional field specify whether @@ -3215,6 +3310,7 @@ spec: type: object type: object type: array + x-kubernetes-list-type: atomic type: object quobyte: description: quobyte represents a Quobyte mount on the host @@ -3265,7 +3361,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: |- @@ -3273,6 +3368,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. @@ -3285,7 +3381,9 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -3305,14 +3403,18 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -3327,6 +3429,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -3352,10 +3455,13 @@ spec: sensitive information. If this is not provided, Login operation will fail. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3364,6 +3470,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: |- storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. @@ -3440,6 +3547,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic optional: description: optional field specify whether the Secret or its keys must be defined @@ -3471,10 +3579,13 @@ spec: credentials. If not specified, default values will be attempted. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3688,6 +3799,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 @@ -3816,6 +3933,12 @@ spec: Service; defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -4296,9 +4419,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -4569,6 +4692,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -4591,6 +4716,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -4684,10 +4812,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -4841,6 +4973,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -4853,16 +4987,8 @@ spec: description: Conditions describe the current conditions of the ContourDeployment resource. 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: |- @@ -4903,12 +5029,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 @@ -4934,7 +5055,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: extensionservices.projectcontour.io spec: preserveUnknownFields: false @@ -4979,6 +5100,39 @@ spec: description: ExtensionServiceSpec defines the desired state of an ExtensionService resource. properties: + circuitBreakerPolicy: + description: |- + CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. + If defined this overrides the global circuit breaker budget. + properties: + maxConnections: + description: The maximum number of connections that a single Envoy + instance allows to the Kubernetes Service; defaults to 1024. + format: int32 + type: integer + maxPendingRequests: + description: The maximum number of pending requests that a single + Envoy instance allows to the Kubernetes Service; defaults to + 1024. + format: int32 + type: integer + maxRequests: + description: The maximum parallel requests a single Envoy instance + allows to the Kubernetes Service; defaults to 1024 + format: int32 + type: integer + maxRetries: + description: The maximum number of parallel retries a single Envoy + instance allows to the Kubernetes Service; defaults to 3. + format: int32 + type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer + type: object loadBalancerPolicy: description: |- The policy for load balancing GRPC service requests. Note that the @@ -5016,6 +5170,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -5030,6 +5186,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -5297,12 +5455,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 @@ -5382,7 +5535,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: httpproxies.projectcontour.io spec: preserveUnknownFields: false @@ -6074,6 +6227,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6088,6 +6243,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -6188,6 +6345,8 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -6211,6 +6370,9 @@ spec: the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -6304,10 +6466,14 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -6952,6 +7118,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6966,6 +7134,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -7632,6 +7802,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -7654,6 +7826,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -7747,10 +7922,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -8089,12 +8268,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 @@ -8213,8 +8387,6 @@ spec: CamelCase names - cloud provider specific error values must have names that comply with the format foo.example.com/CamelCase. - --- - 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 @@ -8224,12 +8396,12 @@ spec: format: int32 type: integer protocol: - default: TCP description: |- Protocol is the protocol of the service port of which status is recorded here The supported values are: "TCP", "UDP", "SCTP" type: string required: + - error - port - protocol type: object @@ -8237,6 +8409,7 @@ spec: x-kubernetes-list-type: atomic type: object type: array + x-kubernetes-list-type: atomic type: object type: object required: @@ -8252,7 +8425,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: tlscertificatedelegations.projectcontour.io spec: preserveUnknownFields: false @@ -8453,12 +8626,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 @@ -8538,7 +8706,7 @@ spec: status: {} --- -# Copyright 2023 The Kubernetes Authors. +# Copyright 2024 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -8557,30 +8725,28 @@ spec: # --- # -# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendlbpolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - labels: - gateway.networking.k8s.io/policy: Direct - name: backendtlspolicies.gateway.networking.k8s.io + name: backendlbpolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: BackendTLSPolicy - listKind: BackendTLSPolicyList - plural: backendtlspolicies + kind: BackendLBPolicy + listKind: BackendLBPolicyList + plural: backendlbpolicies shortNames: - - btlspolicy - singular: backendtlspolicy + - blbpolicy + singular: backendlbpolicy scope: Namespaced versions: - additionalPrinterColumns: @@ -8590,332 +8756,356 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: BackendTLSPolicy provides a way to configure how a Gateway connects - to a Backend via TLS. + description: |- + BackendLBPolicy provides a way to define load balancing rules + for a backend. 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' + 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' + 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 BackendTLSPolicy. + description: Spec defines the desired state of BackendLBPolicy. properties: - targetRef: - description: "TargetRef identifies an API object to apply the policy - to. Only Services have Extended support. Implementations MAY support - additional objects, with Implementation Specific support. Note that - this config applies to the entire referenced resource by default, - but this default may change in the future to provide a more granular - application of the policy. \n Support: Extended for Kubernetes Service - \n Support: Implementation-specific for any other resource" + sessionPersistence: + description: |- + SessionPersistence defines and configures session persistence + for the backend. + + Support: Extended properties: - group: - description: Group is the group of the target resource. - 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 target resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + 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 - name: - description: Name is the name of the target resource. - maxLength: 253 - minLength: 1 + 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 - namespace: - description: Namespace is the namespace of the referent. When - unspecified, the local namespace is inferred. Even when policy - targets a resource in a different namespace, it MUST only apply - to traffic originating from the same namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 - sectionName: - description: "SectionName is the name of a section within the - target resource. When unspecified, this targetRef targets the - entire resource. In the following resources, SectionName is - interpreted as the following: \n * Gateway: Listener Name * - Service: Port Name \n 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." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + 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 - required: + 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)' + targetRefs: + description: |- + TargetRef identifies an API object to apply policy to. + Currently, Backends (i.e. Service, ServiceImport, or any + implementation-specific backendRef) are the only valid API + target references. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + 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 target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: - group - kind - name - type: object - tls: - description: TLS contains backend TLS policy configuration. - properties: - caCertRefs: - description: "CACertRefs contains one or more references to Kubernetes - objects that contain a PEM-encoded TLS CA certificate bundle, - which is used to validate a TLS handshake between the Gateway - and backend Pod. \n If CACertRefs is empty or unspecified, then - WellKnownCACerts must be specified. Only one of CACertRefs or - WellKnownCACerts may be specified, not both. If CACertRefs is - empty or unspecified, the configuration for WellKnownCACerts - MUST be honored instead. \n References to a resource in a different - namespace are invalid for the moment, although we will revisit - this in the future. \n A single CACertRef 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. \n Support: Core - An optional single - reference to a Kubernetes ConfigMap, with the CA certificate - in a key named `ca.crt`. \n Support: Implementation-specific - (More than one reference, or other kinds of resources)." - items: - description: "LocalObjectReference identifies an API object - within the namespace of the referrer. 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. \n 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." + x-kubernetes-list-type: map + required: + - targetRefs + type: object + status: + description: Status defines the current state of BackendLBPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + 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 + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + 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 + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + 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: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. 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. + 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: - description: Kind is kind of the referent. For example "HTTPRoute" - or "Service". + 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. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - maxItems: 8 - type: array - hostname: - description: "Hostname is used for two purposes in the connection - between Gateways and backends: \n 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. \n 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 - wellKnownCACerts: - description: "WellKnownCACerts specifies whether system CA certificates - may be used in the TLS handshake between the gateway and backend - pod. \n If WellKnownCACerts is unspecified or empty (\"\"), - then CACertRefs must be specified with at least one entry for - a valid configuration. Only one of CACertRefs or WellKnownCACerts - may be specified, not both. \n Support: Core for \"System\"" - enum: - - System - type: string - required: - - hostname - type: object - x-kubernetes-validations: - - message: must not contain both CACertRefs and WellKnownCACerts - rule: '!(has(self.caCertRefs) && size(self.caCertRefs) > 0 && has(self.wellKnownCACerts) - && self.wellKnownCACerts != "")' - - message: must specify either CACertRefs or WellKnownCACerts - rule: (has(self.caCertRefs) && size(self.caCertRefs) > 0 || has(self.wellKnownCACerts) - && self.wellKnownCACerts != "") - required: - - targetRef - - tls - type: object - status: - description: Status defines the current state of BackendTLSPolicy. - properties: - ancestors: - description: "Ancestors is a list of ancestor resources (usually Gateways) - that are associated with the policy, and the status of the policy - with respect to each ancestor. When this policy attaches to a parent, - the controller that manages the parent and the ancestors MUST add - an entry to this list when the controller first sees the policy - and SHOULD update the entry as appropriate when the relevant ancestor - is modified. \n 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. \n 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. \n 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. \n A maximum of 16 ancestors will be represented - in this list. An empty list means the Policy is not relevant for - any ancestors. \n 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 here. For example, if this list was full on - BackendTLSPolicy, no additional Gateways would be able to reference - the Service targeted by the BackendTLSPolicy." - items: - description: "PolicyAncestorStatus describes the status of a route - with respect to an associated Ancestor. \n 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 the GatewayClass. Almost always, in - this hierarchy, the Gateway will be the most useful object to - place Policy status on, so we recommend that implementations SHOULD - use Gateway as the PolicyAncestorStatus object unless the designers - have a _very_ good reason otherwise. \n 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. \n 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. \n 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. \n 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. \n 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: - ancestorRef: - description: AncestorRef corresponds with a ParentRef in the - spec that this PolicyAncestorStatus 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). \n - 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -8928,46 +9118,45 @@ spec: respect to the given Ancestor. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -8981,12 +9170,12 @@ 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. + --- + 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 @@ -9004,16 +9193,20 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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\/\-._~%!$&'()*+,;=:]+$ @@ -9042,264 +9235,583 @@ status: storedVersions: null --- # -# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - name: gatewayclasses.gateway.networking.k8s.io + labels: + gateway.networking.k8s.io/policy: Direct + name: backendtlspolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: GatewayClass - listKind: GatewayClassList - plural: gatewayclasses + kind: BackendTLSPolicy + listKind: BackendTLSPolicyList + plural: backendtlspolicies shortNames: - - gc - singular: gatewayclass - scope: Cluster + - btlspolicy + singular: backendtlspolicy + scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1 + name: v1alpha3 schema: openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n 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 propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n 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. \n GatewayClass is - a Cluster level resource." + description: |- + BackendTLSPolicy provides a way to configure how a Gateway + connects to a Backend via TLS. 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' + 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' + 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 GatewayClass. + description: Spec defines the desired state of BackendTLSPolicy. properties: - controllerName: - description: "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. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n 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. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" + targetRefs: + description: |- + TargetRefs identifies an API object to apply the policy to. + Only Services have Extended support. Implementations MAY support + additional objects, with Implementation Specific support. + Note that this config applies to the entire referenced resource + 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: |- + LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a + direct policy to. This should be used as part of Policy resources that can + target single resources. For more information on how this policy attachment + 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. + properties: + group: + description: Group is the group of the target resource. + 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 target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + sectionName: + description: |- + SectionName is the name of a section within the target resource. When + 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. + 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: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + validation: + description: Validation contains backend TLS validation configuration. properties: - group: - description: Group is the group of the referent. - 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. - 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. + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to Kubernetes objects that + 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: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + 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. + 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 + maxItems: 8 + type: array + hostname: + description: |- + 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. + + 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 - namespace: - description: Namespace is the namespace of the referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 + implementation does not support the WellKnownCACertificates field or the value + 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 type: string required: - - group - - kind - - name + - hostname type: object + x-kubernetes-validations: + - message: must not contain both CACertificateRefs and WellKnownCACertificates + rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs) + > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates + != "")' + - message: must specify either CACertificateRefs or WellKnownCACertificates + rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs) + > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates + != "") required: - - controllerName + - targetRefs + - validation type: object status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." + description: Status defines the current state of BackendTLSPolicy. properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + 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 + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + 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 + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + 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: - 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 + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus 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 + conditions: + 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}" + 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-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])$ + 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 required: - - lastTransitionTime - - message - - reason - - status - - type + - ancestorRef + - controllerName type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 + maxItems: 16 type: array - x-kubernetes-list-type: set + required: + - ancestors type: object required: - spec type: object served: true - storage: false + storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml +# +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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + versions: - additionalPrinterColumns: - jsonPath: .spec.controllerName name: Controller @@ -9314,32 +9826,42 @@ spec: name: Description priority: 1 type: string - name: v1beta1 + name: v1 schema: openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n 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 propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n 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. \n GatewayClass is - a Cluster level resource." + description: |- + 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 + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + 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: - 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' + 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' + 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 @@ -9347,10 +9869,15 @@ spec: description: Spec defines the desired state of GatewayClass. properties: controllerName: - description: "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. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n Support: Core" + description: |- + 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 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ @@ -9363,14 +9890,23 @@ spec: maxLength: 64 type: string parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n 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. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" + description: |- + ParametersRef is a reference to a resource that contains the configuration + 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. + + 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: description: Group is the group of the referent. @@ -9389,9 +9925,10 @@ spec: minLength: 1 type: string namespace: - description: Namespace is the namespace of the referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. + description: |- + Namespace is the namespace of the referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -9412,9 +9949,11 @@ spec: reason: Waiting status: Unknown type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." + description: |- + Status defines the current state of GatewayClass. + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. properties: conditions: default: @@ -9423,51 +9962,54 @@ spec: reason: Pending status: Unknown type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + description: |- + 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. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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. + 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. + 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. + 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_])?$ + 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. @@ -9477,11 +10019,12 @@ 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. + --- + 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 @@ -9498,30 +10041,13 @@ spec: - type x-kubernetes-list-type: map supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. type: string maxItems: 64 type: array @@ -9534,6 +10060,254 @@ spec: storage: true subresources: status: {} + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + 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 + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + 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: + 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 GatewayClass. + properties: + controllerName: + description: |- + 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 + 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 + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + 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. + + 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: + description: Group is the group of the referent. + 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. + 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 referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + 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: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + 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}" + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. + items: + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} status: acceptedNames: kind: "" @@ -9548,8 +10322,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: gateways.gateway.networking.k8s.io @@ -9582,18 +10356,24 @@ spec: name: v1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. 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' + 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' + 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 @@ -9601,20 +10381,28 @@ spec: description: Spec defines the desired state of Gateway. properties: addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n 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. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + 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. @@ -9641,9 +10429,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -9665,179 +10455,264 @@ spec: rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. maxLength: 253 minLength: 1 type: string infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + Support: Core + properties: annotations: 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. + 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: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" + 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 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. + 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: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" + 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. + + Support: Extended maxProperties: 8 type: object - type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n 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 \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n 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. \n For example, the following - Listener scenarios are distinct: \n 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 \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n 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. \n 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. \n 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. \n 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 `\"\"`. \n 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. \n 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\"`. \n 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\". \n 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 accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n 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 indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 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. \n 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. \n 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. - \n 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 to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" - items: - description: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. - properties: - allowedRoutes: + 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: + description: Group is the group of the referent. + 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. + 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 + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + 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 + "Listeners in a single Gateway" because implementations MAY merge configuration + 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 + "TLS" Protocol that all have unique Hostname values. + 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 + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + 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 + indicate in the Message which Listeners are conflicted, and which are + 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 + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + 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: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: default: namespaces: from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n 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: \n * 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 a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - 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, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + 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 + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + 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, + support for that Route rule should be dropped to ensure consistency. For + 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: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n 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. \n Support: Core" + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + 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 of a Route resource. @@ -9862,173 +10737,200 @@ spec: namespaces: default: from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" + description: |- + 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: default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * 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. \n Support: - Core" + description: |- + 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 - Selector - Same type: string selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" + description: |- + Selector must be specified when From is set to "Selector". In that case, + 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: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic type: object type: object hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * 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 protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n 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. \n 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`. \n Support: Core" + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + 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 + protocol layers as described above. If an implementation does not + 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 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n Support: Core" + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + Support: Core format: int32 maximum: 65535 minimum: 1 type: integer protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n Support: Core" + 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]+$ type: string tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" + description: |- + TLS is the TLS configuration for the Listener. This field is required if + 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: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n 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. - \n 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. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + 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. - \n 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. \n 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." + 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. 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. + 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 @@ -10046,14 +10948,16 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the referenced - object. When unspecified, the local namespace is - inferred. \n 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. - \n Support: Core" + 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])?$ @@ -10063,49 +10967,143 @@ spec: type: object maxItems: 64 type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + 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: |- + 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 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 + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + 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. + 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 "ConfigMap" 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 + 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: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object mode: default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" + description: |- + 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 + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + Support: Core enum: - Terminate - Passthrough type: string 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. + 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. \n 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. \n Support: Implementation-specific" + 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 type: object x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType - is Terminate + - message: certificateRefs or options must be specified when + mode is Terminate rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' + > 0 || size(self.options) > 0 : true' required: - name - port @@ -10118,13 +11116,13 @@ spec: - name x-kubernetes-list-type: map x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - message: tls must not be specified for protocols ['HTTP', 'TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' - message: hostname must not be specified for protocols ['TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) || l.hostname == '''') : true)' @@ -10155,12 +11153,17 @@ spec: description: Status defines the current state of Gateway. properties: addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * 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) \n " + description: |+ + 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. @@ -10187,9 +11190,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -10215,50 +11220,57 @@ spec: reason: Pending status: Unknown type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n 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. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" + 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. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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. + 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. + 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. + 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. + 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 @@ -10272,11 +11284,12 @@ 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. + --- + 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 @@ -10299,23 +11312,24 @@ spec: description: ListenerStatus is the status associated with a Listener. properties: attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n 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 a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." + description: |- + 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 + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + 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 type: integer conditions: @@ -10323,46 +11337,45 @@ spec: listener. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -10376,12 +11389,12 @@ 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. + --- + 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 @@ -10405,15 +11418,16 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n 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 and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." + description: |- + SupportedKinds is the list indicating the Kinds supported by this + 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 + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. items: description: RouteGroupKind indicates the group and kind of a Route resource. @@ -10451,7 +11465,7 @@ spec: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: @@ -10470,18 +11484,24 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. 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' + 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' + 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 @@ -10489,20 +11509,28 @@ spec: description: Spec defines the desired state of Gateway. properties: addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n 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. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + 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. @@ -10529,9 +11557,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -10553,179 +11583,264 @@ spec: rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. maxLength: 253 minLength: 1 type: string infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + Support: Core + properties: annotations: 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. + 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: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" + 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 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. + 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: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" + 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. + + Support: Extended maxProperties: 8 type: object + 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: + description: Group is the group of the referent. + 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. + 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 type: object listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n 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 \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n 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. \n For example, the following - Listener scenarios are distinct: \n 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 \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n 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. \n 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. \n 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. \n 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 `\"\"`. \n 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. \n 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\"`. \n 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\". \n 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 accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n 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 indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 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. \n 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. \n 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. - \n 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 to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" + description: |- + Listeners associated with this Gateway. Listeners define + 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 + "Listeners in a single Gateway" because implementations MAY merge configuration + 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 + "TLS" Protocol that all have unique Hostname values. + 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 + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + 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 + indicate in the Message which Listeners are conflicted, and which are + 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 + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + 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: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. properties: allowedRoutes: default: namespaces: from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n 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: \n * 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 a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - 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, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + 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 + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + 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, + support for that Route rule should be dropped to ensure consistency. For + 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: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n 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. \n Support: Core" + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + 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 of a Route resource. @@ -10750,173 +11865,200 @@ spec: namespaces: default: from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" + description: |- + 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: default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * 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. \n Support: - Core" + description: |- + 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 - Selector - Same type: string selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" + description: |- + Selector must be specified when From is set to "Selector". In that case, + 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: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic type: object type: object hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * 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 protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n 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. \n 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`. \n Support: Core" + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + 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 + protocol layers as described above. If an implementation does not + 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 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n Support: Core" + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + Support: Core format: int32 maximum: 65535 minimum: 1 type: integer protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n Support: Core" + 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]+$ type: string tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" + description: |- + TLS is the TLS configuration for the Listener. This field is required if + 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: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n 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. - \n 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. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + 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. - \n 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. \n 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." + 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. 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. + 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 @@ -10934,14 +12076,16 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the referenced - object. When unspecified, the local namespace is - inferred. \n 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. - \n Support: Core" + 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])?$ @@ -10951,49 +12095,143 @@ spec: type: object maxItems: 64 type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + 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: |- + 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 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 + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + 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. + 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 "ConfigMap" 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 + 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: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object mode: default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" + description: |- + 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 + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + Support: Core enum: - Terminate - Passthrough type: string 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. + 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. \n 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. \n Support: Implementation-specific" + 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 type: object x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType - is Terminate + - message: certificateRefs or options must be specified when + mode is Terminate rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' + > 0 || size(self.options) > 0 : true' required: - name - port @@ -11006,13 +12244,13 @@ spec: - name x-kubernetes-list-type: map x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - message: tls must not be specified for protocols ['HTTP', 'TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' - message: hostname must not be specified for protocols ['TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) || l.hostname == '''') : true)' @@ -11043,12 +12281,17 @@ spec: description: Status defines the current state of Gateway. properties: addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * 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) \n " + description: |+ + 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. @@ -11075,9 +12318,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -11103,50 +12348,57 @@ spec: reason: Pending status: Unknown type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n 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. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" + 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. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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. + 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. + 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. + 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. + 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 @@ -11160,11 +12412,12 @@ 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. + --- + 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 @@ -11187,23 +12440,24 @@ spec: description: ListenerStatus is the status associated with a Listener. properties: attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n 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 a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." + description: |- + 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 + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + 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 type: integer conditions: @@ -11211,46 +12465,45 @@ spec: listener. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -11264,12 +12517,12 @@ 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. + --- + 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 @@ -11293,15 +12546,16 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n 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 and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." + description: |- + SupportedKinds is the list indicating the Kinds supported by this + 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 + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. items: description: RouteGroupKind indicates the group and kind of a Route resource. @@ -11339,7 +12593,7 @@ spec: - spec type: object served: true - storage: true + storage: false subresources: status: {} status: @@ -11356,8 +12610,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: grpcroutes.gateway.networking.k8s.io @@ -11379,40 +12633,52 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha2 + name: v1 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. \n 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. - \n 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. \n 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\". + 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." + 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' + 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' + 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 @@ -11420,56 +12686,73 @@ 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: \n 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. \n 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: - \n * 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`. + 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. - \n 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`. \n 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. \n 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. \n 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: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n The rejected Route MUST raise an 'Accepted' condition with a - status of 'False' in the corresponding RouteParentStatus. \n Support: - Core" + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -11477,165 +12760,2289 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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: 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -11671,82 +15078,99 @@ spec: 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). + 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. - \n See the GRPCBackendRef definition for the rules about what - makes a single GRPCBackendRef invalid. \n 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. \n 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. \n Support: Core for Kubernetes - Service \n Support: Implementation-specific for any other - resource \n Support for weight: Core" + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in GRPCRouteRule.)" + 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. + 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. \n Support: Implementation-specific \n - This filter can be used multiple times within - the same rule." + 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. + 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 @@ -11768,35 +15192,45 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -11817,44 +15251,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -11876,64 +15327,68 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -11944,29 +15399,27 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -11982,35 +15435,45 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -12031,44 +15494,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -12090,32 +15570,32 @@ spec: 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: \n - - 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. - \n - Extended: Filter types and their corresponding - configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - - 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. - \n Implementers are encouraged to define custom - implementation types to extend the core API with - implementation-specific behavior. \n 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. \n " + 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 @@ -12166,25 +15646,29 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -12195,43 +15679,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -12246,44 +15734,55 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. - \n Specifying the same filter multiple times is not supported - unless explicitly indicated in the filter. \n If an implementation - can not support a combination of filters, it must clearly + 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. \n Support: Core" + 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. + 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. \n Support: Implementation-specific \n This - filter can be used multiple times within the same rule." + 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. + 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 @@ -12305,32 +15804,44 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -12351,40 +15862,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -12406,60 +15937,68 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -12470,25 +16009,26 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -12505,32 +16045,44 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -12551,40 +16103,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -12606,29 +16178,32 @@ spec: 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: \n - 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. \n - Extended: Filter types and their - corresponding configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - 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. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n " + 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 @@ -12677,60 +16252,95 @@ spec: 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. \n For example, take the following matches configuration: - \n ``` matches: - method: service: foo.bar headers: values: - version: 2 - method: service: foo.bar.v2 ``` \n For a request - to match against this rule, it MUST satisfy EITHER of the - two conditions: \n - service of foo.bar AND contains the header - `version: 2` - service of foo.bar.v2 \n See the documentation - for GRPCRouteMatch on how to specify multiple match conditions - to be ANDed together. \n If no matches are specified, the - implementation MUST match every gRPC request. \n 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: \n * Characters in a matching non-wildcard hostname. * - Characters in a matching hostname. * Characters in a matching - service. * Characters in a matching method. * Header matches. - \n If ties still exist across multiple Routes, matching precedence - MUST be determined in order of the following criteria, continuing - on ties: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n 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." + 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. \n For example, the match - below will match a gRPC request only if its service is `foo` - AND it contains the `version: v1` header: \n ``` matches: - - method: type: Exact service: \"foo\" headers: - name: - \"version\" value \"v1\" \n ```" + 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. + 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. + 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. \n 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." + 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|~]+$ @@ -12759,31 +16369,35 @@ spec: - 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. + 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. - \n At least one of Service and Method MUST be a - non-empty string." + 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. - \n At least one of Service and Method MUST be a - non-empty string." + 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) \n Support: Implementation-specific - (Exact with method specified but no service specified) - \n Support: Implementation-specific (RegularExpression)" + 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 @@ -12807,6 +16421,94 @@ spec: 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 @@ -12815,81 +16517,88 @@ spec: 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -12903,12 +16612,12 @@ 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. + --- + 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 @@ -12926,131 +16635,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -13069,9 +16797,7 @@ spec: type: object type: object served: true - storage: true - subresources: - status: {} + storage: false status: acceptedNames: kind: "" @@ -13086,8 +16812,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: httproutes.gateway.networking.k8s.io @@ -13112,20 +16838,26 @@ spec: name: v1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -13133,57 +16865,76 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: - \n * 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`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + 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`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n 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`. \n 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. \n 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. \n 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: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -13191,165 +16942,204 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -13390,81 +17180,101 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n 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. - \n 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. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + 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 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. + + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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 should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + 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: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -13486,35 +17296,45 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -13535,44 +17355,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -13594,64 +17431,68 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -13662,29 +17503,27 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -13700,84 +17539,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -13803,95 +17638,111 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * 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 well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -13912,44 +17763,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -13971,37 +17839,39 @@ spec: 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: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n 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. \n + 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 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` 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. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -14011,79 +17881,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -14181,25 +18048,29 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -14210,43 +18081,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -14261,46 +18136,67 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n 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 + description: |- + 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 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. \n Support: Core" + 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: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -14322,32 +18218,44 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -14368,40 +18276,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -14423,60 +18351,68 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -14487,25 +18423,26 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -14522,77 +18459,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -14618,88 +18558,110 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * 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 - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -14720,40 +18682,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -14775,33 +18757,39 @@ spec: 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: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + 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 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` 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -14811,73 +18799,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -14970,86 +18961,116 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n 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: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n 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. \n 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." + description: |- + Matches define conditions used for matching the rule against incoming + 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: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + 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 action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + 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 + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n 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. - \n 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: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, 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: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". 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. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n 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 determine the supported dialect." + 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 + determine the supported dialect. enum: - Exact - RegularExpression @@ -15070,9 +19091,12 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + Support: Extended enum: - GET - HEAD @@ -15088,15 +19112,18 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + Support: Core (Exact, PathPrefix) + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -15155,48 +19182,53 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n 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. \n 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 match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + 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 + match against the first value of the param if the data plane supports it, + 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 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + 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 + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -15219,39 +19251,145 @@ spec: 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)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + Support: Extended + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway 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. \n 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. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n 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. - \n 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. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -15309,81 +19447,88 @@ spec: description: Status defines the current state of HTTPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -15397,12 +19542,12 @@ 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. + --- + 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 @@ -15420,131 +19565,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -15565,7 +19729,7 @@ spec: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: @@ -15578,20 +19742,26 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -15599,57 +19769,76 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: - \n * 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`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + 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`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n 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`. \n 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. \n 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. \n 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: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -15657,165 +19846,204 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -15856,81 +20084,101 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n 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. - \n 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. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + 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 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. + + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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 should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + 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: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -15952,35 +20200,45 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -16001,44 +20259,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -16060,64 +20335,68 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -16128,29 +20407,27 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -16166,84 +20443,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -16269,95 +20542,111 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * 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 well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -16378,44 +20667,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -16437,37 +20743,39 @@ spec: 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: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n 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. \n + 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 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` 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. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -16477,79 +20785,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -16647,25 +20952,29 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -16676,43 +20985,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -16727,46 +21040,67 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n 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 + description: |- + 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 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. \n Support: Core" + 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: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -16788,32 +21122,44 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -16834,40 +21180,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -16889,60 +21255,68 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -16953,25 +21327,26 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -16988,77 +21363,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -17084,88 +21462,110 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * 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 - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -17186,40 +21586,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -17241,33 +21661,39 @@ spec: 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: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + 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 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` 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -17277,73 +21703,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -17436,86 +21865,116 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n 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: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n 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. \n 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." + description: |- + Matches define conditions used for matching the rule against incoming + 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: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + 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 action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + 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 + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n 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. - \n 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: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, 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: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". 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. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n 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 determine the supported dialect." + 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 + determine the supported dialect. enum: - Exact - RegularExpression @@ -17536,9 +21995,12 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + Support: Extended enum: - GET - HEAD @@ -17554,15 +22016,18 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + Support: Core (Exact, PathPrefix) + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -17621,48 +22086,53 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n 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. \n 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 match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + 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 + match against the first value of the param if the data plane supports it, + 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 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + 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 + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -17685,39 +22155,145 @@ spec: 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)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + Support: Extended + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway 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. \n 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. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n 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. - \n 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. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -17775,81 +22351,88 @@ spec: description: Status defines the current state of HTTPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -17863,12 +22446,12 @@ 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. + --- + 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 @@ -17886,131 +22469,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -18031,7 +22633,7 @@ spec: - spec type: object served: true - storage: true + storage: false subresources: status: {} status: @@ -18048,8 +22650,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: referencegrants.gateway.networking.k8s.io @@ -18076,32 +22678,42 @@ spec: 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. \n 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. \n 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. \n 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." + 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' + 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' + 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 @@ -18109,35 +22721,52 @@ 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. \n Support: Core" + 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. \n Support: Core" + 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. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + 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. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -18151,35 +22780,44 @@ spec: 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. - \n Support: Core" + 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. + 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. \n Support: Core" + 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: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + 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. + 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 @@ -18205,28 +22843,38 @@ spec: name: v1beta1 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. \n 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. \n All cross-namespace references in Gateway API - (with the exception of cross-namespace Gateway-route attachment) require - a ReferenceGrant. \n 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." + 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. + + 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 + 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' + 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' + 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 @@ -18234,35 +22882,52 @@ 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. \n Support: Core" + 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. \n Support: Core" + 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. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + 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. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -18276,35 +22941,44 @@ spec: 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. - \n Support: Core" + 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. + 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. \n Support: Core" + 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: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + 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. + 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 @@ -18337,8 +23011,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tcproutes.gateway.networking.k8s.io @@ -18360,19 +23034,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: TCPRoute provides a way to route TCP requests. When combined - with a Gateway listener, it can be used to forward connections on the port - specified by the listener to a set of backends specified by the TCPRoute. + description: |- + TCPRoute provides a way to route TCP requests. When combined with a Gateway + listener, it can be used to forward connections on the port specified by the + listener to a set of backends specified by the TCPRoute. 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' + 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' + 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 @@ -18380,165 +23060,204 @@ spec: description: Spec defines the desired state of TCPRoute. properties: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -18577,62 +23296,78 @@ spec: description: TCPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Connection rejections must respect - weight; if an invalid backend is requested to have 80% of + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Connection rejections must + respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Extended" + + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -18643,43 +23378,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -18705,81 +23444,88 @@ spec: description: Status defines the current state of TCPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -18793,12 +23539,12 @@ 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. + --- + 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 @@ -18816,131 +23562,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -18978,8 +23743,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tlsroutes.gateway.networking.k8s.io @@ -19001,21 +23766,28 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: "The TLSRoute resource is similar to TCPRoute, but can be configured - to match against TLS-specific metadata. This allows more flexibility in - matching streams for a given TLS listener. \n 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." + description: |- + The TLSRoute resource is similar to TCPRoute, but can be configured + 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: 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' + 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' + 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 @@ -19023,43 +23795,56 @@ spec: description: Spec defines the desired state of TLSRoute. properties: hostnames: - description: "Hostnames defines a set of SNI names that should match - against the SNI attribute of TLS ClientHello message in TLS handshake. - This matches the RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: \n * 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`. * A Listener with `*.example.com` as the hostname - matches TLSRoutes 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. \n 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. \n 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. \n Support: Core" + description: |- + Hostnames defines a set of SNI names that should match against the + 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`. + * A Listener with `*.example.com` as the hostname matches TLSRoutes + 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. + + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -19067,165 +23852,204 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -19264,65 +24088,81 @@ spec: description: TLSRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the rule performs no forwarding; if no filters are specified - that would result in a response being sent, the underlying - implementation must actively reject request attempts to this - backend, by rejecting the connection or returning a 500 status - code. Request rejections must respect weight; if an invalid - backend is requested to have 80% of requests, then 80% of - requests must be rejected instead. \n Support: Core for Kubernetes - Service \n Support: Extended for Kubernetes ServiceImport - \n Support: Implementation-specific for any other resource - \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or + a Service with no endpoints), the rule performs no forwarding; if no + filters are specified that would result in a response being sent, the + underlying implementation must actively reject request attempts to this + backend, by rejecting the connection or returning a 500 status code. + Request rejections must respect weight; if an invalid backend is + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -19333,43 +24173,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -19395,81 +24239,88 @@ spec: description: Status defines the current state of TLSRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -19483,12 +24334,12 @@ 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. + --- + 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 @@ -19506,131 +24357,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -19668,8 +24538,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: udproutes.gateway.networking.k8s.io @@ -19691,19 +24561,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: UDPRoute provides a way to route UDP traffic. When combined with - a Gateway listener, it can be used to forward traffic on the port specified - by the listener to a set of backends specified by the UDPRoute. + description: |- + UDPRoute provides a way to route UDP traffic. When combined with a Gateway + listener, it can be used to forward traffic on the port specified by the + listener to a set of backends specified by the UDPRoute. 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' + 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' + 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 @@ -19711,165 +24587,204 @@ spec: description: Spec defines the desired state of UDPRoute. properties: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -19908,62 +24823,78 @@ spec: description: UDPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Packet drops must respect weight; - if an invalid backend is requested to have 80% of the packets, - then 80% of packets must be dropped instead. \n Support: Core - for Kubernetes Service \n Support: Extended for Kubernetes - ServiceImport \n Support: Implementation-specific for any - other resource \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Packet drops must + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -19974,43 +24905,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -20036,81 +24971,88 @@ spec: description: Status defines the current state of UDPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -20124,12 +25066,12 @@ 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. + --- + 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 @@ -20147,131 +25089,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -20329,8 +25290,6 @@ rules: - configmaps - endpoints - namespaces - - secrets - - services verbs: - get - list @@ -20419,22 +25378,6 @@ rules: - tlsroutes/status verbs: - update -- apiGroups: - - gateway.networking.k8s.io - resources: - - gatewayclasses - - gateways - verbs: - - get - - list - - watch -- apiGroups: - - gateway.networking.k8s.io - resources: - - gatewayclasses/status - - gateways/status - verbs: - - update - apiGroups: - networking.k8s.io resources: @@ -20462,17 +25405,6 @@ rules: - list - update - watch -- apiGroups: - - projectcontour.io - resources: - - contourconfigurations - - extensionservices - - httpproxies - - tlscertificatedelegations - verbs: - - get - - list - - watch - apiGroups: - projectcontour.io resources: @@ -20487,6 +25419,9 @@ rules: - projectcontour.io resources: - contourdeployments + - extensionservices + - httpproxies + - tlscertificatedelegations verbs: - get - list diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index d68bc13728d..42380944242 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -39,7 +39,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourconfigurations.projectcontour.io spec: preserveUnknownFields: false @@ -156,6 +156,12 @@ spec: defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -636,9 +642,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -908,6 +914,8 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -930,6 +938,9 @@ spec: the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -1023,10 +1034,14 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -1179,6 +1194,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -1309,12 +1326,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 @@ -1396,7 +1408,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourdeployments.projectcontour.io spec: preserveUnknownFields: false @@ -1461,9 +1473,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: @@ -1630,6 +1639,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 @@ -1712,12 +1727,8 @@ spec: use to replace existing DaemonSet pods with new pods. 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: @@ -1788,9 +1799,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: @@ -1850,6 +1858,8 @@ spec: to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). type: string name: description: This must match the Name of a Volume. @@ -1859,6 +1869,21 @@ spec: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. type: boolean + recursiveReadOnly: + description: |- + 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 + field is set to Enabled, the mount is made recursively read-only if it is + 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: description: |- Path within the volume from which the container's volume should be mounted. @@ -1894,7 +1919,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: |- @@ -1934,6 +1958,7 @@ spec: 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. @@ -1947,6 +1972,7 @@ spec: to shared' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -1986,6 +2012,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic path: description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' @@ -2007,10 +2034,13 @@ spec: More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2046,10 +2076,13 @@ spec: to OpenStack. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2114,11 +2147,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the ConfigMap @@ -2151,10 +2188,13 @@ spec: secret object contains more than one secret, all secret references are passed. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2198,8 +2238,8 @@ spec: properties: fieldRef: description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' + pod: only annotations, labels, name, namespace + and uid are supported.' properties: apiVersion: description: Version of the schema the FieldPath @@ -2258,6 +2298,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object emptyDir: description: |- @@ -2349,6 +2390,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -2493,11 +2535,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2525,8 +2569,8 @@ spec: If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be 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/persistent-volumes#volumeattributesclass - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). type: string volumeMode: description: |- @@ -2552,7 +2596,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 lun number' @@ -2569,6 +2612,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic wwids: description: |- wwids Optional: FC volume world wide identifiers (wwids) @@ -2576,6 +2620,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object flexVolume: description: |- @@ -2612,10 +2657,13 @@ spec: scripts. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2649,7 +2697,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: |- @@ -2730,9 +2777,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: |- @@ -2749,6 +2793,39 @@ 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 @@ -2769,7 +2846,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: |- @@ -2781,6 +2857,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -2796,6 +2873,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic readOnly: description: |- readOnly here will force the ReadOnly setting in VolumeMounts. @@ -2806,10 +2884,13 @@ spec: target and initiator authentication properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2928,10 +3009,13 @@ 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: |- @@ -2980,11 +3064,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3063,11 +3149,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the @@ -3090,7 +3180,7 @@ spec: fieldRef: description: 'Required: Selects a field of the pod: only annotations, labels, - name and namespace are supported.' + name, namespace and uid are supported.' properties: apiVersion: description: Version of the schema @@ -3154,6 +3244,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object secret: description: secret information about the secret @@ -3197,11 +3288,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional field specify whether @@ -3240,6 +3335,7 @@ spec: type: object type: object type: array + x-kubernetes-list-type: atomic type: object quobyte: description: quobyte represents a Quobyte mount on the host @@ -3290,7 +3386,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: |- @@ -3298,6 +3393,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. @@ -3310,7 +3406,9 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -3330,14 +3428,18 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -3352,6 +3454,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -3377,10 +3480,13 @@ spec: sensitive information. If this is not provided, Login operation will fail. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3389,6 +3495,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: |- storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. @@ -3465,6 +3572,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic optional: description: optional field specify whether the Secret or its keys must be defined @@ -3496,10 +3604,13 @@ spec: credentials. If not specified, default values will be attempted. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3713,6 +3824,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 @@ -3841,6 +3958,12 @@ spec: Service; defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -4321,9 +4444,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -4594,6 +4717,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -4616,6 +4741,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -4709,10 +4837,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -4866,6 +4998,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -4878,16 +5012,8 @@ spec: description: Conditions describe the current conditions of the ContourDeployment resource. 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: |- @@ -4928,12 +5054,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 @@ -4959,7 +5080,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: extensionservices.projectcontour.io spec: preserveUnknownFields: false @@ -5004,6 +5125,39 @@ spec: description: ExtensionServiceSpec defines the desired state of an ExtensionService resource. properties: + circuitBreakerPolicy: + description: |- + CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. + If defined this overrides the global circuit breaker budget. + properties: + maxConnections: + description: The maximum number of connections that a single Envoy + instance allows to the Kubernetes Service; defaults to 1024. + format: int32 + type: integer + maxPendingRequests: + description: The maximum number of pending requests that a single + Envoy instance allows to the Kubernetes Service; defaults to + 1024. + format: int32 + type: integer + maxRequests: + description: The maximum parallel requests a single Envoy instance + allows to the Kubernetes Service; defaults to 1024 + format: int32 + type: integer + maxRetries: + description: The maximum number of parallel retries a single Envoy + instance allows to the Kubernetes Service; defaults to 3. + format: int32 + type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer + type: object loadBalancerPolicy: description: |- The policy for load balancing GRPC service requests. Note that the @@ -5041,6 +5195,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -5055,6 +5211,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -5322,12 +5480,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 @@ -5407,7 +5560,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: httpproxies.projectcontour.io spec: preserveUnknownFields: false @@ -6099,6 +6252,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6113,6 +6268,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -6213,6 +6370,8 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -6236,6 +6395,9 @@ spec: the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -6329,10 +6491,14 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -6977,6 +7143,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6991,6 +7159,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -7657,6 +7827,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -7679,6 +7851,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -7772,10 +7947,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -8114,12 +8293,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 @@ -8238,8 +8412,6 @@ spec: CamelCase names - cloud provider specific error values must have names that comply with the format foo.example.com/CamelCase. - --- - 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 @@ -8249,12 +8421,12 @@ spec: format: int32 type: integer protocol: - default: TCP description: |- Protocol is the protocol of the service port of which status is recorded here The supported values are: "TCP", "UDP", "SCTP" type: string required: + - error - port - protocol type: object @@ -8262,6 +8434,7 @@ spec: x-kubernetes-list-type: atomic type: object type: array + x-kubernetes-list-type: atomic type: object type: object required: @@ -8277,7 +8450,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: tlscertificatedelegations.projectcontour.io spec: preserveUnknownFields: false @@ -8478,12 +8651,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 @@ -8847,9 +9015,6 @@ spec: app: contour template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8000" labels: app: contour spec: @@ -8948,10 +9113,6 @@ spec: app: envoy template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8002" - prometheus.io/path: "/stats/prometheus" labels: app: envoy spec: @@ -8982,7 +9143,7 @@ spec: - --log-level info command: - envoy - image: docker.io/envoyproxy/envoy:v1.29.2 + image: docker.io/envoyproxy/envoy:v1.32.0 imagePullPolicy: IfNotPresent name: envoy env: @@ -9005,6 +9166,10 @@ spec: hostPort: 443 name: https protocol: TCP + - containerPort: 8002 + hostPort: 8002 + name: metrics + protocol: TCP readinessProbe: httpGet: path: /ready @@ -9071,7 +9236,7 @@ spec: runAsGroup: 65534 --- -# Copyright 2023 The Kubernetes Authors. +# Copyright 2024 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -9090,30 +9255,28 @@ spec: # --- # -# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendlbpolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - labels: - gateway.networking.k8s.io/policy: Direct - name: backendtlspolicies.gateway.networking.k8s.io + name: backendlbpolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: BackendTLSPolicy - listKind: BackendTLSPolicyList - plural: backendtlspolicies + kind: BackendLBPolicy + listKind: BackendLBPolicyList + plural: backendlbpolicies shortNames: - - btlspolicy - singular: backendtlspolicy + - blbpolicy + singular: backendlbpolicy scope: Namespaced versions: - additionalPrinterColumns: @@ -9123,332 +9286,356 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: BackendTLSPolicy provides a way to configure how a Gateway connects - to a Backend via TLS. + description: |- + BackendLBPolicy provides a way to define load balancing rules + for a backend. 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' + 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' + 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 BackendTLSPolicy. + description: Spec defines the desired state of BackendLBPolicy. properties: - targetRef: - description: "TargetRef identifies an API object to apply the policy - to. Only Services have Extended support. Implementations MAY support - additional objects, with Implementation Specific support. Note that - this config applies to the entire referenced resource by default, - but this default may change in the future to provide a more granular - application of the policy. \n Support: Extended for Kubernetes Service - \n Support: Implementation-specific for any other resource" + sessionPersistence: + description: |- + SessionPersistence defines and configures session persistence + for the backend. + + Support: Extended properties: - group: - description: Group is the group of the target resource. - 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 target resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + 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 - name: - description: Name is the name of the target resource. - maxLength: 253 - minLength: 1 + 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 - namespace: - description: Namespace is the namespace of the referent. When - unspecified, the local namespace is inferred. Even when policy - targets a resource in a different namespace, it MUST only apply - to traffic originating from the same namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 - sectionName: - description: "SectionName is the name of a section within the - target resource. When unspecified, this targetRef targets the - entire resource. In the following resources, SectionName is - interpreted as the following: \n * Gateway: Listener Name * - Service: Port Name \n 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." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + 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 - required: + 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)' + targetRefs: + description: |- + TargetRef identifies an API object to apply policy to. + Currently, Backends (i.e. Service, ServiceImport, or any + implementation-specific backendRef) are the only valid API + target references. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + 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 target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-list-map-keys: - group - kind - name - type: object - tls: - description: TLS contains backend TLS policy configuration. - properties: - caCertRefs: - description: "CACertRefs contains one or more references to Kubernetes - objects that contain a PEM-encoded TLS CA certificate bundle, - which is used to validate a TLS handshake between the Gateway - and backend Pod. \n If CACertRefs is empty or unspecified, then - WellKnownCACerts must be specified. Only one of CACertRefs or - WellKnownCACerts may be specified, not both. If CACertRefs is - empty or unspecified, the configuration for WellKnownCACerts - MUST be honored instead. \n References to a resource in a different - namespace are invalid for the moment, although we will revisit - this in the future. \n A single CACertRef 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. \n Support: Core - An optional single - reference to a Kubernetes ConfigMap, with the CA certificate - in a key named `ca.crt`. \n Support: Implementation-specific - (More than one reference, or other kinds of resources)." - items: - description: "LocalObjectReference identifies an API object - within the namespace of the referrer. 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. \n 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." + x-kubernetes-list-type: map + required: + - targetRefs + type: object + status: + description: Status defines the current state of BackendLBPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + 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 + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + 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 + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + 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: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. 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. + 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: - description: Kind is kind of the referent. For example "HTTPRoute" - or "Service". + 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. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - maxItems: 8 - type: array - hostname: - description: "Hostname is used for two purposes in the connection - between Gateways and backends: \n 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. \n 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 - wellKnownCACerts: - description: "WellKnownCACerts specifies whether system CA certificates - may be used in the TLS handshake between the gateway and backend - pod. \n If WellKnownCACerts is unspecified or empty (\"\"), - then CACertRefs must be specified with at least one entry for - a valid configuration. Only one of CACertRefs or WellKnownCACerts - may be specified, not both. \n Support: Core for \"System\"" - enum: - - System - type: string - required: - - hostname - type: object - x-kubernetes-validations: - - message: must not contain both CACertRefs and WellKnownCACerts - rule: '!(has(self.caCertRefs) && size(self.caCertRefs) > 0 && has(self.wellKnownCACerts) - && self.wellKnownCACerts != "")' - - message: must specify either CACertRefs or WellKnownCACerts - rule: (has(self.caCertRefs) && size(self.caCertRefs) > 0 || has(self.wellKnownCACerts) - && self.wellKnownCACerts != "") - required: - - targetRef - - tls - type: object - status: - description: Status defines the current state of BackendTLSPolicy. - properties: - ancestors: - description: "Ancestors is a list of ancestor resources (usually Gateways) - that are associated with the policy, and the status of the policy - with respect to each ancestor. When this policy attaches to a parent, - the controller that manages the parent and the ancestors MUST add - an entry to this list when the controller first sees the policy - and SHOULD update the entry as appropriate when the relevant ancestor - is modified. \n 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. \n 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. \n 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. \n A maximum of 16 ancestors will be represented - in this list. An empty list means the Policy is not relevant for - any ancestors. \n 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 here. For example, if this list was full on - BackendTLSPolicy, no additional Gateways would be able to reference - the Service targeted by the BackendTLSPolicy." - items: - description: "PolicyAncestorStatus describes the status of a route - with respect to an associated Ancestor. \n 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 the GatewayClass. Almost always, in - this hierarchy, the Gateway will be the most useful object to - place Policy status on, so we recommend that implementations SHOULD - use Gateway as the PolicyAncestorStatus object unless the designers - have a _very_ good reason otherwise. \n 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. \n 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. \n 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. \n 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. \n 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: - ancestorRef: - description: AncestorRef corresponds with a ParentRef in the - spec that this PolicyAncestorStatus 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). \n - 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -9461,46 +9648,45 @@ spec: respect to the given Ancestor. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -9514,12 +9700,12 @@ 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. + --- + 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 @@ -9537,16 +9723,20 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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\/\-._~%!$&'()*+,;=:]+$ @@ -9575,264 +9765,583 @@ status: storedVersions: null --- # -# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml +# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml # apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null - name: gatewayclasses.gateway.networking.k8s.io + labels: + gateway.networking.k8s.io/policy: Direct + name: backendtlspolicies.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io names: categories: - gateway-api - kind: GatewayClass - listKind: GatewayClassList - plural: gatewayclasses + kind: BackendTLSPolicy + listKind: BackendTLSPolicyList + plural: backendtlspolicies shortNames: - - gc - singular: gatewayclass - scope: Cluster + - btlspolicy + singular: backendtlspolicy + scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1 + name: v1alpha3 schema: openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n 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 propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n 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. \n GatewayClass is - a Cluster level resource." + description: |- + BackendTLSPolicy provides a way to configure how a Gateway + connects to a Backend via TLS. 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' + 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' + 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 GatewayClass. + description: Spec defines the desired state of BackendTLSPolicy. properties: - controllerName: - description: "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. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n 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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n 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. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" + targetRefs: + description: |- + TargetRefs identifies an API object to apply the policy to. + Only Services have Extended support. Implementations MAY support + additional objects, with Implementation Specific support. + Note that this config applies to the entire referenced resource + 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: |- + LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a + direct policy to. This should be used as part of Policy resources that can + target single resources. For more information on how this policy attachment + 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. + properties: + group: + description: Group is the group of the target resource. + 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 target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + sectionName: + description: |- + SectionName is the name of a section within the target resource. When + 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. + 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: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + validation: + description: Validation contains backend TLS validation configuration. properties: - group: - description: Group is the group of the referent. - 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. - 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. + caCertificateRefs: + description: |- + CACertificateRefs contains one or more references to Kubernetes objects that + 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: + description: |- + LocalObjectReference identifies an API object within the namespace of the + referrer. + 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. + 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 + maxItems: 8 + type: array + hostname: + description: |- + 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. + + 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 - namespace: - description: Namespace is the namespace of the referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + 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 + implementation does not support the WellKnownCACertificates field or the value + 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 type: string required: - - group - - kind - - name + - hostname type: object + x-kubernetes-validations: + - message: must not contain both CACertificateRefs and WellKnownCACertificates + rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs) + > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates + != "")' + - message: must specify either CACertificateRefs or WellKnownCACertificates + rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs) + > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates + != "") required: - - controllerName + - targetRefs + - validation type: object status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." + description: Status defines the current state of BackendTLSPolicy. properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + 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 + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + 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 + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + 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: - 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 + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus 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 + conditions: + 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}" + 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-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])$ + 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 required: - - lastTransitionTime - - message - - reason - - status - - type + - ancestorRef + - controllerName type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 + maxItems: 16 type: array - x-kubernetes-list-type: set + required: + - ancestors type: object required: - spec type: object served: true - storage: false + storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml +# +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 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + versions: - additionalPrinterColumns: - jsonPath: .spec.controllerName name: Controller @@ -9847,32 +10356,42 @@ spec: name: Description priority: 1 type: string - name: v1beta1 + name: v1 schema: openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the - user for creating Gateway resources. \n 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 propagated down to existing - Gateways. This recommendation is intended to limit the blast radius of changes - to GatewayClass or associated parameters. If implementations choose to propagate - GatewayClass changes to existing Gateways, that MUST be clearly documented - by the implementation. \n 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. \n GatewayClass is - a Cluster level resource." + description: |- + 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 + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + 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: - 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' + 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' + 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 @@ -9880,10 +10399,15 @@ spec: description: Spec defines the desired state of GatewayClass. properties: controllerName: - description: "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. \n Example: \"example.net/gateway-controller\". - \n This field is not mutable and cannot be empty. \n Support: Core" + description: |- + 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 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ @@ -9896,14 +10420,23 @@ spec: maxLength: 64 type: string parametersRef: - description: "ParametersRef is a reference to a resource that contains - the configuration parameters corresponding to the GatewayClass. - This is optional if the controller does not require any additional - configuration. \n 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. \n If the - referent cannot be found, the GatewayClass's \"InvalidParameters\" - status condition will be true. \n Support: Implementation-specific" + description: |- + ParametersRef is a reference to a resource that contains the configuration + 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. + + 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: description: Group is the group of the referent. @@ -9922,9 +10455,10 @@ spec: minLength: 1 type: string namespace: - description: Namespace is the namespace of the referent. This - field is required when referring to a Namespace-scoped resource - and MUST be unset when referring to a Cluster-scoped resource. + description: |- + Namespace is the namespace of the referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -9945,9 +10479,11 @@ spec: reason: Waiting status: Unknown type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations - MUST populate status on all GatewayClass resources which specify their - controller name." + description: |- + Status defines the current state of GatewayClass. + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. properties: conditions: default: @@ -9956,49 +10492,52 @@ spec: reason: Pending status: Unknown type: Accepted - description: "Conditions is the current status from the controller - for this GatewayClass. \n Controllers should prefer to publish conditions - using values of GatewayClassConditionType for the type of each Condition." + description: |- + 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. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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. + 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. + 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. + 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 + 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 @@ -10010,11 +10549,12 @@ 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. + --- + 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 @@ -10031,30 +10571,13 @@ spec: - type x-kubernetes-list-type: map supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass - support. It MUST be sorted in ascending alphabetical order. ' + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. items: - description: SupportedFeature is used to describe distinct features - that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. type: string maxItems: 64 type: array @@ -10067,6 +10590,254 @@ spec: storage: true subresources: status: {} + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + 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 + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + 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: + 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 GatewayClass. + properties: + controllerName: + description: |- + 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 + 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 + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + 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. + + 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: + description: Group is the group of the referent. + 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. + 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 referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + 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: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + 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}" + 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 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + supportedFeatures: + description: | + SupportedFeatures is the set of features the GatewayClass support. + It MUST be sorted in ascending alphabetical order. + items: + description: |- + SupportedFeature is used to describe distinct features that are covered by + conformance tests. + type: string + maxItems: 64 + type: array + x-kubernetes-list-type: set + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} status: acceptedNames: kind: "" @@ -10081,8 +10852,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: gateways.gateway.networking.k8s.io @@ -10115,18 +10886,24 @@ spec: name: v1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. 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' + 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' + 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 @@ -10134,20 +10911,28 @@ spec: description: Spec defines the desired state of Gateway. properties: addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n 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. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + 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. @@ -10174,9 +10959,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -10198,179 +10985,264 @@ spec: rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. maxLength: 253 minLength: 1 type: string infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + Support: Core + properties: annotations: 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. + 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: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" + 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 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. + 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: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" + 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. + + Support: Extended maxProperties: 8 type: object - type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n 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 \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n 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. \n For example, the following - Listener scenarios are distinct: \n 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 \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n 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. \n 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. \n 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. \n 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 `\"\"`. \n 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. \n 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\"`. \n 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\". \n 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 accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n 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 indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 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. \n 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. \n 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. - \n 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 to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" - items: - description: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. - properties: - allowedRoutes: - default: - namespaces: + 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: + description: Group is the group of the referent. + 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. + 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 + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + 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 + "Listeners in a single Gateway" because implementations MAY merge configuration + 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 + "TLS" Protocol that all have unique Hostname values. + 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 + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + 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 + indicate in the Message which Listeners are conflicted, and which are + 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 + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + 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: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n 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: \n * 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 a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - 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, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + 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 + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + 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, + support for that Route rule should be dropped to ensure consistency. For + 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: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n 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. \n Support: Core" + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + 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 of a Route resource. @@ -10395,173 +11267,200 @@ spec: namespaces: default: from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" + description: |- + 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: default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * 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. \n Support: - Core" + description: |- + 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 - Selector - Same type: string selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" + description: |- + Selector must be specified when From is set to "Selector". In that case, + 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: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic type: object type: object hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * 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 protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n 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. \n 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`. \n Support: Core" + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + 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 + protocol layers as described above. If an implementation does not + 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 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n Support: Core" + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + Support: Core format: int32 maximum: 65535 minimum: 1 type: integer protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n Support: Core" + 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]+$ type: string tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" + description: |- + TLS is the TLS configuration for the Listener. This field is required if + 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: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n 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. - \n 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. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + 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. - \n 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. \n 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." + 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. 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. + 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 @@ -10579,14 +11478,16 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the referenced - object. When unspecified, the local namespace is - inferred. \n 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. - \n Support: Core" + 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])?$ @@ -10596,49 +11497,143 @@ spec: type: object maxItems: 64 type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + 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: |- + 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 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 + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + 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. + 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 "ConfigMap" 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 + 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: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object mode: default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" + description: |- + 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 + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + Support: Core enum: - Terminate - Passthrough type: string 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. + 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. \n 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. \n Support: Implementation-specific" + 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 type: object x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType - is Terminate + - message: certificateRefs or options must be specified when + mode is Terminate rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' + > 0 || size(self.options) > 0 : true' required: - name - port @@ -10651,13 +11646,13 @@ spec: - name x-kubernetes-list-type: map x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - message: tls must not be specified for protocols ['HTTP', 'TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' - message: hostname must not be specified for protocols ['TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) || l.hostname == '''') : true)' @@ -10688,12 +11683,17 @@ spec: description: Status defines the current state of Gateway. properties: addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * 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) \n " + description: |+ + 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. @@ -10720,9 +11720,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -10748,50 +11750,57 @@ spec: reason: Pending status: Unknown type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n 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. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" + 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. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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. + 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. + 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. + 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. + 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 @@ -10805,11 +11814,12 @@ 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. + --- + 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 @@ -10832,23 +11842,24 @@ spec: description: ListenerStatus is the status associated with a Listener. properties: attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n 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 a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." + description: |- + 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 + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + 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 type: integer conditions: @@ -10856,46 +11867,45 @@ spec: listener. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -10909,12 +11919,12 @@ 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. + --- + 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 @@ -10938,15 +11948,16 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n 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 and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." + description: |- + SupportedKinds is the list indicating the Kinds supported by this + 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 + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. items: description: RouteGroupKind indicates the group and kind of a Route resource. @@ -10984,7 +11995,7 @@ spec: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: @@ -11003,18 +12014,24 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling - infrastructure by binding Listeners to a set of IP addresses. + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. 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' + 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' + 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 @@ -11022,20 +12039,28 @@ spec: description: Spec defines the desired state of Gateway. properties: addresses: - description: "Addresses requested for this Gateway. This is optional - and behavior can depend on the implementation. If a value is set - in the spec and the requested address is invalid or unavailable, - the implementation MUST indicate this in the associated entry in - GatewayStatus.Addresses. \n 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. \n If no Addresses - are specified, the implementation MAY schedule the Gateway in an - implementation-specific manner, assigning an appropriate set of - Addresses. \n The implementation MUST bind all Listeners to every - GatewayAddress that it assigns to the Gateway and add a corresponding - entry in GatewayStatus.Addresses. \n Support: Extended \n " + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + 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. @@ -11062,9 +12087,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -11086,183 +12113,268 @@ spec: rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name - of a GatewayClass resource. + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. maxLength: 253 minLength: 1 type: string infrastructure: - description: "Infrastructure defines infrastructure level attributes - about this Gateway instance. \n Support: Core \n " + description: |+ + Infrastructure defines infrastructure level attributes about this Gateway instance. + + Support: Core + properties: annotations: 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. + 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: "Annotations that SHOULD be applied to any resources - created in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - annotations as they see fit. \n Support: Extended" + 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 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. + 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: "Labels that SHOULD be applied to any resources created - in response to this Gateway. \n 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. - \n An implementation may chose to add additional implementation-specific - labels as they see fit. \n Support: Extended" + 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. + + Support: Extended maxProperties: 8 type: object - type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define - logical endpoints that are bound on this Gateway's addresses. At - least one Listener MUST be specified. \n 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 \"Listeners - in a single Gateway\" because implementations MAY merge configuration - from multiple Gateways onto a single data plane, and these rules - _also_ apply in that case). \n Practically, this means that each - listener in a set MUST have a unique combination of Port, Protocol, - and, if supported by the protocol, Hostname. \n Some combinations - of port, protocol, and TLS settings are considered Core support - and MUST be supported by implementations based on their targeted - conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, - Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: - Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: - 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners - have the following property: \n 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. \n For example, the following - Listener scenarios are distinct: \n 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 \"TLS\" Protocol that all have unique Hostname - values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, - where no Listener with the same Protocol has the same Port value. - \n 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. \n 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. \n 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. \n 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 `\"\"`. \n 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. \n 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\"`. \n 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\". \n 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 accept a partial Listener - set only if they throw out *all* the conflicting Listeners. No picking - one of the conflicting listeners as the winner. This also means - that the Gateway must have at least one non-conflicting Listener - in this case, otherwise it violates the requirement that at least - one Listener must be present. \n 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 indicate in the Message which Listeners are conflicted, - and which are Accepted. Additionally, the Listener status for those - listeners SHOULD indicate which Listeners are conflicted and not - Accepted. \n A Gateway's Listeners are considered \"compatible\" - if: \n 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. \n 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. \n 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. - \n 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 to the \"foo.example.com\" Listener (and not the \"*.example.com\" - Listener). This concept is known as \"Listener Isolation\". Implementations - that do not support Listener Isolation MUST clearly document this. - \n Implementations MAY merge separate Gateways onto a single set - of Addresses if all Listeners across all Gateways are compatible. - \n Support: Core" - items: - description: Listener embodies the concept of a logical endpoint - where a Gateway accepts network connections. - properties: - allowedRoutes: - default: - namespaces: - from: Same - description: "AllowedRoutes defines the types of routes that - MAY be attached to a Listener and the trusted namespaces where - those Route resources MAY be present. \n 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: \n * 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 a Route with a creation timestamp of \"2020-09-08 01:02:04\". - * If everything else is equivalent, the Route appearing first - in alphabetical order (namespace/name) should be given precedence. - For example, foo/bar is given precedence over foo/baz. \n - 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, support for that Route rule should - be dropped to ensure consistency. For example, even if a filter - specified by a Route rule is invalid, the rest of the rules - within that Route should still be supported. \n Support: Core" - properties: - kinds: - description: "Kinds specifies the groups and kinds of Routes - that are allowed to bind to this Gateway Listener. When - unspecified or empty, the kinds of Routes selected are - determined using the Listener protocol. \n 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. \n Support: Core" - items: - description: RouteGroupKind indicates the group and kind - of a Route resource. - properties: + 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: + description: Group is the group of the referent. + 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. + 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 + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + 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 + "Listeners in a single Gateway" because implementations MAY merge configuration + 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 + "TLS" Protocol that all have unique Hostname values. + 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 + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + 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 + indicate in the Message which Listeners are conflicted, and which are + 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 + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + 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: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + 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 + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + 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, + support for that Route rule should be dropped to ensure consistency. For + 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: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + 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 + of a Route resource. + properties: group: default: gateway.networking.k8s.io description: Group is the group of the Route. @@ -11283,173 +12395,200 @@ spec: namespaces: default: from: Same - description: "Namespaces indicates namespaces from which - Routes may be attached to this Listener. This is restricted - to the namespace of this Gateway by default. \n Support: - Core" + description: |- + 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: default: Same - description: "From indicates where Routes will be selected - for this Gateway. Possible values are: \n * 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. \n Support: - Core" + description: |- + 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 - Selector - Same type: string selector: - description: "Selector must be specified when From is - set to \"Selector\". In that case, only Routes in - Namespaces matching this Selector will be selected - by this Gateway. This field is ignored for other values - of \"From\". \n Support: Core" + description: |- + Selector must be specified when From is set to "Selector". In that case, + 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: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. properties: key: description: key is the label key that the selector applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object x-kubernetes-map-type: atomic type: object type: object hostname: - description: "Hostname specifies the virtual hostname to match - for protocol types that define this concept. When unspecified, - all hostnames are matched. This field is ignored for protocols - that don't require hostname based matching. \n Implementations - MUST apply Hostname matching appropriately for each of the - following protocols: \n * 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 protocol layers as described - above. If an implementation does not ensure that both the - SNI and Host header match the Listener hostname, it MUST clearly - document that. \n 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. \n 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`. \n Support: Core" + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + 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 + protocol layers as described above. If an implementation does not + 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 pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string name: - description: "Name is the name of the Listener. This name MUST - be unique within a Gateway. \n Support: Core" + description: |- + Name is the name of the Listener. This name MUST be unique within a + 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 port: - description: "Port is the network port. Multiple listeners may - use the same port, subject to the Listener compatibility rules. - \n Support: Core" + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + Support: Core format: int32 maximum: 65535 minimum: 1 type: integer protocol: - description: "Protocol specifies the network protocol this listener - expects to receive. \n Support: Core" + 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]+$ type: string tls: - description: "TLS is the TLS configuration for the Listener. - This field is required if the Protocol field is \"HTTPS\" - or \"TLS\". It is invalid to set this field if the Protocol - field is \"HTTP\", \"TCP\", or \"UDP\". \n The association - of SNIs to Certificate defined in GatewayTLSConfig is defined - based on the Hostname field for this listener. \n The GatewayClass - MUST use the longest matching SNI out of all available certificates - for any TLS handshake. \n Support: Core" + description: |- + TLS is the TLS configuration for the Listener. This field is required if + 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: - description: "CertificateRefs contains a series of references - to Kubernetes objects that contains TLS certificates and - private keys. These certificates are used to establish - a TLS handshake for requests that match the hostname of - the associated listener. \n 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. - \n 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. \n This - field is required to have at least one element when the - mode is set to \"Terminate\" (default) and is optional - otherwise. \n CertificateRefs can reference to standard - Kubernetes resources, i.e. Secret, or implementation-specific - custom resources. \n Support: Core - A single reference - to a Kubernetes Secret of type kubernetes.io/tls \n Support: - Implementation-specific (More than one reference or other - resource types)" + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + 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. - \n 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. \n 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." + 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. 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. + 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 @@ -11467,14 +12606,16 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the referenced - object. When unspecified, the local namespace is - inferred. \n 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. - \n Support: Core" + 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])?$ @@ -11484,49 +12625,143 @@ spec: type: object maxItems: 64 type: array + frontendValidation: + description: |+ + FrontendValidation holds configuration information for validating the frontend (client). + Setting this field will require clients to send a client certificate + required for validation during the TLS handshake. In browsers this may result in a dialog appearing + 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: |- + 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 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 + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + items: + 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. + 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 "ConfigMap" 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 + 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: + - group + - kind + - name + type: object + maxItems: 8 + minItems: 1 + type: array + type: object mode: default: Terminate - description: "Mode defines the TLS behavior for the TLS - session initiated by the client. There are two possible - modes: \n - Terminate: The TLS session between the downstream - client and the Gateway is terminated at the Gateway. This - mode requires certificateRefs to be set and contain at - least one element. - Passthrough: The TLS session is NOT - terminated by the Gateway. This implies that the Gateway - can't decipher the TLS stream except for the ClientHello - message of the TLS protocol. CertificateRefs field is - ignored in this mode. \n Support: Core" + description: |- + 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 + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + Support: Core enum: - Terminate - Passthrough type: string 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. + 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. \n 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. \n Support: Implementation-specific" + 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 type: object x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType - is Terminate + - message: certificateRefs or options must be specified when + mode is Terminate rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) - > 0 : true' + > 0 || size(self.options) > 0 : true' required: - name - port @@ -11539,13 +12774,13 @@ spec: - name x-kubernetes-list-type: map x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) - : true)' - message: tls must not be specified for protocols ['HTTP', 'TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' - message: hostname must not be specified for protocols ['TCP', 'UDP'] rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) || l.hostname == '''') : true)' @@ -11576,12 +12811,17 @@ spec: description: Status defines the current state of Gateway. properties: addresses: - description: "Addresses lists the network addresses that have been - bound to the Gateway. \n This list may differ from the addresses - provided in the spec under some conditions: \n * 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) \n " + description: |+ + 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. @@ -11608,9 +12848,11 @@ spec: pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ type: string value: - description: "Value of the address. The validity of the values - will depend on the type and support by the controller. \n - Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + description: |- + 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 type: string @@ -11636,50 +12878,57 @@ spec: reason: Pending status: Unknown type: Programmed - description: "Conditions describe the current conditions of the Gateway. - \n 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. \n Known condition types are: \n * \"Accepted\" - * \"Programmed\" * \"Ready\"" + 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. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + 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. + 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. + 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. + 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. + 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 @@ -11693,11 +12942,12 @@ 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. + --- + 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 @@ -11720,23 +12970,24 @@ spec: description: ListenerStatus is the status associated with a Listener. properties: attachedRoutes: - description: "AttachedRoutes represents the total number of - Routes that have been successfully attached to this Listener. - \n 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 a Listener when it is selected - by the Listener's AllowedRoutes field AND the Route has a - valid ParentRef selecting the whole Gateway resource or a - specific Listener as a parent resource (more detail on attachment - semantics can be found in the documentation on the various - Route kinds ParentRefs fields). Listener or Route status does - not impact successful attachment, i.e. the AttachedRoutes - field count MUST be set for Listeners with condition Accepted: - false and MUST count successfully attached Routes that may - themselves have Accepted: false conditions. \n Uses for this - field include troubleshooting Route attachment and measuring - blast radius/impact of changes to a Listener." + description: |- + 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 + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + 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 type: integer conditions: @@ -11744,46 +12995,45 @@ spec: listener. items: description: "Condition contains details for one aspect of - the current state of this API Resource. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -11797,12 +13047,12 @@ 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. + --- + 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 @@ -11826,15 +13076,16 @@ spec: pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string supportedKinds: - description: "SupportedKinds is the list indicating the Kinds - supported by this listener. This MUST represent the kinds - an implementation supports for that Listener configuration. - \n 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 and invalid Route kinds are specified, - the implementation MUST reference the valid Route kinds that - have been specified." + description: |- + SupportedKinds is the list indicating the Kinds supported by this + 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 + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. items: description: RouteGroupKind indicates the group and kind of a Route resource. @@ -11872,7 +13123,7 @@ spec: - spec type: object served: true - storage: true + storage: false subresources: status: {} status: @@ -11889,8 +13140,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: grpcroutes.gateway.networking.k8s.io @@ -11912,40 +13163,2137 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date - name: v1alpha2 + name: v1 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. \n 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. - \n 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. \n 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\". + 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." + 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' + 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: 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' + 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 @@ -11953,56 +15301,73 @@ 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: \n 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. \n 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: - \n * 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`. + 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. - \n 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`. \n 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. \n 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. \n 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: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n The rejected Route MUST raise an 'Accepted' condition with a - status of 'False' in the corresponding RouteParentStatus. \n Support: - Core" + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -12010,165 +15375,204 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -12204,82 +15608,99 @@ spec: 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). + 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. - \n See the GRPCBackendRef definition for the rules about what - makes a single GRPCBackendRef invalid. \n 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. \n 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. \n Support: Core for Kubernetes - Service \n Support: Implementation-specific for any other - resource \n Support for weight: Core" + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in GRPCRouteRule.)" + 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. + 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. \n Support: Implementation-specific \n - This filter can be used multiple times within - the same rule." + 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. + 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 @@ -12301,35 +15722,45 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -12350,44 +15781,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -12409,64 +15857,68 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -12477,29 +15929,27 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -12515,35 +15965,45 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -12564,44 +16024,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -12623,32 +16100,32 @@ spec: 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: \n - - 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. - \n - Extended: Filter types and their corresponding - configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - - 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. - \n Implementers are encouraged to define custom - implementation types to extend the core API with - implementation-specific behavior. \n 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. \n " + 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 @@ -12699,25 +16176,29 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -12728,43 +16209,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -12779,44 +16264,55 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. - \n Specifying the same filter multiple times is not supported - unless explicitly indicated in the filter. \n If an implementation - can not support a combination of filters, it must clearly + 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. \n Support: Core" + 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. + 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. \n Support: Implementation-specific \n This - filter can be used multiple times within the same rule." + 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. + 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 @@ -12838,32 +16334,44 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -12884,40 +16392,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -12939,60 +16467,68 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -13003,25 +16539,26 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -13038,32 +16575,44 @@ spec: - backendRef type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -13084,40 +16633,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -13139,29 +16708,32 @@ spec: 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: \n - 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. \n - Extended: Filter types and their - corresponding configuration defined by \"Support: Extended\" - in this package, e.g. \"RequestMirror\". Implementers - are encouraged to support extended filters. \n - 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. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n " + 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 @@ -13210,60 +16782,95 @@ spec: 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. \n For example, take the following matches configuration: - \n ``` matches: - method: service: foo.bar headers: values: - version: 2 - method: service: foo.bar.v2 ``` \n For a request - to match against this rule, it MUST satisfy EITHER of the - two conditions: \n - service of foo.bar AND contains the header - `version: 2` - service of foo.bar.v2 \n See the documentation - for GRPCRouteMatch on how to specify multiple match conditions - to be ANDed together. \n If no matches are specified, the - implementation MUST match every gRPC request. \n 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: \n * Characters in a matching non-wildcard hostname. * - Characters in a matching hostname. * Characters in a matching - service. * Characters in a matching method. * Header matches. - \n If ties still exist across multiple Routes, matching precedence - MUST be determined in order of the following criteria, continuing - on ties: \n * The oldest Route based on creation timestamp. - * The Route appearing first in alphabetical order by \"{namespace}/{name}\". - \n 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." + 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. \n For example, the match - below will match a gRPC request only if its service is `foo` - AND it contains the `version: v1` header: \n ``` matches: - - method: type: Exact service: \"foo\" headers: - name: - \"version\" value \"v1\" \n ```" + 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. + 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. + 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. \n 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." + 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|~]+$ @@ -13292,31 +16899,35 @@ spec: - 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. + 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. - \n At least one of Service and Method MUST be a - non-empty string." + 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. - \n At least one of Service and Method MUST be a - non-empty string." + 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) \n Support: Implementation-specific - (Exact with method specified but no service specified) - \n Support: Implementation-specific (RegularExpression)" + 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 @@ -13340,6 +16951,94 @@ spec: 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 @@ -13348,81 +17047,88 @@ spec: 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -13436,12 +17142,12 @@ 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. + --- + 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 @@ -13459,131 +17165,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -13602,9 +17327,7 @@ spec: type: object type: object served: true - storage: true - subresources: - status: {} + storage: false status: acceptedNames: kind: "" @@ -13619,8 +17342,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: httproutes.gateway.networking.k8s.io @@ -13645,20 +17368,26 @@ spec: name: v1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -13666,57 +17395,76 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: - \n * 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`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + 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`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n 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`. \n 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. \n 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. \n 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: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -13724,165 +17472,204 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -13923,81 +17710,101 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n 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. - \n 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. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + 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 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. + + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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 should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + 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: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -14019,35 +17826,45 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -14068,44 +17885,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -14127,64 +17961,68 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -14195,29 +18033,27 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -14233,84 +18069,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -14336,95 +18168,111 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * 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 well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -14445,44 +18293,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -14504,37 +18369,39 @@ spec: 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: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n 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. \n + 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 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` 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. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -14544,79 +18411,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -14714,25 +18578,29 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -14743,43 +18611,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -14794,46 +18666,67 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n 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 + description: |- + 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 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. \n Support: Core" + 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: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -14855,32 +18748,44 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -14901,40 +18806,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -14956,60 +18881,68 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -15020,25 +18953,26 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -15055,77 +18989,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -15151,88 +19088,110 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * 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 - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -15253,40 +19212,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -15308,33 +19287,39 @@ spec: 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: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + 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 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` 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -15344,73 +19329,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -15503,86 +19491,116 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n 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: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n 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. \n 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." + description: |- + Matches define conditions used for matching the rule against incoming + 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: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + 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 action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + 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 + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n 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. - \n 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: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, 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: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". 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. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n 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 determine the supported dialect." + 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 + determine the supported dialect. enum: - Exact - RegularExpression @@ -15603,9 +19621,12 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + Support: Extended enum: - GET - HEAD @@ -15621,15 +19642,18 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + Support: Core (Exact, PathPrefix) + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -15688,48 +19712,53 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n 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. \n 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 match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + 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 + match against the first value of the param if the data plane supports it, + 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 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + 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 + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -15752,39 +19781,145 @@ spec: 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)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + Support: Extended + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway 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. \n 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. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n 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. - \n 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. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -15842,81 +19977,88 @@ spec: description: Status defines the current state of HTTPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -15930,12 +20072,12 @@ 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. + --- + 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 @@ -15953,131 +20095,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -16098,7 +20259,7 @@ spec: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: @@ -16111,20 +20272,26 @@ spec: name: v1beta1 schema: openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes - the capability to match requests by hostname, path, header, or query param. - Filters can be used to specify additional processing steps. Backends specify - where matching requests should be routed. + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. 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' + 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' + 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 @@ -16132,57 +20299,76 @@ spec: description: Spec defines the desired state of HTTPRoute. properties: hostnames: - description: "Hostnames defines a set of hostnames that should match - against the HTTP Host header to select a HTTPRoute used to process - the request. Implementations MUST ignore any port value specified - in the HTTP Host header while performing a match and (absent of - any applicable header modification configuration) MUST forward this - header unmodified to the backend. \n Valid values for Hostnames - are determined by RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: - \n * 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`. + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + 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`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes - that have either not specified any hostnames or have specified at - least one hostname that matches the Listener hostname. For example, - `*.example.com`, `test.example.com`, and `foo.test.example.com` - would all match. On the other hand, `example.com` and `test.example.net` - would not match. \n 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`. \n 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. \n 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. \n 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: \n * Characters in a matching - non-wildcard hostname. * Characters in a matching hostname. \n If - ties exist across multiple Routes, the matching precedence rules - for HTTPRouteMatches takes over. \n Support: Core" + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -16190,165 +20376,204 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -16389,81 +20614,101 @@ spec: value: / description: Rules are a list of HTTP matchers, filters and actions. items: - description: HTTPRouteRule defines semantics for matching an HTTP - request based on conditions (matches), processing it (filters), - and forwarding the request to an API object (backendRefs). + description: |- + HTTPRouteRule defines semantics for matching an HTTP 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. \n Failure behavior here depends - on how many BackendRefs are specified and how many are invalid. - \n 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. \n - See the HTTPBackendRef definition for the rules about what - makes a single HTTPBackendRef invalid. \n 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. - \n 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. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Core" + 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 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. + + 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. \n Note that when a namespace different - than the local namespace is specified, a ReferenceGrant - object is required in the referent namespace to allow that + 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - " + 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 should be - executed if and only if the request is being forwarded - to the backend defined here. \n Support: Implementation-specific - (For broader support of filters, use the Filters field - in HTTPRouteRule.)" + description: |- + 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: - description: HTTPRouteFilter defines processing steps - that must be completed during the request or response - lifecycle. HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times - within the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -16485,35 +20730,45 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema - for a filter that modifies request headers. \n - Support: Core" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -16534,44 +20789,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -16593,64 +20865,68 @@ spec: 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. \n 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. \n Support: Extended" + 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. \n Mirrored - requests must be sent only to a single destination - endpoint within this BackendRef, irrespective - of how many endpoints are present within this - BackendRef. \n 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 + 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. - \n 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. \n In either error - case, the Message of the `ResolvedRefs` Condition - should be used to provide more detail about - the problem. \n Support: Extended for Kubernetes - Service \n Support: Implementation-specific - for any other resource" + + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with - a type other than ExternalName) \n Support: - Implementation-specific (Services with - type ExternalName)" + 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])?$ @@ -16661,29 +20937,27 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace - of the backend. When unspecified, the - local namespace is inferred. \n 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. \n Support: - Core" + 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. + 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 @@ -16699,84 +20973,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for - a filter that responds to the request with an - HTTP redirection. \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be - used in the value of the `Location` header - in the response. When empty, the hostname - in the `Host` header of the request is used. - \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to - modify the path of the incoming request. The - modified path is then used to construct the - `Location` header. When empty, the request - path is used as-is. \n Support: Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -16802,95 +21072,111 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in - the value of the `Location` header in the - response. \n If no port is specified, the - redirect port MUST be derived using the following - rules: \n * 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 well-known port, the listener port of the - Gateway SHOULD be used. * If redirect scheme - is empty, the redirect port MUST be the Gateway - Listener port. \n Implementations SHOULD NOT - add the port number in the 'Location' header - in the following cases: \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n Scheme redirects can affect the - port of the redirect, for more information, - refer to the documentation for the port field - of this filter. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. - \n Unknown values here must result in the - implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`. \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status - code to be used in response. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause - a crash. \n Unknown values here must result - in the implementation setting the Accepted - Condition for the Route to `status: False`, - with a Reason of `UnsupportedValue`. \n Support: - Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n - Support: Extended" + 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. \n Input: GET /foo HTTP/1.1 - my-header: foo \n Config: add: - name: \"my-header\" - value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 - my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -16911,44 +21197,61 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo - my-header2: bar my-header3: baz \n Config: - remove: [\"my-header1\", \"my-header3\"] \n - Output: GET /foo HTTP/1.1 my-header2: bar" + 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. \n Input: GET /foo HTTP/1.1 my-header: - foo \n Config: set: - name: \"my-header\" - value: \"bar\" \n Output: GET /foo HTTP/1.1 - my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -16970,37 +21273,39 @@ spec: 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: \n - - Core: Filter types and their corresponding configuration - defined by \"Support: Core\" in this package, - e.g. \"RequestHeaderModifier\". All implementations - must support core filters. \n - Extended: Filter - types and their corresponding configuration defined - by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged - to support extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged - to define custom implementation types to extend - the core API with implementation-specific behavior. - \n 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. \n + 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 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` 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. \n Unknown values here must result in - the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason - of `UnsupportedValue`." + 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -17010,79 +21315,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a - filter that modifies a request during forwarding. - \n Support: Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used - to replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n - Support: Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the - value with which to replace the full path + description: |- + ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies - the value with which to replace the prefix - match of a request during a rewrite or - redirect. For example, a request to \"/foo/bar\" - with a prefix match of \"/foo\" and a - ReplacePrefixMatch of \"/xyz\" would be - modified to \"/xyz/bar\". \n 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. - \n 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`. \n 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 | / | /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path - modifier. Additional types may be added - in a future release of the API. \n Note - that values may be added to this enum, - implementations must ensure that unknown - values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the - Route to `status: False`, with a Reason - of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -17180,25 +21482,29 @@ spec: <= 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -17209,43 +21515,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -17260,46 +21570,67 @@ spec: maxItems: 16 type: array filters: - description: "Filters define the filters that are applied to - requests that match this rule. \n The effects of ordering - of multiple behaviors are currently unspecified. This can - change in the future based on feedback during the alpha stage. - \n Conformance-levels at this level are defined based on the - type of filter: \n - 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. \n Specifying - the same filter multiple times is not supported unless explicitly - indicated in the filter. \n 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 + description: |- + 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 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. \n Support: Core" + 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: HTTPRouteFilter defines processing steps that - must be completed during the request or response lifecycle. - HTTPRouteFilters 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. + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters 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. \n This filter can be used multiple times within - the same rule. \n Support: Implementation-specific" + 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. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific 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. + 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 @@ -17321,32 +21652,44 @@ spec: - name type: object requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for - a filter that modifies request headers. \n Support: - Core" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -17367,40 +21710,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -17422,60 +21785,68 @@ spec: 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. \n 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. \n - Support: Extended" + 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. \n Mirrored requests - must be sent only to a single destination endpoint - within this BackendRef, irrespective of how many - endpoints are present within this BackendRef. \n - 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. \n 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. \n In either error case, the Message - of the `ResolvedRefs` Condition should be used to - provide more detail about the problem. \n Support: - Extended for Kubernetes Service \n Support: Implementation-specific - for any other resource" + 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. + 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\". - \n Defaults to \"Service\" when not specified. - \n 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. \n Support: Core (Services with a - type other than ExternalName) \n Support: Implementation-specific - (Services with type ExternalName)" + 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])?$ @@ -17486,25 +21857,26 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the - backend. When unspecified, the local namespace - is inferred. \n 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. \n Support: Core" + 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 + 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 @@ -17521,77 +21893,80 @@ spec: - backendRef type: object requestRedirect: - description: "RequestRedirect defines a schema for a filter - that responds to the request with an HTTP redirection. - \n Support: Core" + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core properties: hostname: - description: "Hostname is the hostname to be used - in the value of the `Location` header in the response. - When empty, the hostname in the `Host` header of - the request is used. \n Support: Core" + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + 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 path: - description: "Path defines parameters used to modify - the path of the incoming request. The modified path - is then used to construct the `Location` header. - When empty, the request path is used as-is. \n Support: - Extended" + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -17617,88 +21992,110 @@ spec: rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' port: - description: "Port is the port to be used in the value - of the `Location` header in the response. \n If - no port is specified, the redirect port MUST be - derived using the following rules: \n * 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 - well-known port, the listener port of the Gateway - SHOULD be used. * If redirect scheme is empty, the - redirect port MUST be the Gateway Listener port. - \n Implementations SHOULD NOT add the port number - in the 'Location' header in the following cases: - \n * 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. \n Support: Extended" + description: |- + 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 + well-known port, the listener port of the Gateway SHOULD be used. + * 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 minimum: 1 type: integer scheme: - description: "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. \n - Scheme redirects can affect the port of the redirect, - for more information, refer to the documentation - for the port field of this filter. \n Note that - values may be added to this enum, implementations - must ensure that unknown values will not cause a - crash. \n Unknown values here must result in the - implementation setting the Accepted Condition for - the Route to `status: False`, with a Reason of `UnsupportedValue`. - \n Support: Extended" + description: |- + 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 - https type: string statusCode: default: 302 - description: "StatusCode is the HTTP status code to - be used in response. \n Note that values may be - added to this enum, implementations must ensure - that unknown values will not cause a crash. \n Unknown - values here must result in the implementation setting - the Accepted Condition for the Route to `status: - False`, with a Reason of `UnsupportedValue`. \n - Support: Core" + 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 - 302 type: integer type: object responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema - for a filter that modifies response headers. \n Support: - Extended" + 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. \n Input: GET /foo HTTP/1.1 my-header: foo - \n Config: add: - name: \"my-header\" value: \"bar,baz\" - \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + 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). - \n 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." + 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|~]+$ @@ -17719,40 +22116,60 @@ spec: - 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). - \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: - bar my-header3: baz \n Config: remove: [\"my-header1\", - \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: - bar" + 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. \n - Input: GET /foo HTTP/1.1 my-header: foo \n Config: - set: - name: \"my-header\" value: \"bar\" \n Output: - GET /foo HTTP/1.1 my-header: bar" + 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). - \n 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." + 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|~]+$ @@ -17774,33 +22191,39 @@ spec: 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: \n - Core: Filter types and - their corresponding configuration defined by \"Support: - Core\" in this package, e.g. \"RequestHeaderModifier\". - All implementations must support core filters. \n - - Extended: Filter types and their corresponding configuration - defined by \"Support: Extended\" in this package, e.g. - \"RequestMirror\". Implementers are encouraged to support - extended filters. \n - 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` should be set to \"ExtensionRef\" - for custom filters. \n Implementers are encouraged to - define custom implementation types to extend the core - API with implementation-specific behavior. \n 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. \n Note that values may be added to this enum, - implementations must ensure that unknown values will - not cause a crash. \n Unknown values here must result - in the implementation setting the Accepted Condition - for the Route to `status: False`, with a Reason of `UnsupportedValue`." + 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 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` 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`. enum: - RequestHeaderModifier - ResponseHeaderModifier @@ -17810,73 +22233,76 @@ spec: - ExtensionRef type: string urlRewrite: - description: "URLRewrite defines a schema for a filter - that modifies a request during forwarding. \n Support: - Extended" + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended properties: hostname: - description: "Hostname is the value to be used to - replace the Host header value during forwarding. - \n Support: Extended" + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + 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 path: - description: "Path defines a path rewrite. \n Support: - Extended" + description: |- + Path defines a path rewrite. + + Support: Extended properties: replaceFullPath: - description: ReplaceFullPath specifies the value - with which to replace the full path of a request - during a rewrite or redirect. + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. maxLength: 1024 type: string replacePrefixMatch: - description: "ReplacePrefixMatch specifies the - value with which to replace the prefix match - of a request during a rewrite or redirect. For - example, a request to \"/foo/bar\" with a prefix - match of \"/foo\" and a ReplacePrefixMatch of - \"/xyz\" would be modified to \"/xyz/bar\". - \n 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. \n 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`. \n 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 | / | - /" + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + 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: - description: "Type defines the type of path modifier. - Additional types may be added in a future release - of the API. \n Note that values may be added - to this enum, implementations must ensure that - unknown values will not cause a crash. \n Unknown - values here must result in the implementation - setting the Accepted Condition for the Route - to `status: False`, with a Reason of `UnsupportedValue`." + description: |- + 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`. enum: - ReplaceFullPath - ReplacePrefixMatch @@ -17969,86 +22395,116 @@ spec: - path: type: PathPrefix value: / - description: "Matches define conditions used for matching the - rule against incoming HTTP requests. Each match is independent, - i.e. this rule will be matched if **any** one of the matches - is satisfied. \n For example, take the following matches configuration: - \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" - value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request - to match against this rule, a request must satisfy EITHER - of the two conditions: \n - path prefixed with `/foo` AND - contains the header `version: v2` - path prefix of `/v2/foo` - \n See the documentation for HTTPRouteMatch on how to specify - multiple match conditions that should be ANDed together. \n - If no matches are specified, the default is a prefix path - match on \"/\", which has the effect of matching every HTTP - request. \n 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: - \n * \"Exact\" path match. * \"Prefix\" path match with largest - number of characters. * Method match. * Largest number of - header matches. * Largest number of query param matches. \n - Note: The precedence of RegularExpression path matches are - implementation-specific. \n If ties still exist across multiple - Routes, matching precedence MUST be determined in order of - the following criteria, continuing on ties: \n * The oldest - Route based on creation timestamp. * The Route appearing first - in alphabetical order by \"{namespace}/{name}\". \n 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. \n 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." + description: |- + Matches define conditions used for matching the rule against incoming + 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: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + 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 action. Multiple match types are - ANDed together, i.e. the match will evaluate to true only - if all conditions are satisfied. \n For example, the match - below will match a HTTP request only if its path starts - with `/foo` AND it contains the `version: v1` header: \n - ``` match: \n path: value: \"/foo\" headers: - name: \"version\" - value \"v1\" \n ```" + 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 + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n\n```" properties: headers: - description: Headers specifies HTTP request header matchers. - Multiple match values are ANDed together, meaning, a - request must match all the specified headers to select - the route. + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. items: - description: HTTPHeaderMatch describes how to select - a HTTP route by matching HTTP request headers. + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. 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). - \n 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. - \n 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: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 - regarding processing a repeated header, with special - handling for \"Set-Cookie\"." + 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, 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: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". 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. \n Support: Core (Exact) - \n Support: Implementation-specific (RegularExpression) - \n 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 determine the supported dialect." + 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 + determine the supported dialect. enum: - Exact - RegularExpression @@ -18069,9 +22525,12 @@ spec: - name x-kubernetes-list-type: map method: - description: "Method specifies HTTP method matcher. When - specified, this route will be matched only if the request - has the specified method. \n Support: Extended" + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + Support: Extended enum: - GET - HEAD @@ -18087,15 +22546,18 @@ spec: default: type: PathPrefix value: / - description: Path specifies a HTTP request path matcher. - If this field is not specified, a default prefix match - on the "/" path is provided. + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. properties: type: default: PathPrefix - description: "Type specifies how to match against - the path Value. \n Support: Core (Exact, PathPrefix) - \n Support: Implementation-specific (RegularExpression)" + description: |- + Type specifies how to match against the path Value. + + Support: Core (Exact, PathPrefix) + + Support: Implementation-specific (RegularExpression) enum: - Exact - PathPrefix @@ -18154,48 +22616,53 @@ spec: rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' queryParams: - description: "QueryParams specifies HTTP query parameter - matchers. Multiple match values are ANDed together, - meaning, a request must match all the specified query - parameters to select the route. \n Support: Extended" + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + Support: Extended items: - description: HTTPQueryParamMatch describes how to select - a HTTP route by matching HTTP query parameters. + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. properties: name: - description: "Name is the name of the HTTP query - param to be matched. This must be an exact string - match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). - \n 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. \n 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 match against the first - value of the param if the data plane supports - it, as this behavior is expected in other load - balancing contexts outside of the Gateway API. - \n Users SHOULD NOT route traffic based on repeated - query params to guard themselves against potential - differences in the implementations." + description: |- + Name is the name of the HTTP query param to be matched. This must be an + 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 + match against the first value of the param if the data plane supports it, + 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 minLength: 1 pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string type: default: Exact - description: "Type specifies how to match against - the value of the query parameter. \n Support: - Extended (Exact) \n Support: Implementation-specific - (RegularExpression) \n Since RegularExpression - QueryParamMatchType has Implementation-specific - conformance, implementations can support POSIX, - PCRE or any other dialects of regular expressions. - Please read the implementation's documentation - to determine the supported dialect." + 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 + documentation to determine the supported dialect. enum: - Exact - RegularExpression @@ -18218,39 +22685,145 @@ spec: 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)' timeouts: - description: "Timeouts defines the timeouts that can be configured - for an HTTP request. \n Support: Extended \n " + description: |+ + Timeouts defines the timeouts that can be configured for an HTTP request. + + Support: Extended + properties: backendRequest: - description: "BackendRequest specifies a timeout for an - individual request from the gateway 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. \n 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. - \n Because the Request timeout encompasses the BackendRequest - timeout, the value of BackendRequest must be <= the value - of Request timeout. \n Support: Extended" + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string request: - description: "Request specifies the maximum duration for - a gateway to respond to an HTTP request. If the gateway - has not been able to respond before this deadline is met, - the gateway MUST return a timeout error. \n 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. - \n 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. \n When this - field is unspecified, request timeout behavior is implementation-specific. - \n Support: Extended" + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + 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. + + Support: Extended pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object @@ -18308,81 +22881,88 @@ spec: description: Status defines the current state of HTTPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -18396,12 +22976,12 @@ 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. + --- + 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 @@ -18419,131 +22999,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -18564,7 +23163,7 @@ spec: - spec type: object served: true - storage: true + storage: false subresources: status: {} status: @@ -18581,8 +23180,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: referencegrants.gateway.networking.k8s.io @@ -18609,32 +23208,42 @@ spec: 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. \n 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. \n 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. \n 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." + 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' + 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' + 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 @@ -18642,35 +23251,52 @@ 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. \n Support: Core" + 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. \n Support: Core" + 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. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + 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. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -18684,35 +23310,44 @@ spec: 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. - \n Support: Core" + 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. + 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. \n Support: Core" + 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: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + 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. + 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 @@ -18738,28 +23373,38 @@ spec: name: v1beta1 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. \n 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. \n All cross-namespace references in Gateway API - (with the exception of cross-namespace Gateway-route attachment) require - a ReferenceGrant. \n 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." + 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. + + 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 + 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' + 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' + 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 @@ -18767,35 +23412,52 @@ 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. \n Support: Core" + 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. \n Support: Core" + 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. \n When - used to permit a SecretObjectReference: \n * Gateway \n When - used to permit a BackendObjectReference: \n * GRPCRoute * - HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + 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. \n - Support: Core" + description: |- + Namespace is the namespace of the referent. + + Support: Core maxLength: 63 minLength: 1 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -18809,35 +23471,44 @@ spec: 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. - \n Support: Core" + 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. + 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. \n Support: Core" + 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: \n * Secret - when used to permit a SecretObjectReference * Service when - used to permit a BackendObjectReference" + 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. + 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 @@ -18870,8 +23541,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tcproutes.gateway.networking.k8s.io @@ -18893,19 +23564,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: TCPRoute provides a way to route TCP requests. When combined - with a Gateway listener, it can be used to forward connections on the port - specified by the listener to a set of backends specified by the TCPRoute. + description: |- + TCPRoute provides a way to route TCP requests. When combined with a Gateway + listener, it can be used to forward connections on the port specified by the + listener to a set of backends specified by the TCPRoute. 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' + 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' + 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 @@ -18913,165 +23590,204 @@ spec: description: Spec defines the desired state of TCPRoute. properties: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -19110,62 +23826,78 @@ spec: description: TCPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Connection rejections must respect - weight; if an invalid backend is requested to have 80% of + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Connection rejections must + respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead. - \n Support: Core for Kubernetes Service \n Support: Extended - for Kubernetes ServiceImport \n Support: Implementation-specific - for any other resource \n Support for weight: Extended" + + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -19176,43 +23908,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -19238,81 +23974,88 @@ spec: description: Status defines the current state of TCPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -19326,12 +24069,12 @@ 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. + --- + 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 @@ -19349,131 +24092,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -19511,8 +24273,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tlsroutes.gateway.networking.k8s.io @@ -19534,21 +24296,28 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: "The TLSRoute resource is similar to TCPRoute, but can be configured - to match against TLS-specific metadata. This allows more flexibility in - matching streams for a given TLS listener. \n 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." + description: |- + The TLSRoute resource is similar to TCPRoute, but can be configured + 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: 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' + 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' + 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 @@ -19556,43 +24325,56 @@ spec: description: Spec defines the desired state of TLSRoute. properties: hostnames: - description: "Hostnames defines a set of SNI names that should match - against the SNI attribute of TLS ClientHello message in TLS handshake. - This matches the RFC 1123 definition of a hostname with 2 notable - exceptions: \n 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. \n 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: \n * 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`. * A Listener with `*.example.com` as the hostname - matches TLSRoutes 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. \n 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. \n 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. \n Support: Core" + description: |- + Hostnames defines a set of SNI names that should match against the + 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`. + * A Listener with `*.example.com` as the hostname matches TLSRoutes + 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. + + 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: \n 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. \n 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`). - \n 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." + 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])?)*$ @@ -19600,165 +24382,204 @@ spec: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -19797,65 +24618,81 @@ spec: description: TLSRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the rule performs no forwarding; if no filters are specified - that would result in a response being sent, the underlying - implementation must actively reject request attempts to this - backend, by rejecting the connection or returning a 500 status - code. Request rejections must respect weight; if an invalid - backend is requested to have 80% of requests, then 80% of - requests must be rejected instead. \n Support: Core for Kubernetes - Service \n Support: Extended for Kubernetes ServiceImport - \n Support: Implementation-specific for any other resource - \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or + a Service with no endpoints), the rule performs no forwarding; if no + filters are specified that would result in a response being sent, the + underlying implementation must actively reject request attempts to this + backend, by rejecting the connection or returning a 500 status code. + Request rejections must respect weight; if an invalid backend is + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -19866,43 +24703,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -19928,81 +24769,88 @@ spec: description: Status defines the current state of TLSRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -20016,12 +24864,12 @@ 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. + --- + 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 @@ -20039,131 +24887,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ @@ -20201,8 +25068,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2997 + gateway.networking.k8s.io/bundle-version: v1.1.0 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: udproutes.gateway.networking.k8s.io @@ -20224,19 +25091,25 @@ spec: name: v1alpha2 schema: openAPIV3Schema: - description: UDPRoute provides a way to route UDP traffic. When combined with - a Gateway listener, it can be used to forward traffic on the port specified - by the listener to a set of backends specified by the UDPRoute. + description: |- + UDPRoute provides a way to route UDP traffic. When combined with a Gateway + listener, it can be used to forward traffic on the port specified by the + listener to a set of backends specified by the UDPRoute. 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' + 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' + 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 @@ -20244,165 +25117,204 @@ spec: description: Spec defines the desired state of UDPRoute. properties: 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. \n There are two kinds of parent resources with \"Core\" - support: \n * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services only) This - API may be extended in the future to support additional kinds of - parent resources. \n ParentRefs must be _distinct_. This means either - that: \n * 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. - \n Some examples: \n * If one ParentRef sets `sectionName`, all - ParentRefs referencing the same object must also set `sectionName`. + 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`. \n 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. \n Note that - for ParentRefs that cross namespace boundaries, there are specific + 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. \n 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. \n 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. \n " + 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: \n * Gateway (Gateway conformance profile) * Service - (Mesh conformance profile, experimental, ClusterIP Services only) - \n This API may be extended in the future to support additional - kinds of parent resources. \n 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." + 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). \n Support: - Core" + 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. \n There are two - kinds of parent resources with \"Core\" support: \n * Gateway - (Gateway conformance profile) * Service (Mesh conformance - profile, experimental, ClusterIP Services only) \n Support - for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. - \n 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 + 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. - \n 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. - \n 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. \n Support: Core" + + 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. \n 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. \n 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. \n Implementations MAY choose to support other parent - resources. Implementations supporting other types of parent - resources MUST clearly document how/if Port is interpreted. - \n 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. \n - Support: Extended \n " + 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: \n * 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. Note that attaching - Routes to Services as Parents is part of experimental Mesh - support and is not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. \n Support: Core" + 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])?)*$ @@ -20441,62 +25353,78 @@ spec: description: UDPRouteRule is the configuration for a given rule. properties: backendRefs: - description: "BackendRefs defines the backend(s) where matching - requests should be sent. If unspecified or invalid (refers - to a non-existent resource or a Service with no endpoints), - the underlying implementation MUST actively reject connection - attempts to this backend. Packet drops must respect weight; - if an invalid backend is requested to have 80% of the packets, - then 80% of packets must be dropped instead. \n Support: Core - for Kubernetes Service \n Support: Extended for Kubernetes - ServiceImport \n Support: Implementation-specific for any - other resource \n Support for weight: Extended" + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. If unspecified or invalid (refers to a non-existent resource or a + Service with no endpoints), the underlying implementation MUST actively + reject connection attempts to this backend. Packet drops must + 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. \n 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. \n - \n When the BackendRef points to a Kubernetes Service, implementations - SHOULD honor the appProtocol field if it is set for the - target Service Port. \n Implementations supporting appProtocol - SHOULD recognize the Kubernetes Standard Application Protocols - defined in KEP-3726. \n 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. \n 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. \n - \n 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." + 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. 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. + 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\". \n Defaults to - \"Service\" when not specified. \n 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. - \n Support: Core (Services with a type other than ExternalName) - \n Support: Implementation-specific (Services with type - ExternalName)" + 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])?$ @@ -20507,43 +25435,47 @@ spec: minLength: 1 type: string namespace: - description: "Namespace is the namespace of the backend. - When unspecified, the local namespace is inferred. \n - 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. \n Support: Core" + 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. + 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. \n - 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. \n Support for this field varies based - on the context where used." + 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 @@ -20569,81 +25501,88 @@ spec: description: Status defines the current state of UDPRoute. 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. - \n 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. \n A maximum of 32 Gateways will be represented - in this list. An empty list means the route has not been attached - to any Gateway." + 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. + 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. \n 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. \n A Route MUST be considered \"Accepted\" - if at least one of the Route's rules is implemented by the - Gateway. \n There are a number of cases where the \"Accepted\" - condition may not be set due to lack of controller visibility, - that includes when: \n * 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." + 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. --- This struct + 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 type FooStatus struct{ - // Represents the observations of a foo's current state. - // Known .status.conditions.type are: \"Available\", \"Progressing\", - and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields - }" + .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. + 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. + 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. + 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. + 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_])?$ @@ -20657,12 +25596,12 @@ 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. + --- + 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 @@ -20680,131 +25619,150 @@ spec: - 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. \n Example: - \"example.net/gateway-controller\". \n 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). - \n 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." + 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. + 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). \n - Support: Core" + 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. \n There are - two kinds of parent resources with \"Core\" support: \n - * Gateway (Gateway conformance profile) * Service (Mesh - conformance profile, experimental, ClusterIP Services - only) \n Support for other resources is Implementation-Specific." + 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. \n Support: - Core" + 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. \n 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. \n 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. \n 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. \n Support: - Core" + 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. \n 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. \n 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. \n Implementations MAY choose - to support other parent resources. Implementations supporting - other types of parent resources MUST clearly document - how/if Port is interpreted. \n 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, + 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. - \n Support: Extended \n " + + 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: \n * 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. Note that attaching Routes to Services - as Parents is part of experimental Mesh support and is - not supported for any other purpose. \n Implementations - MAY choose to support attaching Routes to other resources. - If that is the case, they MUST clearly document how SectionName - is interpreted. \n 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. - \n Support: Core" + 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])?)*$ diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 1246f04d59a..37d07cbd3bd 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -223,7 +223,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourconfigurations.projectcontour.io spec: preserveUnknownFields: false @@ -340,6 +340,12 @@ spec: defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -820,9 +826,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -1092,6 +1098,8 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -1114,6 +1122,9 @@ spec: the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -1207,10 +1218,14 @@ spec: descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -1363,6 +1378,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -1493,12 +1510,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 @@ -1580,7 +1592,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: contourdeployments.projectcontour.io spec: preserveUnknownFields: false @@ -1645,9 +1657,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: @@ -1814,6 +1823,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 @@ -1896,12 +1911,8 @@ spec: use to replace existing DaemonSet pods with new pods. 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: @@ -1972,9 +1983,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: @@ -2034,6 +2042,8 @@ spec: to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). type: string name: description: This must match the Name of a Volume. @@ -2043,6 +2053,21 @@ spec: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. type: boolean + recursiveReadOnly: + description: |- + 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 + field is set to Enabled, the mount is made recursively read-only if it is + 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: description: |- Path within the volume from which the container's volume should be mounted. @@ -2078,7 +2103,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: |- @@ -2118,6 +2142,7 @@ spec: 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. @@ -2131,6 +2156,7 @@ spec: to shared' type: string readOnly: + default: false description: |- readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -2170,6 +2196,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic path: description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' @@ -2191,10 +2218,13 @@ spec: More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2230,10 +2260,13 @@ spec: to OpenStack. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2298,11 +2331,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the ConfigMap @@ -2335,10 +2372,13 @@ spec: secret object contains more than one secret, all secret references are passed. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2382,8 +2422,8 @@ spec: properties: fieldRef: description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' + pod: only annotations, labels, name, namespace + and uid are supported.' properties: apiVersion: description: Version of the schema the FieldPath @@ -2442,6 +2482,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object emptyDir: description: |- @@ -2533,6 +2574,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -2677,11 +2719,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2709,8 +2753,8 @@ spec: If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be 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/persistent-volumes#volumeattributesclass - (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default). type: string volumeMode: description: |- @@ -2736,7 +2780,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 lun number' @@ -2753,6 +2796,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic wwids: description: |- wwids Optional: FC volume world wide identifiers (wwids) @@ -2760,6 +2804,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object flexVolume: description: |- @@ -2796,10 +2841,13 @@ spec: scripts. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -2833,7 +2881,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: |- @@ -2914,9 +2961,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: |- @@ -2933,6 +2977,39 @@ 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 @@ -2953,7 +3030,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: |- @@ -2965,6 +3041,7 @@ spec: description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: + default: default description: |- iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). @@ -2980,6 +3057,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic readOnly: description: |- readOnly here will force the ReadOnly setting in VolumeMounts. @@ -2990,10 +3068,13 @@ spec: target and initiator authentication properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3112,10 +3193,13 @@ 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: |- @@ -3164,11 +3248,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3247,11 +3333,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional specify whether the @@ -3274,7 +3364,7 @@ spec: fieldRef: description: 'Required: Selects a field of the pod: only annotations, labels, - name and namespace are supported.' + name, namespace and uid are supported.' properties: apiVersion: description: Version of the schema @@ -3338,6 +3428,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object secret: description: secret information about the secret @@ -3381,11 +3472,15 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: optional field specify whether @@ -3424,6 +3519,7 @@ spec: type: object type: object type: array + x-kubernetes-list-type: atomic type: object quobyte: description: quobyte represents a Quobyte mount on the host @@ -3474,7 +3570,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: |- @@ -3482,6 +3577,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. @@ -3494,7 +3590,9 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -3514,14 +3612,18 @@ spec: More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -3536,6 +3638,7 @@ spec: attached and mounted on Kubernetes nodes. properties: fsType: + default: xfs description: |- fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. @@ -3561,10 +3664,13 @@ spec: sensitive information. If this is not provided, Login operation will fail. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3573,6 +3679,7 @@ spec: with Gateway, default false type: boolean storageMode: + default: ThinProvisioned description: |- storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. @@ -3649,6 +3756,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic optional: description: optional field specify whether the Secret or its keys must be defined @@ -3680,10 +3788,13 @@ spec: credentials. If not specified, default values will be attempted. properties: name: + default: "" description: |- Name of the referent. + 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. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object x-kubernetes-map-type: atomic @@ -3897,6 +4008,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 @@ -4025,6 +4142,12 @@ spec: Service; defaults to 3. format: int32 type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer type: object dnsLookupFamily: description: |- @@ -4505,9 +4628,9 @@ spec: description: |- FeatureFlags defines toggle to enable new contour features. Available toggles are: - useEndpointSlices - configures contour to fetch endpoint data - from k8s endpoint slices. defaults to false and reading endpoint - data from the k8s endpoints. + useEndpointSlices - Configures contour to fetch endpoint data + from k8s endpoint slices. defaults to true, + If false then reads endpoint data from the k8s endpoints. items: type: string type: array @@ -4778,6 +4901,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -4800,6 +4925,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -4893,10 +5021,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -5050,6 +5182,8 @@ spec: Defines the XDSServer to use for `contour serve`. Values: `envoy` (default), `contour (deprecated)`. Other values will produce an error. + Deprecated: this field will be removed in a future release when + the `contour` xDS server implementation is removed. type: string type: object type: object @@ -5062,16 +5196,8 @@ spec: description: Conditions describe the current conditions of the ContourDeployment resource. 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: |- @@ -5112,12 +5238,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 @@ -5143,7 +5264,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: extensionservices.projectcontour.io spec: preserveUnknownFields: false @@ -5188,6 +5309,39 @@ spec: description: ExtensionServiceSpec defines the desired state of an ExtensionService resource. properties: + circuitBreakerPolicy: + description: |- + CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. + If defined this overrides the global circuit breaker budget. + properties: + maxConnections: + description: The maximum number of connections that a single Envoy + instance allows to the Kubernetes Service; defaults to 1024. + format: int32 + type: integer + maxPendingRequests: + description: The maximum number of pending requests that a single + Envoy instance allows to the Kubernetes Service; defaults to + 1024. + format: int32 + type: integer + maxRequests: + description: The maximum parallel requests a single Envoy instance + allows to the Kubernetes Service; defaults to 1024 + format: int32 + type: integer + maxRetries: + description: The maximum number of parallel retries a single Envoy + instance allows to the Kubernetes Service; defaults to 3. + format: int32 + type: integer + perHostMaxConnections: + description: |- + PerHostMaxConnections is the maximum number of connections + that Envoy will allow to each individual host in a cluster. + format: int32 + type: integer + type: object loadBalancerPolicy: description: |- The policy for load balancing GRPC service requests. Note that the @@ -5225,6 +5379,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -5239,6 +5395,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -5506,12 +5664,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 @@ -5591,7 +5744,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: httpproxies.projectcontour.io spec: preserveUnknownFields: false @@ -6283,6 +6436,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -6297,6 +6452,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -6397,6 +6554,8 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -6420,6 +6579,9 @@ spec: the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -6513,10 +6675,14 @@ spec: of the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -7161,6 +7327,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - headerName type: object queryParameterHashOptions: description: |- @@ -7175,6 +7343,8 @@ spec: request, no hash will be produced. minLength: 1 type: string + required: + - parameterName type: object terminal: description: |- @@ -7841,6 +8011,8 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object remoteAddress: description: |- @@ -7863,6 +8035,9 @@ spec: of the header to look for on the request. minLength: 1 type: string + required: + - descriptorKey + - headerName type: object requestHeaderValueMatch: description: |- @@ -7956,10 +8131,14 @@ spec: the descriptor entry. minLength: 1 type: string + required: + - value type: object type: object minItems: 1 type: array + required: + - entries type: object minItems: 1 type: array @@ -8298,12 +8477,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 @@ -8422,8 +8596,6 @@ spec: CamelCase names - cloud provider specific error values must have names that comply with the format foo.example.com/CamelCase. - --- - 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 @@ -8433,12 +8605,12 @@ spec: format: int32 type: integer protocol: - default: TCP description: |- Protocol is the protocol of the service port of which status is recorded here The supported values are: "TCP", "UDP", "SCTP" type: string required: + - error - port - protocol type: object @@ -8446,6 +8618,7 @@ spec: x-kubernetes-list-type: atomic type: object type: array + x-kubernetes-list-type: atomic type: object type: object required: @@ -8461,7 +8634,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.4 name: tlscertificatedelegations.projectcontour.io spec: preserveUnknownFields: false @@ -8662,12 +8835,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 @@ -9031,9 +9199,6 @@ spec: app: contour template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8000" labels: app: contour spec: @@ -9132,10 +9297,6 @@ spec: app: envoy template: metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8002" - prometheus.io/path: "/stats/prometheus" labels: app: envoy spec: @@ -9166,7 +9327,7 @@ spec: - --log-level info command: - envoy - image: docker.io/envoyproxy/envoy:v1.29.2 + image: docker.io/envoyproxy/envoy:v1.32.0 imagePullPolicy: IfNotPresent name: envoy env: @@ -9189,6 +9350,10 @@ spec: hostPort: 443 name: https protocol: TCP + - containerPort: 8002 + hostPort: 8002 + name: metrics + protocol: TCP readinessProbe: httpGet: path: /ready diff --git a/go.mod b/go.mod index 0b10daa570e..a04f443d534 100644 --- a/go.mod +++ b/go.mod @@ -3,77 +3,79 @@ module github.com/projectcontour/contour go 1.22.0 require ( - dario.cat/mergo v1.0.0 - github.com/Masterminds/semver/v3 v3.2.1 + dario.cat/mergo v1.0.1 + github.com/Masterminds/semver/v3 v3.3.0 github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 github.com/alecthomas/kingpin/v2 v2.4.0 github.com/bombsimon/logrusr/v4 v4.1.0 - github.com/cert-manager/cert-manager v1.14.4 + github.com/cert-manager/cert-manager v1.16.1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc - github.com/distribution/reference v0.5.0 - github.com/envoyproxy/go-control-plane v0.12.1-0.20240111020705-5401a878d8bb - github.com/go-logr/logr v1.4.1 + github.com/distribution/reference v0.6.0 + github.com/envoyproxy/go-control-plane v0.13.1 + github.com/go-logr/logr v1.4.2 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v48 v48.2.0 github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 - github.com/onsi/ginkgo/v2 v2.17.1 - github.com/onsi/gomega v1.32.0 + github.com/onsi/ginkgo/v2 v2.20.2 + github.com/onsi/gomega v1.34.2 + github.com/pkg/errors v0.9.1 github.com/projectcontour/yages v0.1.0 - github.com/prometheus/client_golang v1.19.0 - github.com/prometheus/client_model v0.6.0 - github.com/prometheus/common v0.51.1 + github.com/prometheus/client_golang v1.20.5 + github.com/prometheus/client_model v0.6.1 + github.com/prometheus/common v0.60.1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 - github.com/tsaarni/certyaml v0.9.3 - github.com/vektra/mockery/v2 v2.42.1 - go.uber.org/automaxprocs v1.5.3 - golang.org/x/oauth2 v0.18.0 - gonum.org/v1/plot v0.14.0 - google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 - google.golang.org/grpc v1.62.1 - google.golang.org/protobuf v1.33.0 + github.com/tsaarni/certyaml v0.10.0 + github.com/vektra/mockery/v2 v2.46.0 + go.uber.org/automaxprocs v1.6.0 + golang.org/x/net v0.30.0 + golang.org/x/oauth2 v0.23.0 + gonum.org/v1/plot v0.15.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 + google.golang.org/grpc v1.67.1 + google.golang.org/protobuf v1.35.1 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.29.3 - k8s.io/apiextensions-apiserver v0.29.3 - k8s.io/apimachinery v0.29.3 - k8s.io/client-go v0.29.3 - k8s.io/klog/v2 v2.120.1 - k8s.io/utils v0.0.0-20240102154912-e7106e64919e - sigs.k8s.io/controller-runtime v0.17.2 - sigs.k8s.io/controller-tools v0.14.0 - sigs.k8s.io/gateway-api v1.0.0 - sigs.k8s.io/kustomize/kyaml v0.16.0 - sigs.k8s.io/yaml v1.4.0 + k8s.io/api v0.31.2 + k8s.io/apiextensions-apiserver v0.31.2 + k8s.io/apimachinery v0.31.2 + k8s.io/client-go v0.31.2 + k8s.io/klog/v2 v2.130.1 + k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 + sigs.k8s.io/controller-runtime v0.19.0 + sigs.k8s.io/controller-tools v0.16.4 + sigs.k8s.io/gateway-api v1.1.0 + sigs.k8s.io/kustomize/kyaml v0.17.2 ) require ( - git.sr.ht/~sbinet/gg v0.5.0 // indirect + cel.dev/expr v0.16.0 // indirect + git.sr.ht/~sbinet/gg v0.6.0 // indirect github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/campoy/embedmd v1.0.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chigopher/pathlib v0.19.1 // indirect - github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect - github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.8.0 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.6 // indirect github.com/go-errors/errors v1.4.2 // indirect - github.com/go-fonts/liberation v0.3.1 // indirect - github.com/go-latex/latex v0.0.0-20230307184459-12ec69307ad9 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect - github.com/go-openapi/swag v0.22.7 // indirect - github.com/go-pdf/fpdf v0.8.0 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/gobuffalo/flect v1.0.2 // indirect + github.com/go-fonts/liberation v0.3.3 // indirect + github.com/go-latex/latex v0.0.0-20240709081214-31cef3c7570e // 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-pdf/fpdf v0.9.0 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/gobuffalo/flect v1.0.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -81,8 +83,8 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect @@ -91,55 +93,57 @@ require ( github.com/jinzhu/copier v0.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.9 // 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/miekg/dns v1.1.62 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/spdystream 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/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/pelletier/go-toml/v2 v2.0.6 // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/rs/zerolog v1.29.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/tsaarni/x500dn v1.0.0 // indirect + github.com/x448/float16 v0.8.4 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect - golang.org/x/image v0.11.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/image v0.21.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/time v0.6.0 // indirect + golang.org/x/tools v0.26.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // 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.29.3 // indirect k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect k8s.io/klog v1.0.0 // indirect - k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 // indirect + k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 6d0ba7a6b48..8ca5803043d 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +cel.dev/expr v0.16.0 h1:yloc84fytn4zmJX2GU3TkXGsaieaV7dQ057Qs4sIG2Y= +cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= 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= @@ -35,17 +37,17 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl 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.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= git.sr.ht/~sbinet/cmpimg v0.1.0 h1:E0zPRk2muWuCqSKSVZIWsgtU9pjsw3eKHi8VmQeScxo= git.sr.ht/~sbinet/cmpimg v0.1.0/go.mod h1:FU12psLbF4TfNXkKH2ZZQ29crIqoiqTZmeQ7dkp/pxE= -git.sr.ht/~sbinet/gg v0.5.0 h1:6V43j30HM623V329xA9Ntq+WJrMjDxRjuAB1LFWF5m8= -git.sr.ht/~sbinet/gg v0.5.0/go.mod h1:G2C0eRESqlKhS7ErsNey6HHrqU1PwsnCQlekFi9Q2Oo= +git.sr.ht/~sbinet/gg v0.6.0 h1:RIzgkizAk+9r7uPzf/VfbJHBMKUr0F5hRFxTUGMnt38= +git.sr.ht/~sbinet/gg v0.6.0/go.mod h1:uucygbfC9wVPQIfrmwM2et0imr8L7KQWywX0xpFMm94= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/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/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 h1:+XfOU14S4bGuwyvCijJwhhBIjYN+YXS18jrCY2EzJaY= github.com/ahmetb/gen-crd-api-reference-docs v0.3.0/go.mod h1:TdjdkYhlOifCQWPs1UdTma97kQQMozf5h26hTuG70u8= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= @@ -68,10 +70,10 @@ github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cert-manager/cert-manager v1.14.4 h1:DLXIZHx3jhkViYfobXo+N7/od/oj4YgG6AJw4ORJnYs= -github.com/cert-manager/cert-manager v1.14.4/go.mod h1:d+CBeRu5MbpHTfXkkiiamUhnfdvhbThoOPwilU4UM98= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cert-manager/cert-manager v1.16.1 h1:1ceFMqTtwiqY2vyfaRT85CNiVmK7pJjt3GebYCx9awY= +github.com/cert-manager/cert-manager v1.16.1/go.mod h1:MfLVTL45hFZsqmaT1O0+b2ugaNNQQZttSFV9hASHUb0= +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/chigopher/pathlib v0.19.1 h1:RoLlUJc0CqBGwq239cilyhxPNLXTK+HXoASGyGznx5A= github.com/chigopher/pathlib v0.19.1/go.mod h1:tzC1dZLW8o33UQpWkNkhvPwL5n4yyFRFm/jL1YGWFvY= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -81,74 +83,76 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk 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/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= +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/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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/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/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.12.1-0.20240111020705-5401a878d8bb h1:1BlzJS6JUqCF+HY7RLLafmZdZPmpHLvUWZSw8Jz+GcM= -github.com/envoyproxy/go-control-plane v0.12.1-0.20240111020705-5401a878d8bb/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= +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/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= -github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +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/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -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/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-asn1-ber/asn1-ber v1.5.6 h1:CYsqysemXfEaQbyrLJmdsCRuufHoLa3P/gGWGl5TDrM= +github.com/go-asn1-ber/asn1-ber v1.5.6/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= 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-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ= -github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= -github.com/go-fonts/latin-modern v0.3.1 h1:/cT8A7uavYKvglYXvrdDw4oS5ZLkcOU22fa2HJ1/JVM= -github.com/go-fonts/latin-modern v0.3.1/go.mod h1:ysEQXnuT/sCDOAONxC7ImeEDVINbltClhasMAqEtRK0= -github.com/go-fonts/liberation v0.3.1 h1:9RPT2NhUpxQ7ukUvz3jeUckmN42T9D9TpjtQcqK/ceM= -github.com/go-fonts/liberation v0.3.1/go.mod h1:jdJ+cqF+F4SUL2V+qxBth8fvBpBDS7yloUL5Fi8GTGY= +github.com/go-fonts/dejavu v0.3.4 h1:Qqyx9IOs5CQFxyWTdvddeWzrX0VNwUAvbmAzL0fpjbc= +github.com/go-fonts/dejavu v0.3.4/go.mod h1:D1z0DglIz+lmpeNYMYlxW4r22IhcdOYnt+R3PShU/Kg= +github.com/go-fonts/latin-modern v0.3.3 h1:g2xNgI8yzdNzIVm+qvbMryB6yGPe0pSMss8QT3QwlJ0= +github.com/go-fonts/latin-modern v0.3.3/go.mod h1:tHaiWDGze4EPB0Go4cLT5M3QzRY3peya09Z/8KSCrpY= +github.com/go-fonts/liberation v0.3.3 h1:tM/T2vEOhjia6v5krQu8SDDegfH1SfXVRUNNKpq0Usk= +github.com/go-fonts/liberation v0.3.3/go.mod h1:eUAzNRuJnpSnd1sm2EyloQfSOT79pdw7X7++Ri+3MCU= 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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-latex/latex v0.0.0-20230307184459-12ec69307ad9 h1:NxXI5pTAtpEaU49bpLpQoDsu1zrteW/vxzTz8Cd2UAs= -github.com/go-latex/latex v0.0.0-20230307184459-12ec69307ad9/go.mod h1:gWuR/CrFDDeVRFQwHPvsv9soJVB/iqymhuZQuJ3a9OM= +github.com/go-latex/latex v0.0.0-20240709081214-31cef3c7570e h1:xcdj0LWnMSIU1j8+jIeJyfvk6SjgJedFQssSqFthJ2E= +github.com/go-latex/latex v0.0.0-20240709081214-31cef3c7570e/go.mod h1:J4SAGzkcl+28QWi7yz72tyC/4aGnppOvya+AEv4TaAQ= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +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-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= -github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= -github.com/go-pdf/fpdf v0.8.0 h1:IJKpdaagnWUeSkUFUjTcSzTppFxmv8ucGQyNPQWxYOQ= -github.com/go-pdf/fpdf v0.8.0/go.mod h1:gfqhcNwXrsd3XYKte9a7vM3smvU/jB4ZRDrmWSxpfdc= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw= +github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y= 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 v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= -github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= +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 v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= +github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -181,8 +185,6 @@ 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.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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -198,7 +200,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.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= @@ -223,8 +224,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf 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-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -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-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -232,9 +233,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ 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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= @@ -263,6 +263,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/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.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -273,6 +275,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -284,12 +288,14 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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/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/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -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/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -303,10 +309,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 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.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.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= 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/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -316,6 +322,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +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= @@ -323,15 +331,15 @@ github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/projectcontour/yages v0.1.0 h1:vcFpregOq5TVF0/AXLive1MY4CVMDkgL7/+qbUeIbDs= github.com/projectcontour/yages v0.1.0/go.mod h1:pcJrPa3dP17HwGj2YOfBZ4w5WmC1rSpv/X/sV4wauSw= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +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-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw= -github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +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.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= 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= @@ -349,8 +357,8 @@ github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -367,7 +375,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -376,19 +383,20 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/tsaarni/certyaml v0.9.3 h1:m8HHbuUzWVUOmv8IQU9HgVZZ8r5ICExKm++54DJKCs0= -github.com/tsaarni/certyaml v0.9.3/go.mod h1:hhuU1qYr5re488geArUP4gZWqMUMqGlj4HA2qUyGYLk= +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/vektra/mockery/v2 v2.42.1 h1:z7l3O4jCzRZat3rm9jpHc8lzpR8bs1VBii7bYtl3KQs= -github.com/vektra/mockery/v2 v2.42.1/go.mod h1:XNTE9RIu3deGAGQRVjP1VZxGpQNm0YedZx4oDs3prr8= +github.com/vektra/mockery/v2 v2.46.0 h1:DKIFj6hAPGwmOYiWfWzdsQtBgU8ozPXo3Bwbmf+Ku80= +github.com/vektra/mockery/v2 v2.46.0/go.mod h1:XNTE9RIu3deGAGQRVjP1VZxGpQNm0YedZx4oDs3prr8= +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/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 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= @@ -396,8 +404,8 @@ 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.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -405,18 +413,17 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= 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= @@ -427,12 +434,12 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= 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/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo= -golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8= +golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= +golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= 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= @@ -454,10 +461,8 @@ 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -490,10 +495,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= 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= @@ -503,8 +506,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ 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.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.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= @@ -515,10 +518,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -558,19 +559,14 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= 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= @@ -579,16 +575,13 @@ 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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -640,20 +633,18 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= -gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE= -gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU= +gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= +gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= +gonum.org/v1/plot v0.15.0 h1:SIFtFNdZNWLRDRVjD6CYxdawcpJDWySZehJGpv1ukkw= +gonum.org/v1/plot v0.15.0/go.mod h1:3Nx4m77J4T/ayr/b8dQ8uGRmZF6H3eTqliUExDrQHnM= 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= @@ -680,8 +671,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww 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/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= 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= @@ -719,12 +708,10 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -741,8 +728,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM 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.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +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 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= @@ -753,16 +740,16 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 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.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= @@ -785,16 +772,14 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt 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= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= -k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= -k8s.io/apiextensions-apiserver v0.29.3 h1:9HF+EtZaVpFjStakF4yVufnXGPRppWFEQ87qnO91YeI= -k8s.io/apiextensions-apiserver v0.29.3/go.mod h1:po0XiY5scnpJfFizNGo6puNU6Fq6D70UJY2Cb2KwAVc= -k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= -k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= -k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= -k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= -k8s.io/component-base v0.29.3 h1:Oq9/nddUxlnrCuuR2K/jp6aflVvc0uDvxMzAWxnGzAo= -k8s.io/component-base v0.29.3/go.mod h1:Yuj33XXjuOk2BAaHsIGHhCKZQAgYKhqIxIjIr2UXYio= +k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= +k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= +k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= +k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= +k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= +k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= +k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= k8s.io/gengo v0.0.0-20201203183100-97869a43a9d9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= @@ -802,27 +787,27 @@ k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 h1:avRdiaB03v88Mfvum2S3BBwkNuTlmuar4LlfO9Hajko= -k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022/go.mod h1:sIV51WBTkZrlGOJMCDZDA1IaPBUDTulPpD4y7oe038k= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUxmcUV/CtNU8QM7h1FLWQOo= +k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= +k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI= +k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= -sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= -sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= -sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= -sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs= -sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/controller-tools v0.16.4 h1:VXmar78eDXbx1by/H09ikEq1hiq3bqInxuV3lMr3GmQ= +sigs.k8s.io/controller-tools v0.16.4/go.mod h1:kcsZyYMXiOFuBhofSPtkB90zTSxVRxVVyvtKQcx3q1A= +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/kustomize/kyaml v0.16.0 h1:6J33uKSoATlKZH16unr2XOhDI+otoe2sR3M8PDzW3K0= -sigs.k8s.io/kustomize/kyaml v0.16.0/go.mod h1:xOK/7i+vmE14N2FdFyugIshB8eF6ALpy7jI87Q2nRh4= +sigs.k8s.io/kustomize/kyaml v0.17.2 h1:+AzvoJUY0kq4QAhH/ydPHHMRLijtUKiyVyh7fOSshr0= +sigs.k8s.io/kustomize/kyaml v0.17.2/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= 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/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/hack/actions/install-kubernetes-toolchain.sh b/hack/actions/install-kubernetes-toolchain.sh index a1c4ac7e18f..8a7eea88d0e 100755 --- a/hack/actions/install-kubernetes-toolchain.sh +++ b/hack/actions/install-kubernetes-toolchain.sh @@ -4,8 +4,8 @@ set -o errexit set -o nounset set -o pipefail -readonly KUBECTL_VERS="v1.29.2" -readonly KIND_VERS="v0.22.0" +readonly KUBECTL_VERS="v1.31.0" +readonly KIND_VERS="v0.24.0" readonly PROGNAME=$(basename $0) readonly CURL=${CURL:-curl} diff --git a/hack/release/release-notes-template.md b/hack/release/release-notes-template.md index 61ee8d38a8a..8d115c0c28b 100644 --- a/hack/release/release-notes-template.md +++ b/hack/release/release-notes-template.md @@ -49,14 +49,19 @@ Feedback and bug reports are welcome! {{ if .Prerelease}} The simplest way to install {{ .Version }} is to apply one of the example configurations: -With Gateway API: +Standalone Contour: ```bash -kubectl apply -f https://raw.githubusercontent.com/projectcontour/contour/{{ .Version }}/examples/render/contour-gateway.yaml +kubectl apply -f https://raw.githubusercontent.com/projectcontour/contour/{{ .Version }}/examples/render/contour.yaml ``` -Without Gateway API: +Contour Gateway Provisioner: ```bash -kubectl apply -f https://raw.githubusercontent.com/projectcontour/contour/{{ .Version }}/examples/render/contour.yaml +kubectl apply -f https://raw.githubusercontent.com/projectcontour/contour/{{ .Version }}/examples/render/contour-gateway-provisioner.yaml +``` + +Statically provisioned Contour with Gateway API: +```bash +kubectl apply -f https://raw.githubusercontent.com/projectcontour/contour/{{ .Version }}/examples/render/contour-gateway.yaml ``` {{ else }} For a fresh install of Contour, consult the [getting started documentation](https://projectcontour.io/getting-started/). diff --git a/hack/yamllint b/hack/yamllint index c9e6276b189..55ed8b8dd52 100755 --- a/hack/yamllint +++ b/hack/yamllint @@ -3,13 +3,14 @@ readonly PROGNAME="yamllint" if command -v ${PROGNAME} >/dev/null; then - exec ${PROGNAME} "$@" + exec ${PROGNAME} -c .yamllint . fi if command -v docker >/dev/null; then exec docker run --rm -i \ -v $(pwd):/workdir \ - giantswarm/yamllint "$@" + --workdir=/workdir \ + giantswarm/yamllint -c .yamllint . fi cat < 0 { + otherListenerHostnames = append(otherListenerHostnames, string(*listener.listener.Hostname)) + } + } + // Keep track of the number of intersecting hosts // between the route and all allowed listeners for // this parent ref so that we can set the appropriate @@ -238,11 +248,11 @@ func (p *GatewayAPIProcessor) processRoute( routeHostnames = route.Spec.Hostnames case *gatewayapi_v1alpha2.TLSRoute: routeHostnames = route.Spec.Hostnames - case *gatewayapi_v1alpha2.GRPCRoute: + case *gatewayapi_v1.GRPCRoute: routeHostnames = route.Spec.Hostnames } - hosts, errs = p.computeHosts(routeHostnames, string(ptr.Deref(listener.listener.Hostname, ""))) + hosts, errs = p.computeHosts(routeHostnames, string(ptr.Deref(listener.listener.Hostname, "")), otherListenerHostnames) for _, err := range errs { // The Gateway API spec does not indicate what to do if syntactically // invalid hostnames make it through, we're using our best judgment here. @@ -263,7 +273,7 @@ func (p *GatewayAPIProcessor) processRoute( p.computeHTTPRouteForListener(route, routeParentStatus, routeParentRef, listener, hosts) case *gatewayapi_v1alpha2.TLSRoute: p.computeTLSRouteForListener(route, routeParentStatus, listener, hosts) - case *gatewayapi_v1alpha2.GRPCRoute: + case *gatewayapi_v1.GRPCRoute: p.computeGRPCRouteForListener(route, routeParentStatus, listener, hosts) case *gatewayapi_v1alpha2.TCPRoute: p.computeTCPRouteForListener(route, routeParentStatus, listener) @@ -311,7 +321,7 @@ func (p *GatewayAPIProcessor) getListenersForRouteParentRef( listeners []*listenerInfo, attachedRoutes map[string]int, routeParentStatusAccessor *status.RouteParentStatusUpdate, -) []*listenerInfo { +) map[string]*listenerInfo { // Find the set of valid listeners that are relevant given this // parent ref (either all of them, if the ref is to the entire // gateway, or one of them, if the ref is to a specific listener, @@ -329,7 +339,7 @@ func (p *GatewayAPIProcessor) getListenersForRouteParentRef( // Now find the subset of those listeners that allow this route // to select them, based on route kind and namespace. - var allowedListeners []*listenerInfo + allowedListeners := map[string]*listenerInfo{} readyListenerCount := 0 @@ -354,7 +364,7 @@ func (p *GatewayAPIProcessor) getListenersForRouteParentRef( attachedRoutes[string(selectedListener.listener.Name)]++ if selectedListener.ready { - allowedListeners = append(allowedListeners, selectedListener) + allowedListeners[string(selectedListener.listener.Name)] = selectedListener } } @@ -834,7 +844,7 @@ func isSecretRef(certificateRef gatewayapi_v1.SecretObjectReference) bool { // invalid and some condition should be added to the route. This shouldn't be // possible because of kubebuilder+admission webhook validation but we're being // defensive here. -func (p *GatewayAPIProcessor) computeHosts(routeHostnames []gatewayapi_v1.Hostname, listenerHostname string) (sets.Set[string], []error) { +func (p *GatewayAPIProcessor) computeHosts(routeHostnames []gatewayapi_v1.Hostname, listenerHostname string, otherListenerHosts []string) (sets.Set[string], []error) { // The listener hostname is assumed to be valid because it's been run // through the `gatewayapi.ValidateListeners` logic, so we don't need // to validate it here. @@ -852,6 +862,21 @@ func (p *GatewayAPIProcessor) computeHosts(routeHostnames []gatewayapi_v1.Hostna hostnames := sets.New[string]() var errs []error + otherListenerIntersection := func(routeHostname, actualListenerHostname string) bool { + for _, listenerHostname := range otherListenerHosts { + if routeHostname == listenerHostname { + return true + } + if strings.HasPrefix(listenerHostname, "*") && + hostnameMatchesWildcardHostname(routeHostname, listenerHostname) && + len(listenerHostname) > len(actualListenerHostname) { + return true + } + } + + return false + } + for i := range routeHostnames { routeHostname := string(routeHostnames[i]) @@ -862,17 +887,21 @@ func (p *GatewayAPIProcessor) computeHosts(routeHostnames []gatewayapi_v1.Hostna } switch { - // No listener hostname: use the route hostname. + // No listener hostname: use the route hostname if + // it does not also intersect with another Listener. case len(listenerHostname) == 0: - hostnames.Insert(routeHostname) + if !otherListenerIntersection(routeHostname, listenerHostname) { + hostnames.Insert(routeHostname) + } // Listener hostname matches the route hostname: use it. case listenerHostname == routeHostname: hostnames.Insert(routeHostname) - // Listener has a wildcard hostname: check if the route hostname matches. + // Listener has a wildcard hostname: check if the route hostname matches + // but do not use it if it intersects with a more specific other Listener. case strings.HasPrefix(listenerHostname, "*"): - if hostnameMatchesWildcardHostname(routeHostname, listenerHostname) { + if hostnameMatchesWildcardHostname(routeHostname, listenerHostname) && !otherListenerIntersection(routeHostname, listenerHostname) { hostnames.Insert(routeHostname) } @@ -1089,10 +1118,10 @@ func (p *GatewayAPIProcessor) resolveRouteRefs(route any, routeAccessor *status. } } } - case *gatewayapi_v1alpha2.GRPCRoute: + case *gatewayapi_v1.GRPCRoute: for _, r := range route.Spec.Rules { for _, f := range r.Filters { - if f.Type == gatewayapi_v1alpha2.GRPCRouteFilterRequestMirror && f.RequestMirror != nil { + if f.Type == gatewayapi_v1.GRPCRouteFilterRequestMirror && f.RequestMirror != nil { _, cond := p.validateBackendObjectRef(f.RequestMirror.BackendRef, "Spec.Rules.Filters.RequestMirror.BackendRef", KindGRPCRoute, route.Namespace) if cond != nil { routeAccessor.AddCondition(gatewayapi_v1.RouteConditionType(cond.Type), cond.Status, gatewayapi_v1.RouteConditionReason(cond.Reason), cond.Message) @@ -1117,28 +1146,52 @@ func (p *GatewayAPIProcessor) resolveRouteRefs(route any, routeAccessor *status. } func parseHTTPRouteTimeouts(httpRouteTimeouts *gatewayapi_v1.HTTPRouteTimeouts) (*RouteTimeoutPolicy, error) { - if httpRouteTimeouts == nil { + if httpRouteTimeouts == nil || (httpRouteTimeouts.Request == nil && httpRouteTimeouts.BackendRequest == nil) { return nil, nil } - // Since Gateway API doesn't yet support retries, this timeout setting - // is functionally equivalent to httpRouteTimeouts.Request, so we're - // not implementing it for now. Once retries are added to Gateway API, - // support for backend request timeouts can be added. - if httpRouteTimeouts.BackendRequest != nil { - return nil, errors.New("HTTPRoute.Spec.Rules.Timeouts.BackendRequest is not supported, use HTTPRoute.Spec.Rules.Timeouts.Request instead") - } - if httpRouteTimeouts.Request == nil { - return nil, nil + var responseTimeout timeout.Setting + + if httpRouteTimeouts.Request != nil { + requestTimeout, err := timeout.Parse(string(*httpRouteTimeouts.Request)) + if err != nil { + return nil, fmt.Errorf("invalid HTTPRoute.Spec.Rules.Timeouts.Request: %v", err) + } + + // For Gateway API a zero-valued timeout means disable the timeout. + if requestTimeout.Duration() == 0 { + requestTimeout = timeout.DisabledSetting() + } + + responseTimeout = requestTimeout } - requestTimeout, err := timeout.Parse(string(*httpRouteTimeouts.Request)) - if err != nil { - return nil, fmt.Errorf("invalid HTTPRoute.Spec.Rules.Timeouts.Request: %v", err) + // Note, since retries are not yet implemented in Gateway API, the backend + // request timeout is functionally equivalent to the request timeout for now. + // The API spec requires that it be less than/equal to the request timeout if + // both are specified. This implementation will change when retries are implemented. + if httpRouteTimeouts.BackendRequest != nil { + backendRequestTimeout, err := timeout.Parse(string(*httpRouteTimeouts.BackendRequest)) + if err != nil { + return nil, fmt.Errorf("invalid HTTPRoute.Spec.Rules.Timeouts.BackendRequest: %v", err) + } + + // For Gateway API a zero-valued timeout means disable the timeout. + if backendRequestTimeout.Duration() == 0 { + backendRequestTimeout = timeout.DisabledSetting() + } + + // If Timeouts.Request was specified, then Timeouts.BackendRequest must be + // less than/equal to it. + if responseTimeout.Duration() > 0 && backendRequestTimeout.Duration() > responseTimeout.Duration() { + return nil, fmt.Errorf("HTTPRoute.Spec.Rules.Timeouts.BackendRequest must be less than/equal to HTTPRoute.Spec.Rules.Timeouts.Request when both are specified") + } + + responseTimeout = backendRequestTimeout } return &RouteTimeoutPolicy{ - ResponseTimeout: requestTimeout, + ResponseTimeout: responseTimeout, }, nil } @@ -1149,6 +1202,8 @@ func (p *GatewayAPIProcessor) computeHTTPRouteForListener( listener *listenerInfo, hosts sets.Set[string], ) { + // Count number of rules under this Route that are invalid. + invalidRuleCnt := 0 for ruleIndex, rule := range route.Spec.Rules { // Get match conditions for the rule. var matchconditions []*matchConditions @@ -1425,25 +1480,62 @@ func (p *GatewayAPIProcessor) computeHTTPRouteForListener( timeoutPolicy) } - // Add each route to the relevant vhost(s)/svhosts(s). - for host := range hosts { - for _, route := range routes { - switch { - case listener.tlsSecret != nil: - svhost := p.dag.EnsureSecureVirtualHost(listener.dagListenerName, host) - svhost.Secret = listener.tlsSecret - svhost.AddRoute(route) - default: - vhost := p.dag.EnsureVirtualHost(listener.dagListenerName, host) - vhost.AddRoute(route) + // Check all the routes whether there is conflict against previous rules. + if !p.hasConflictRoute(listener, hosts, routes) { + // Add the route if there is no conflict at the same rule level. + // Add each route to the relevant vhost(s)/svhosts(s). + for host := range hosts { + for _, route := range routes { + switch { + case listener.tlsSecret != nil: + svhost := p.dag.EnsureSecureVirtualHost(listener.dagListenerName, host) + svhost.Secret = listener.tlsSecret + svhost.AddRoute(route) + default: + vhost := p.dag.EnsureVirtualHost(listener.dagListenerName, host) + vhost.AddRoute(route) + } + } + } + } else { + // Skip adding the routes under this rule. + invalidRuleCnt++ + } + } + + if invalidRuleCnt == len(route.Spec.Rules) { + // No rules under the route is valid, mark it as not accepted. + addRouteNotAcceptedConditionDueToMatchConflict(routeAccessor, KindHTTPRoute) + } else if invalidRuleCnt > 0 { + // Some of the rules are conflicted, mark it as partially invalid. + addRoutePartiallyInvalidConditionDueToMatchPartiallyConflict(routeAccessor, KindHTTPRoute) + } +} + +func (p *GatewayAPIProcessor) hasConflictRoute(listener *listenerInfo, hosts sets.Set[string], routes []*Route) bool { + // check if there is conflict match first + for host := range hosts { + for _, route := range routes { + switch { + case listener.tlsSecret != nil: + svhost := p.dag.EnsureSecureVirtualHost(listener.dagListenerName, host) + if svhost.HasConflictRoute(route) { + return true + } + default: + vhost := p.dag.EnsureVirtualHost(listener.dagListenerName, host) + if vhost.HasConflictRoute(route) { + return true } } } } + return false } -func (p *GatewayAPIProcessor) computeGRPCRouteForListener(route *gatewayapi_v1alpha2.GRPCRoute, routeAccessor *status.RouteParentStatusUpdate, listener *listenerInfo, hosts sets.Set[string]) bool { +func (p *GatewayAPIProcessor) computeGRPCRouteForListener(route *gatewayapi_v1.GRPCRoute, routeAccessor *status.RouteParentStatusUpdate, listener *listenerInfo, hosts sets.Set[string]) bool { var programmed bool + invalidRuleCnt := 0 for ruleIndex, rule := range route.Spec.Rules { // Get match conditions for the rule. var matchconditions []*matchConditions @@ -1486,7 +1578,7 @@ func (p *GatewayAPIProcessor) computeGRPCRouteForListener(route *gatewayapi_v1al // subsequent instances. for _, filter := range rule.Filters { switch filter.Type { - case gatewayapi_v1alpha2.GRPCRouteFilterRequestHeaderModifier: + case gatewayapi_v1.GRPCRouteFilterRequestHeaderModifier: if filter.RequestHeaderModifier == nil || requestHeaderPolicy != nil { continue } @@ -1496,7 +1588,7 @@ func (p *GatewayAPIProcessor) computeGRPCRouteForListener(route *gatewayapi_v1al if err != nil { routeAccessor.AddCondition(gatewayapi_v1.RouteConditionResolvedRefs, meta_v1.ConditionFalse, status.ReasonDegraded, fmt.Sprintf("%s on request headers", err)) } - case gatewayapi_v1alpha2.GRPCRouteFilterResponseHeaderModifier: + case gatewayapi_v1.GRPCRouteFilterResponseHeaderModifier: if filter.ResponseHeaderModifier == nil || responseHeaderPolicy != nil { continue } @@ -1506,7 +1598,7 @@ func (p *GatewayAPIProcessor) computeGRPCRouteForListener(route *gatewayapi_v1al if err != nil { routeAccessor.AddCondition(gatewayapi_v1.RouteConditionResolvedRefs, meta_v1.ConditionFalse, status.ReasonDegraded, fmt.Sprintf("%s on response headers", err)) } - case gatewayapi_v1alpha2.GRPCRouteFilterRequestMirror: + case gatewayapi_v1.GRPCRouteFilterRequestMirror: if filter.RequestMirror == nil { continue } @@ -1566,28 +1658,41 @@ func (p *GatewayAPIProcessor) computeGRPCRouteForListener(route *gatewayapi_v1al nil, ) - // Add each route to the relevant vhost(s)/svhosts(s). - for host := range hosts { - for _, route := range routes { - switch { - case listener.tlsSecret != nil: - svhost := p.dag.EnsureSecureVirtualHost(listener.dagListenerName, host) - svhost.Secret = listener.tlsSecret - svhost.AddRoute(route) - default: - vhost := p.dag.EnsureVirtualHost(listener.dagListenerName, host) - vhost.AddRoute(route) + // Check all the routes whether there is conflict against previous rules. + if !p.hasConflictRoute(listener, hosts, routes) { + // Add the route if there is no conflict at the same rule level. + // Add each route to the relevant vhost(s)/svhosts(s). + for host := range hosts { + for _, route := range routes { + switch { + case listener.tlsSecret != nil: + svhost := p.dag.EnsureSecureVirtualHost(listener.dagListenerName, host) + svhost.Secret = listener.tlsSecret + svhost.AddRoute(route) + default: + vhost := p.dag.EnsureVirtualHost(listener.dagListenerName, host) + vhost.AddRoute(route) + } } - - programmed = true } + } else { + // Skip adding the routes under this rule. + invalidRuleCnt++ } } + if invalidRuleCnt == len(route.Spec.Rules) { + // No rules under the route is valid, mark it as not accepted. + addRouteNotAcceptedConditionDueToMatchConflict(routeAccessor, KindGRPCRoute) + } else if invalidRuleCnt > 0 { + // Some of the rules are conflicted, mark it as partially invalid. + addRoutePartiallyInvalidConditionDueToMatchPartiallyConflict(routeAccessor, KindGRPCRoute) + } + return programmed } -func gatewayGRPCMethodMatchCondition(match *gatewayapi_v1alpha2.GRPCMethodMatch, routeAccessor *status.RouteParentStatusUpdate) (MatchCondition, bool) { +func gatewayGRPCMethodMatchCondition(match *gatewayapi_v1.GRPCMethodMatch, routeAccessor *status.RouteParentStatusUpdate) (MatchCondition, bool) { // If method match is not specified, all services and methods will match. if match == nil { return &PrefixMatchCondition{Prefix: "/"}, true @@ -1599,7 +1704,7 @@ func gatewayGRPCMethodMatchCondition(match *gatewayapi_v1alpha2.GRPCMethodMatch, // Not Support: Implementation-specific (RegularExpression) // Support "Exact" match type only. If match type is not specified, use "Exact" as default. - if match.Type != nil && *match.Type != gatewayapi_v1alpha2.GRPCMethodMatchExact { + if match.Type != nil && *match.Type != gatewayapi_v1.GRPCMethodMatchExact { routeAccessor.AddCondition(gatewayapi_v1.RouteConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1.RouteReasonUnsupportedValue, "GRPCRoute.Spec.Rules.Matches.Method: Only Exact match type is supported.") return nil, false } @@ -1615,7 +1720,7 @@ func gatewayGRPCMethodMatchCondition(match *gatewayapi_v1alpha2.GRPCMethodMatch, return &ExactMatchCondition{Path: path}, true } -func gatewayGRPCHeaderMatchConditions(matches []gatewayapi_v1alpha2.GRPCHeaderMatch) ([]HeaderMatchCondition, error) { +func gatewayGRPCHeaderMatchConditions(matches []gatewayapi_v1.GRPCHeaderMatch) ([]HeaderMatchCondition, error) { var headerMatchConditions []HeaderMatchCondition seenNames := sets.New[string]() @@ -2063,7 +2168,7 @@ func (p *GatewayAPIProcessor) computeBackendTLSPolicies(routeNamespace string, b var upstreamValidation *PeerValidationContext var upstreamTLS *UpstreamTLS - var backendRefGroup gatewayapi_v1alpha2.Group + var backendRefGroup gatewayapi_v1.Group if backendRef.Group != nil { backendRefGroup = *backendRef.Group } @@ -2080,18 +2185,17 @@ func (p *GatewayAPIProcessor) computeBackendTLSPolicies(routeNamespace string, b backendNamespace = ptr.To(gatewayapi_v1.Namespace(routeNamespace)) } - policyTargetRef := gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Group: backendRefGroup, - Kind: backendRefKind, - Name: backendRef.Name, - Namespace: backendNamespace, + policyTargetRef := gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Group: backendRefGroup, + Kind: backendRefKind, + Name: backendRef.Name, }, SectionName: ptr.To(gatewayapi_v1alpha2.SectionName(service.Weighted.ServicePort.Name)), } // Check to see if there is any BackendTLSPolicy matching this service and service port - backendTLSPolicy, found := p.source.LookupBackendTLSPolicyByTargetRef(policyTargetRef) + backendTLSPolicy, found := p.source.LookupBackendTLSPolicyByTargetRef(policyTargetRef, string(*backendNamespace)) if found { backendTLSPolicyAccessor, commit := p.dag.StatusCache.BackendTLSPolicyConditionsAccessor( k8s.NamespacedNameOf(backendTLSPolicy), @@ -2100,24 +2204,24 @@ func (p *GatewayAPIProcessor) computeBackendTLSPolicies(routeNamespace string, b defer commit() backendTLSPolicyAncestorStatus := backendTLSPolicyAccessor.StatusUpdateFor(routeParentRef) - if backendTLSPolicy.Spec.TLS.WellKnownCACerts != nil && *backendTLSPolicy.Spec.TLS.WellKnownCACerts != "" { - backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, "BackendTLSPolicy.Spec.TLS.WellKnownCACerts is unsupported.") + if backendTLSPolicy.Spec.Validation.WellKnownCACertificates != nil && *backendTLSPolicy.Spec.Validation.WellKnownCACertificates != "" { + backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, "BackendTLSPolicy.Spec.Validation.WellKnownCACertificates is unsupported.") return nil, nil } - if err := gatewayapi.IsValidHostname(string(backendTLSPolicy.Spec.TLS.Hostname)); err != nil { - backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("BackendTLSPolicy.Spec.TLS.Hostname %q is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", backendTLSPolicy.Spec.TLS.Hostname)) + if err := gatewayapi.IsValidHostname(string(backendTLSPolicy.Spec.Validation.Hostname)); err != nil { + backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("BackendTLSPolicy.Spec.Validation.Hostname %q is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", backendTLSPolicy.Spec.Validation.Hostname)) return nil, nil } - if strings.Contains(string(backendTLSPolicy.Spec.TLS.Hostname), "*") { - backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("BackendTLSPolicy.Spec.TLS.Hostname %q is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", backendTLSPolicy.Spec.TLS.Hostname)) + if strings.Contains(string(backendTLSPolicy.Spec.Validation.Hostname), "*") { + backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("BackendTLSPolicy.Spec.Validation.Hostname %q is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", backendTLSPolicy.Spec.Validation.Hostname)) return nil, nil } var isInvalidCertChain bool var caSecrets []*Secret - for _, certRef := range backendTLSPolicy.Spec.TLS.CACertRefs { + for _, certRef := range backendTLSPolicy.Spec.Validation.CACertificateRefs { switch certRef.Kind { case "Secret": caSecret, err := p.source.LookupCASecret(types.NamespacedName{ @@ -2125,7 +2229,7 @@ func (p *GatewayAPIProcessor) computeBackendTLSPolicies(routeNamespace string, b Namespace: backendTLSPolicy.Namespace, }, backendTLSPolicy.Namespace) if err != nil { - backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("Could not find CACertRef Secret: %s/%s", backendTLSPolicy.Namespace, certRef.Name)) + backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("Could not find CACertificateRef Secret: %s/%s", backendTLSPolicy.Namespace, certRef.Name)) isInvalidCertChain = true continue } @@ -2136,13 +2240,13 @@ func (p *GatewayAPIProcessor) computeBackendTLSPolicies(routeNamespace string, b Namespace: backendTLSPolicy.Namespace, }) if err != nil { - backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("Could not find CACertRef ConfigMap: %s/%s", backendTLSPolicy.Namespace, certRef.Name)) + backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("Could not find CACertificateRef ConfigMap: %s/%s", backendTLSPolicy.Namespace, certRef.Name)) isInvalidCertChain = true continue } caSecrets = append(caSecrets, caSecret) default: - backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("BackendTLSPolicy.Spec.TLS.CACertRef.Kind %q is unsupported. Only ConfigMap or Secret Kind is supported.", certRef.Kind)) + backendTLSPolicyAncestorStatus.AddCondition(gatewayapi_v1alpha2.PolicyConditionAccepted, meta_v1.ConditionFalse, gatewayapi_v1alpha2.PolicyReasonInvalid, fmt.Sprintf("BackendTLSPolicy.Spec.Validation.CACertificateRef.Kind %q is unsupported. Only ConfigMap or Secret Kind is supported.", certRef.Kind)) isInvalidCertChain = true continue } @@ -2155,7 +2259,7 @@ func (p *GatewayAPIProcessor) computeBackendTLSPolicies(routeNamespace string, b if len(caSecrets) != 0 { upstreamValidation = &PeerValidationContext{ CACertificates: caSecrets, - SubjectNames: []string{string(backendTLSPolicy.Spec.TLS.Hostname)}, + SubjectNames: []string{string(backendTLSPolicy.Spec.Validation.Hostname)}, } upstreamTLS = p.UpstreamTLS @@ -2168,7 +2272,7 @@ func (p *GatewayAPIProcessor) computeBackendTLSPolicies(routeNamespace string, b } // grpcClusters builds clusters from backendRef. -func (p *GatewayAPIProcessor) grpcClusters(routeNamespace string, backendRefs []gatewayapi_v1alpha2.GRPCBackendRef, routeAccessor *status.RouteParentStatusUpdate, protocolType gatewayapi_v1.ProtocolType) ([]*Cluster, uint32, bool) { +func (p *GatewayAPIProcessor) grpcClusters(routeNamespace string, backendRefs []gatewayapi_v1.GRPCBackendRef, routeAccessor *status.RouteParentStatusUpdate, protocolType gatewayapi_v1.ProtocolType) ([]*Cluster, uint32, bool) { totalWeight := uint32(0) if len(backendRefs) == 0 { @@ -2195,7 +2299,7 @@ func (p *GatewayAPIProcessor) grpcClusters(routeNamespace string, backendRefs [] // subsequent instances. for _, filter := range backendRef.Filters { switch filter.Type { - case gatewayapi_v1alpha2.GRPCRouteFilterRequestHeaderModifier: + case gatewayapi_v1.GRPCRouteFilterRequestHeaderModifier: if filter.RequestHeaderModifier == nil || clusterRequestHeaderPolicy != nil { continue } @@ -2205,7 +2309,7 @@ func (p *GatewayAPIProcessor) grpcClusters(routeNamespace string, backendRefs [] if err != nil { routeAccessor.AddCondition(gatewayapi_v1.RouteConditionResolvedRefs, meta_v1.ConditionFalse, status.ReasonDegraded, fmt.Sprintf("%s on request headers", err)) } - case gatewayapi_v1alpha2.GRPCRouteFilterResponseHeaderModifier: + case gatewayapi_v1.GRPCRouteFilterResponseHeaderModifier: if filter.ResponseHeaderModifier == nil || clusterResponseHeaderPolicy != nil { continue } @@ -2397,3 +2501,59 @@ func handlePathRewritePrefixRemoval(p *PathRewritePolicy, mc *matchConditions) * return p } + +// sortHTTPRoutes sorts httproutes based on creationTimestamp in ascending order +// if creationTimestamps are the same, sort based on namespaced name ("/") in alphetical ascending order +func sortHTTPRoutes(m map[types.NamespacedName]*gatewayapi_v1.HTTPRoute) []*gatewayapi_v1.HTTPRoute { + routes := []*gatewayapi_v1.HTTPRoute{} + for _, r := range m { + routes = append(routes, r) + } + sort.SliceStable(routes, func(i, j int) bool { + // if the creation time is the same, compare the route name + if routes[i].CreationTimestamp.Equal(&routes[j].CreationTimestamp) { + return k8s.NamespacedNameOf(routes[i]).String() < + k8s.NamespacedNameOf(routes[j]).String() + } + return routes[i].CreationTimestamp.Before(&routes[j].CreationTimestamp) + }) + + return routes +} + +// sortGRPCRoutes sorts grpcroutes based on creationTimestamp in ascending order +// if creationTimestamps are the same, sort based on namespaced name ("/") in alphetical ascending order +func sortGRPCRoutes(m map[types.NamespacedName]*gatewayapi_v1.GRPCRoute) []*gatewayapi_v1.GRPCRoute { + routes := []*gatewayapi_v1.GRPCRoute{} + for _, r := range m { + routes = append(routes, r) + } + sort.SliceStable(routes, func(i, j int) bool { + // if the creation time is the same, compare the route name + if routes[i].CreationTimestamp.Equal(&routes[j].CreationTimestamp) { + return k8s.NamespacedNameOf(routes[i]).String() < + k8s.NamespacedNameOf(routes[j]).String() + } + return routes[i].CreationTimestamp.Before(&routes[j].CreationTimestamp) + }) + + return routes +} + +func addRouteNotAcceptedConditionDueToMatchConflict(routeAccessor *status.RouteParentStatusUpdate, routeKind string) { + routeAccessor.AddCondition( + gatewayapi_v1.RouteConditionAccepted, + meta_v1.ConditionFalse, + status.ReasonRouteRuleMatchConflict, + fmt.Sprintf(status.MessageRouteRuleMatchConflict, routeKind, routeKind), + ) +} + +func addRoutePartiallyInvalidConditionDueToMatchPartiallyConflict(routeAccessor *status.RouteParentStatusUpdate, routeKind string) { + routeAccessor.AddCondition( + gatewayapi_v1.RouteConditionPartiallyInvalid, + meta_v1.ConditionTrue, + status.ReasonRouteRuleMatchPartiallyConflict, + fmt.Sprintf(status.MessageRouteRuleMatchPartiallyConflict, routeKind, routeKind), + ) +} diff --git a/internal/dag/gatewayapi_processor_test.go b/internal/dag/gatewayapi_processor_test.go index bf7e5cf71f3..55a656fa8c4 100644 --- a/internal/dag/gatewayapi_processor_test.go +++ b/internal/dag/gatewayapi_processor_test.go @@ -16,12 +16,14 @@ package dag import ( "fmt" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" core_v1 "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" @@ -33,10 +35,11 @@ import ( func TestComputeHosts(t *testing.T) { tests := map[string]struct { - listenerHost string - hostnames []gatewayapi_v1.Hostname - want sets.Set[string] - wantError []error + listenerHost string + otherListenerHosts []string + hostnames []gatewayapi_v1.Hostname + want sets.Set[string] + wantError []error }{ "single host": { listenerHost: "", @@ -228,6 +231,75 @@ func TestComputeHosts(t *testing.T) { want: nil, wantError: nil, }, + "empty listener host with other listener specific hosts that match route hostnames": { + listenerHost: "", + otherListenerHosts: []string{ + "foo", + }, + hostnames: []gatewayapi_v1.Hostname{ + "foo", + "bar", + "*.foo", + }, + want: sets.New("bar", "*.foo"), + wantError: nil, + }, + "empty listener host with other listener wildcard hosts that match route hostnames": { + listenerHost: "", + otherListenerHosts: []string{ + "*.foo", + }, + hostnames: []gatewayapi_v1.Hostname{ + "a.bar", + "foo", + "a.foo", + "*.foo", + }, + want: sets.New("a.bar", "foo"), + wantError: nil, + }, + "wildcard listener host with other listener specific hosts that match route hostnames": { + listenerHost: "*.foo", + otherListenerHosts: []string{ + "a.foo", + }, + hostnames: []gatewayapi_v1.Hostname{ + "a.foo", + "c.b.foo", + "*.foo", + }, + want: sets.New("c.b.foo", "*.foo"), + wantError: nil, + }, + "wildcard listener host with other listener more specific wildcard hosts that match route hostnames": { + listenerHost: "*.foo", + otherListenerHosts: []string{ + "*.a.foo", + }, + hostnames: []gatewayapi_v1.Hostname{ + "a.foo", + "b.a.foo", + "d.c.foo", + "*.foo", + "*.b.a.foo", + }, + want: sets.New("a.foo", "d.c.foo", "*.foo"), + wantError: nil, + }, + "wildcard listener host with other listener less specific wildcard hosts that match route hostnames": { + listenerHost: "*.a.foo", + otherListenerHosts: []string{ + "*.foo", + }, + hostnames: []gatewayapi_v1.Hostname{ + "a.foo", + "b.a.foo", + "d.c.foo", + "*.a.foo", + }, + want: sets.New("b.a.foo", "*.a.foo"), + wantError: nil, + }, } for name, tc := range tests { @@ -236,7 +308,7 @@ func TestComputeHosts(t *testing.T) { FieldLogger: fixture.NewTestLogger(t), } - got, gotError := processor.computeHosts(tc.hostnames, tc.listenerHost) + got, gotError := processor.computeHosts(tc.hostnames, tc.listenerHost, tc.otherListenerHosts) assert.Equal(t, tc.want, got) assert.Equal(t, tc.wantError, gotError) }) @@ -759,12 +831,878 @@ func TestGetListenersForRouteParentRef(t *testing.T) { map[string]int{}, rpsu) - var want []*listenerInfo - for _, i := range tc.want { - want = append(want, tc.listeners[i]) + var want map[string]*listenerInfo + if len(tc.want) > 0 { + want = map[string]*listenerInfo{} + for _, i := range tc.want { + listener := tc.listeners[i] + want[string(listener.listener.Name)] = listener + } } assert.Equal(t, want, got) }) } } + +func TestSortRoutes(t *testing.T) { + time1 := time.Date(2021, time.Month(2), 21, 1, 10, 30, 0, time.UTC) + time2 := time.Date(2022, time.Month(2), 21, 1, 10, 30, 0, time.UTC) + time3 := time.Date(2023, time.Month(2), 21, 1, 10, 30, 0, time.UTC) + tests := []struct { + name string + m map[types.NamespacedName]*gatewayapi_v1.HTTPRoute + expected []*gatewayapi_v1.HTTPRoute + }{ + { + name: "3 httproutes, with different timestamp, earlier one should be first ", + m: map[types.NamespacedName]*gatewayapi_v1.HTTPRoute{ + { + Namespace: "ns", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time3), + }, + }, + { + Namespace: "ns", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + Namespace: "ns", Name: "name3", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.HTTPRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time3), + }, + }, + }, + }, + { + name: "3 httproutes with same creation timestamps, same namespaces, smaller name comes first", + m: map[types.NamespacedName]*gatewayapi_v1.HTTPRoute{ + { + Namespace: "ns", Name: "name3", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.HTTPRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + }, + { + name: "3 httproutes with same creation timestamp, smaller namespaces comes first", + m: map[types.NamespacedName]*gatewayapi_v1.HTTPRoute{ + { + Namespace: "ns3", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns2", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns1", Name: "name3", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.HTTPRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + }, + { + name: "mixed order, two with same creation timestamp, two with same name", + m: map[types.NamespacedName]*gatewayapi_v1.HTTPRoute{ + { + Namespace: "ns1", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + Namespace: "ns2", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns1", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + }, + expected: []*gatewayapi_v1.HTTPRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + }, + }, + { + name: "same name, same timestamp, different namespace", + m: map[types.NamespacedName]*gatewayapi_v1.HTTPRoute{ + { + Namespace: "ns3", Name: "name", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns2", Name: "name", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns1", Name: "name", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.HTTPRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + res := sortHTTPRoutes(tc.m) + assert.Equal(t, tc.expected, res) + }) + } +} + +func TestSortGRPCRoutes(t *testing.T) { + time1 := time.Date(2021, time.Month(2), 21, 1, 10, 30, 0, time.UTC) + time2 := time.Date(2022, time.Month(2), 21, 1, 10, 30, 0, time.UTC) + time3 := time.Date(2023, time.Month(2), 21, 1, 10, 30, 0, time.UTC) + tests := []struct { + name string + m map[types.NamespacedName]*gatewayapi_v1.GRPCRoute + expected []*gatewayapi_v1.GRPCRoute + }{ + { + name: "3 grpcroutes, with different timestamp, earlier one should be first ", + m: map[types.NamespacedName]*gatewayapi_v1.GRPCRoute{ + { + Namespace: "ns", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time3), + }, + }, + { + Namespace: "ns", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + Namespace: "ns", Name: "name3", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.GRPCRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time3), + }, + }, + }, + }, + { + name: "3 grpcroutes with same creation timestamps, same namespaces, smaller name comes first", + m: map[types.NamespacedName]*gatewayapi_v1.GRPCRoute{ + { + Namespace: "ns", Name: "name3", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.GRPCRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + }, + { + name: "3 grpcroutes with same creation timestamp, smaller namespaces comes first", + m: map[types.NamespacedName]*gatewayapi_v1.GRPCRoute{ + { + Namespace: "ns3", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns2", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns1", Name: "name3", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.GRPCRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name3", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + }, + { + name: "mixed order, two with same creation timestamp, two with same name", + m: map[types.NamespacedName]*gatewayapi_v1.GRPCRoute{ + { + Namespace: "ns1", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + Namespace: "ns2", Name: "name2", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns1", Name: "name1", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + }, + expected: []*gatewayapi_v1.GRPCRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name1", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name2", + CreationTimestamp: meta_v1.NewTime(time2), + }, + }, + }, + }, + { + name: "same name, same timestamp, different namespace", + m: map[types.NamespacedName]*gatewayapi_v1.GRPCRoute{ + { + Namespace: "ns3", Name: "name", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns2", Name: "name", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + Namespace: "ns1", Name: "name", + }: { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + expected: []*gatewayapi_v1.GRPCRoute{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns1", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns2", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + { + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: "ns3", + Name: "name", + CreationTimestamp: meta_v1.NewTime(time1), + }, + }, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + res := sortGRPCRoutes(tc.m) + assert.Equal(t, tc.expected, res) + }) + } +} + +func TestHasConflictRoute(t *testing.T) { + host1 := "test.projectcontour.io" + host2 := "test1.projectcontour.io" + hosts := sets.New( + host1, + host2, + ) + listener := &listenerInfo{ + listener: gatewayapi_v1.Listener{ + Name: "l1", + AllowedRoutes: &gatewayapi_v1.AllowedRoutes{ + Namespaces: &gatewayapi_v1.RouteNamespaces{ + From: ptr.To(gatewayapi_v1.NamespacesFromSame), + }, + }, + }, + dagListenerName: "l1", + allowedKinds: []gatewayapi_v1.Kind{KindHTTPRoute}, + ready: true, + } + tlsListener := &listenerInfo{ + listener: gatewayapi_v1.Listener{ + Name: "ltls", + AllowedRoutes: &gatewayapi_v1.AllowedRoutes{ + Namespaces: &gatewayapi_v1.RouteNamespaces{ + From: ptr.To(gatewayapi_v1.NamespacesFromSame), + }, + }, + }, + allowedKinds: []gatewayapi_v1.Kind{KindHTTPRoute}, + ready: true, + dagListenerName: "ltls", + tlsSecret: &Secret{}, + } + tests := []struct { + name string + existingRoutes []*Route + routes []*Route + listener *listenerInfo + expectedConflict bool + }{ + { + name: "There are 2 existing httproute, the 3rd route to add doesn't have conflict, listen doesn't have tls, no conflict expected", + existingRoutes: []*Route{ + { + Name: "route1", + Namespace: "default", + PathMatchCondition: prefixSegment("/path1"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: ":authority", MatchType: HeaderMatchTypeRegex, Value: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?\\.example\\.com(:[0-9]+)?"}, + }, + QueryParamMatchConditions: []QueryParamMatchCondition{ + {Name: "param-1", Value: "value-1", MatchType: QueryParamMatchTypeExact}, + }, + }, + { + Kind: KindHTTPRoute, + Name: "route2", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "version", Value: "2", MatchType: "exact", Invert: false}, + }, + }, + }, + routes: []*Route{ + { + Kind: KindHTTPRoute, + Name: "route3", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "e-tag", Value: "abc", MatchType: "contains", Invert: true}, + }, + }, + }, + listener: listener, + }, + { + name: "There are 2 existing grpcroute, the 3rd route to add doesn't have conflict, listen doesn't have tls, no conflict expected", + existingRoutes: []*Route{ + { + Name: "route1", + Namespace: "default", + PathMatchCondition: prefixSegment("/path1"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: ":authority", MatchType: HeaderMatchTypeRegex, Value: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?\\.example\\.com(:[0-9]+)?"}, + }, + QueryParamMatchConditions: []QueryParamMatchCondition{ + {Name: "param-1", Value: "value-1", MatchType: QueryParamMatchTypeExact}, + }, + }, + { + Kind: KindGRPCRoute, + Name: "route2", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "version", Value: "2", MatchType: "exact", Invert: false}, + }, + }, + }, + routes: []*Route{ + { + Kind: KindGRPCRoute, + Name: "route3", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "e-tag", Value: "abc", MatchType: "contains", Invert: true}, + }, + }, + }, + listener: listener, + }, + { + name: "There are 2 existing route, the 3rd route to add doesn't have conflict, listen has tls, no conflict expected", + existingRoutes: []*Route{ + { + Name: "route1", + Namespace: "default", + PathMatchCondition: prefixSegment("/path1"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: ":authority", MatchType: HeaderMatchTypeRegex, Value: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?\\.example\\.com(:[0-9]+)?"}, + }, + QueryParamMatchConditions: []QueryParamMatchCondition{ + {Name: "param-1", Value: "value-1", MatchType: QueryParamMatchTypeExact}, + }, + }, + { + Kind: KindHTTPRoute, + Name: "route2", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "version", Value: "2", MatchType: "exact", Invert: false}, + }, + }, + }, + routes: []*Route{ + { + Kind: KindHTTPRoute, + Name: "route3", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "e-tag", Value: "abc", MatchType: "contains", Invert: true}, + }, + }, + }, + listener: tlsListener, + }, + { + name: "There are 2 existing route, the 3rd route to add is conflict with 2nd route, listen doesn't have tls, expect conflicts", + existingRoutes: []*Route{ + { + Name: "route1", + Namespace: "default", + PathMatchCondition: prefixSegment("/path1"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: ":authority", MatchType: HeaderMatchTypeRegex, Value: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?\\.example\\.com(:[0-9]+)?"}, + }, + }, + { + Kind: KindHTTPRoute, + Name: "route2", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "version", Value: "2", MatchType: "exact", Invert: false}, + }, + QueryParamMatchConditions: []QueryParamMatchCondition{ + {Name: "param-1", Value: "value-1", MatchType: QueryParamMatchTypeExact}, + }, + }, + }, + routes: []*Route{ + { + Kind: KindHTTPRoute, + Name: "route3", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "version", Value: "2", MatchType: "exact", Invert: false}, + }, + QueryParamMatchConditions: []QueryParamMatchCondition{ + {Name: "param-1", Value: "value-1", MatchType: QueryParamMatchTypeExact}, + }, + }, + }, + listener: listener, + expectedConflict: true, + }, + { + name: "There are 1 existing route, the 2nd route to add is conflict with 1st route, listen has tls, expect conflicts", + existingRoutes: []*Route{ + { + Kind: KindHTTPRoute, + Name: "route1", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "version", Value: "2", MatchType: "exact", Invert: false}, + }, + QueryParamMatchConditions: []QueryParamMatchCondition{ + {Name: "param-1", Value: "value-1", MatchType: QueryParamMatchTypeExact}, + }, + }, + }, + routes: []*Route{ + { + Kind: KindHTTPRoute, + Name: "route2", + Namespace: "default", + PathMatchCondition: prefixSegment("/path2"), + HeaderMatchConditions: []HeaderMatchCondition{ + {Name: "version", Value: "2", MatchType: "exact", Invert: false}, + }, + QueryParamMatchConditions: []QueryParamMatchCondition{ + {Name: "param-1", Value: "value-1", MatchType: QueryParamMatchTypeExact}, + }, + }, + }, + listener: tlsListener, + expectedConflict: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + processor := &GatewayAPIProcessor{ + FieldLogger: fixture.NewTestLogger(t), + dag: &DAG{ + Listeners: map[string]*Listener{ + tlsListener.dagListenerName: { + svhostsByName: map[string]*SecureVirtualHost{ + host1: { + VirtualHost: VirtualHost{ + Name: host1, + Routes: make(map[string]*Route), + }, + }, + }, + }, + listener.dagListenerName: { + vhostsByName: map[string]*VirtualHost{ + host2: { + Routes: make(map[string]*Route), + }, + }, + }, + }, + }, + } + for host := range hosts { + for _, route := range tc.existingRoutes { + switch { + case tc.listener.tlsSecret != nil: + svhost := processor.dag.EnsureSecureVirtualHost(tc.listener.dagListenerName, host) + svhost.Secret = listener.tlsSecret + svhost.AddRoute(route) + default: + vhost := processor.dag.EnsureVirtualHost(tc.listener.dagListenerName, host) + vhost.AddRoute(route) + } + } + } + + res := processor.hasConflictRoute(tc.listener, hosts, tc.routes) + assert.Equal(t, tc.expectedConflict, res) + }) + } +} diff --git a/internal/dag/httpproxy_processor.go b/internal/dag/httpproxy_processor.go index 7dac1510315..083fd741353 100644 --- a/internal/dag/httpproxy_processor.go +++ b/internal/dag/httpproxy_processor.go @@ -114,7 +114,7 @@ type HTTPProxyProcessor struct { SetSourceMetadataOnRoutes bool // GlobalCircuitBreakerDefaults defines global circuit breaker defaults. - GlobalCircuitBreakerDefaults *contour_v1alpha1.GlobalCircuitBreakerDefaults + GlobalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers // UpstreamTLS defines the TLS settings like min/max version // and cipher suites for upstream connections. diff --git a/internal/dag/ingress_processor.go b/internal/dag/ingress_processor.go index d5dd05e5bed..63639e22712 100644 --- a/internal/dag/ingress_processor.go +++ b/internal/dag/ingress_processor.go @@ -68,7 +68,7 @@ type IngressProcessor struct { SetSourceMetadataOnRoutes bool // GlobalCircuitBreakerDefaults defines global circuit breaker defaults. - GlobalCircuitBreakerDefaults *contour_v1alpha1.GlobalCircuitBreakerDefaults + GlobalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers // UpstreamTLS defines the TLS settings like min/max version // and cipher suites for upstream connections. diff --git a/internal/dag/policy.go b/internal/dag/policy.go index 1c1ea5ea6f2..720d959e534 100644 --- a/internal/dag/policy.go +++ b/internal/dag/policy.go @@ -28,7 +28,6 @@ import ( "k8s.io/apimachinery/pkg/util/validation" "k8s.io/utils/ptr" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" @@ -254,7 +253,7 @@ func headersPolicyGatewayAPI(hf *gatewayapi_v1.HTTPHeaderFilter, headerPolicyTyp continue } if key == "Host" && (headerPolicyType == string(gatewayapi_v1.HTTPRouteFilterRequestHeaderModifier) || - headerPolicyType == string(gatewayapi_v1alpha2.GRPCRouteFilterRequestHeaderModifier)) { + headerPolicyType == string(gatewayapi_v1.GRPCRouteFilterRequestHeaderModifier)) { hostRewrite = header.Value continue } @@ -809,25 +808,29 @@ func loadBalancerRequestHashPolicies(lbp *contour_v1.LoadBalancerPolicy, validCo } } -func serviceCircuitBreakerPolicy(s *Service, cb *contour_v1alpha1.GlobalCircuitBreakerDefaults) *Service { +func serviceCircuitBreakerPolicy(s *Service, cb *contour_v1alpha1.CircuitBreakers) *Service { if s == nil { return nil } - if s.MaxConnections == 0 && cb != nil { - s.MaxConnections = cb.MaxConnections + if s.CircuitBreakers.MaxConnections == 0 && cb != nil { + s.CircuitBreakers.MaxConnections = cb.MaxConnections } - if s.MaxPendingRequests == 0 && cb != nil { - s.MaxPendingRequests = cb.MaxPendingRequests + if s.CircuitBreakers.MaxPendingRequests == 0 && cb != nil { + s.CircuitBreakers.MaxPendingRequests = cb.MaxPendingRequests } - if s.MaxRequests == 0 && cb != nil { - s.MaxRequests = cb.MaxRequests + if s.CircuitBreakers.MaxRequests == 0 && cb != nil { + s.CircuitBreakers.MaxRequests = cb.MaxRequests } - if s.MaxRetries == 0 && cb != nil { - s.MaxRetries = cb.MaxRetries + if s.CircuitBreakers.MaxRetries == 0 && cb != nil { + s.CircuitBreakers.MaxRetries = cb.MaxRetries + } + + if s.CircuitBreakers.PerHostMaxConnections == 0 && cb != nil { + s.CircuitBreakers.PerHostMaxConnections = cb.PerHostMaxConnections } return s diff --git a/internal/dag/policy_test.go b/internal/dag/policy_test.go index 62301bbb1d6..ab006db9b57 100644 --- a/internal/dag/policy_test.go +++ b/internal/dag/policy_test.go @@ -1276,7 +1276,7 @@ func TestValidateHeaderAlteration(t *testing.T) { func TestServiceCircuitBreakerPolicy(t *testing.T) { tests := map[string]struct { in *Service - globalDefault *contour_v1alpha1.GlobalCircuitBreakerDefaults + globalDefault *contour_v1alpha1.CircuitBreakers want *Service }{ "service is nil and globalDefault is nil": { @@ -1286,51 +1286,65 @@ func TestServiceCircuitBreakerPolicy(t *testing.T) { }, "service is nil and globalDefault is not nil": { in: nil, - globalDefault: &contour_v1alpha1.GlobalCircuitBreakerDefaults{}, + globalDefault: &contour_v1alpha1.CircuitBreakers{}, want: nil, }, "service is not nil and globalDefault is nil": { in: &Service{ - MaxConnections: 42, - MaxPendingRequests: 73, - MaxRequests: 89, - MaxRetries: 13, + CircuitBreakers: CircuitBreakers{ + MaxConnections: 42, + MaxPendingRequests: 73, + MaxRequests: 89, + MaxRetries: 13, + PerHostMaxConnections: 23, + }, }, globalDefault: nil, want: &Service{ - MaxConnections: 42, - MaxPendingRequests: 73, - MaxRequests: 89, - MaxRetries: 13, + CircuitBreakers: CircuitBreakers{ + MaxConnections: 42, + MaxPendingRequests: 73, + MaxRequests: 89, + MaxRetries: 13, + PerHostMaxConnections: 23, + }, }, }, "service is not set but global is": { in: &Service{}, - globalDefault: &contour_v1alpha1.GlobalCircuitBreakerDefaults{ - MaxConnections: 42, - MaxPendingRequests: 73, - MaxRequests: 89, - MaxRetries: 13, + globalDefault: &contour_v1alpha1.CircuitBreakers{ + MaxConnections: 42, + MaxPendingRequests: 73, + MaxRequests: 89, + MaxRetries: 13, + PerHostMaxConnections: 23, }, want: &Service{ - MaxConnections: 42, - MaxPendingRequests: 73, - MaxRequests: 89, - MaxRetries: 13, + CircuitBreakers: CircuitBreakers{ + MaxConnections: 42, + MaxPendingRequests: 73, + MaxRequests: 89, + MaxRetries: 13, + PerHostMaxConnections: 23, + }, }, }, "service is not set but global is partial": { in: &Service{}, - globalDefault: &contour_v1alpha1.GlobalCircuitBreakerDefaults{ - MaxConnections: 42, - MaxPendingRequests: 73, - MaxRequests: 89, + globalDefault: &contour_v1alpha1.CircuitBreakers{ + MaxConnections: 42, + MaxPendingRequests: 73, + MaxRequests: 89, + PerHostMaxConnections: 23, }, want: &Service{ - MaxConnections: 42, - MaxPendingRequests: 73, - MaxRequests: 89, - MaxRetries: 0, + CircuitBreakers: CircuitBreakers{ + MaxConnections: 42, + MaxPendingRequests: 73, + MaxRequests: 89, + MaxRetries: 0, + PerHostMaxConnections: 23, + }, }, }, } diff --git a/internal/dag/status_test.go b/internal/dag/status_test.go index 4272f49b29e..cefc5a79836 100644 --- a/internal/dag/status_test.go +++ b/internal/dag/status_test.go @@ -16,6 +16,7 @@ package dag import ( "fmt" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -28,6 +29,7 @@ import ( "k8s.io/utils/ptr" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -5510,7 +5512,8 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { "test.projectcontour.io", }, Rules: []gatewayapi_v1.HTTPRouteRule{{ - Matches: gatewayapi.HTTPRouteMatch(gatewayapi_v1.PathMatchPathPrefix, "/"), + // changed to different matches in case there is conflict with above HTTPRoute + Matches: gatewayapi.HTTPRouteMatch(gatewayapi_v1.PathMatchExact, "/"), BackendRefs: gatewayapi.HTTPBackendRef("kuard", 8080, 1), }}, }, @@ -5545,6 +5548,215 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { wantGatewayStatusUpdate: validGatewayStatusUpdate("http", gatewayapi_v1.HTTPProtocolType, 2), }) + run(t, "3 httproutes, but duplicate match condition between these 3. The 2 rank lower gets Conflict condition ", testcase{ + objs: []any{ + kuardService, + // first HTTPRoute with oldest creationTimestamp + &gatewayapi_v1.HTTPRoute{ + TypeMeta: meta_v1.TypeMeta{ + Kind: KindHTTPRoute, + }, + ObjectMeta: meta_v1.ObjectMeta{ + Name: "basic-1", + Namespace: "default", + CreationTimestamp: meta_v1.Date(2020, time.Month(2), 21, 1, 10, 30, 0, time.UTC), + }, + Spec: gatewayapi_v1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, + }, + Hostnames: []gatewayapi_v1.Hostname{ + "test.projectcontour.io", + }, + Rules: []gatewayapi_v1.HTTPRouteRule{{ + Matches: []gatewayapi_v1.HTTPRouteMatch{ + { + Path: &gatewayapi_v1.HTTPPathMatch{ + Type: ptr.To(gatewayapi_v1.PathMatchPathPrefix), + Value: ptr.To("/"), + }, + Headers: []gatewayapi_v1.HTTPHeaderMatch{ + { + Type: ptr.To(gatewayapi_v1.HeaderMatchExact), + Name: gatewayapi_v1.HTTPHeaderName("foo"), + Value: "bar", + }, + }, + QueryParams: []gatewayapi_v1.HTTPQueryParamMatch{ + { + Type: ptr.To(gatewayapi_v1.QueryParamMatchRegularExpression), + Name: "param-1", + Value: "valid-[a-z]?-[A-Za-z]+-[0=9]+-\\d+", + }, + }, + }, + { + Path: &gatewayapi_v1.HTTPPathMatch{ + Type: ptr.To(gatewayapi_v1.PathMatchPathPrefix), + Value: ptr.To("/"), + }, + Headers: []gatewayapi_v1.HTTPHeaderMatch{ + { + Type: ptr.To(gatewayapi_v1.HeaderMatchExact), + Name: gatewayapi_v1.HTTPHeaderName("a"), + Value: "b", + }, + }, + }, + }, + + BackendRefs: gatewayapi.HTTPBackendRef("kuard", 8080, 1), + }}, + }, + }, + // second HTTPRoute with 2nd oldest creationTimestamp, conflict with 1st HTTPRoute + &gatewayapi_v1.HTTPRoute{ + TypeMeta: meta_v1.TypeMeta{ + Kind: KindHTTPRoute, + }, + ObjectMeta: meta_v1.ObjectMeta{ + Name: "basic-2", + Namespace: "default", + CreationTimestamp: meta_v1.Date(2021, time.Month(2), 21, 1, 10, 30, 0, time.UTC), + }, + Spec: gatewayapi_v1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, + }, + Hostnames: []gatewayapi_v1.Hostname{ + "test.projectcontour.io", + }, + Rules: []gatewayapi_v1.HTTPRouteRule{{ + Matches: []gatewayapi_v1.HTTPRouteMatch{ + { + Path: &gatewayapi_v1.HTTPPathMatch{ + Type: ptr.To(gatewayapi_v1.PathMatchPathPrefix), + Value: ptr.To("/"), + }, + Headers: []gatewayapi_v1.HTTPHeaderMatch{ + { + Type: ptr.To(gatewayapi_v1.HeaderMatchExact), + Name: gatewayapi_v1.HTTPHeaderName("a"), + Value: "b", + }, + }, + }, + }, + + BackendRefs: gatewayapi.HTTPBackendRef("kuard", 8080, 1), + }}, + }, + }, + // 3rd HTTPRoute with newest creationTimestamp, partially conflict with 1st HTTPRoute + &gatewayapi_v1.HTTPRoute{ + TypeMeta: meta_v1.TypeMeta{ + Kind: KindHTTPRoute, + }, + ObjectMeta: meta_v1.ObjectMeta{ + Name: "basic-3", + Namespace: "default", + CreationTimestamp: meta_v1.Date(2022, time.Month(2), 21, 1, 10, 30, 0, time.UTC), + }, + Spec: gatewayapi_v1.HTTPRouteSpec{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, + }, + Hostnames: []gatewayapi_v1.Hostname{ + "test.projectcontour.io", + }, + Rules: []gatewayapi_v1.HTTPRouteRule{ + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + { + Path: &gatewayapi_v1.HTTPPathMatch{ + Type: ptr.To(gatewayapi_v1.PathMatchPathPrefix), + Value: ptr.To("/"), + }, + Headers: []gatewayapi_v1.HTTPHeaderMatch{ + { + Type: ptr.To(gatewayapi_v1.HeaderMatchExact), + Name: gatewayapi_v1.HTTPHeaderName("foo"), + Value: "bar", + }, + }, + QueryParams: []gatewayapi_v1.HTTPQueryParamMatch{ + { + Type: ptr.To(gatewayapi_v1.QueryParamMatchRegularExpression), + Name: "param-1", + Value: "valid-[a-z]?-[A-Za-z]+-[0=9]+-\\d+", + }, + }, + }, + }, + + BackendRefs: gatewayapi.HTTPBackendRef("kuard", 8080, 1), + }, + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + { + Path: &gatewayapi_v1.HTTPPathMatch{ + Type: ptr.To(gatewayapi_v1.PathMatchPathPrefix), + Value: ptr.To("/random"), + }, + Headers: []gatewayapi_v1.HTTPHeaderMatch{ + { + Type: ptr.To(gatewayapi_v1.HeaderMatchExact), + Name: gatewayapi_v1.HTTPHeaderName("random"), + Value: "b", + }, + }, + }, + }, + + BackendRefs: gatewayapi.HTTPBackendRef("kuard", 8080, 1), + }, + }, + }, + }, + }, + wantRouteConditions: []*status.RouteStatusUpdate{ + { + FullName: types.NamespacedName{Namespace: "default", Name: "basic-1"}, + RouteParentStatuses: []*gatewayapi_v1.RouteParentStatus{ + { + ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), + Conditions: []meta_v1.Condition{ + routeResolvedRefsCondition(), + routeAcceptedHTTPRouteCondition(), + }, + }, + }, + }, + { + FullName: types.NamespacedName{Namespace: "default", Name: "basic-2"}, + RouteParentStatuses: []*gatewayapi_v1.RouteParentStatus{ + { + ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), + Conditions: []meta_v1.Condition{ + routeAcceptedFalse(status.ReasonRouteRuleMatchConflict, fmt.Sprintf(status.MessageRouteRuleMatchConflict, KindHTTPRoute, KindHTTPRoute)), + routeResolvedRefsCondition(), + }, + }, + }, + }, + { + FullName: types.NamespacedName{Namespace: "default", Name: "basic-3"}, + RouteParentStatuses: []*gatewayapi_v1.RouteParentStatus{ + { + ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), + Conditions: []meta_v1.Condition{ + routeAcceptedHTTPRouteCondition(), + routePartialMatchConflict(status.ReasonRouteRuleMatchPartiallyConflict, fmt.Sprintf(status.MessageRouteRuleMatchPartiallyConflict, KindHTTPRoute, KindHTTPRoute)), + routeResolvedRefsCondition(), + }, + }, + }, + }, + }, + // is it ok to show the listeners are attached, just it's not accepted because of the conflict + wantGatewayStatusUpdate: validGatewayStatusUpdate("http", gatewayapi_v1.HTTPProtocolType, 3), + }) + run(t, "prefix path match not starting with '/' for httproute", testcase{ objs: []any{ kuardService, @@ -9441,7 +9653,7 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { }, }) - run(t, "route rule with timeouts.request and timeouts.backendRequest specified", testcase{ + run(t, "route rule with timeouts.backendRequest greater than timeouts.request", testcase{ objs: []any{ kuardService, &gatewayapi_v1.HTTPRoute{ @@ -9462,7 +9674,7 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { BackendRefs: gatewayapi.HTTPBackendRef("kuard", 8080, 1), Timeouts: &gatewayapi_v1.HTTPRouteTimeouts{ Request: ptr.To(gatewayapi_v1.Duration("30s")), - BackendRequest: ptr.To(gatewayapi_v1.Duration("30s")), + BackendRequest: ptr.To(gatewayapi_v1.Duration("60s")), }, }, }, @@ -9477,7 +9689,7 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), Conditions: []meta_v1.Condition{ routeResolvedRefsCondition(), - routeAcceptedFalse(gatewayapi_v1.RouteReasonUnsupportedValue, "HTTPRoute.Spec.Rules.Timeouts.BackendRequest is not supported, use HTTPRoute.Spec.Rules.Timeouts.Request instead"), + routeAcceptedFalse(gatewayapi_v1.RouteReasonUnsupportedValue, "HTTPRoute.Spec.Rules.Timeouts.BackendRequest must be less than/equal to HTTPRoute.Spec.Rules.Timeouts.Request when both are specified"), }, }, }, @@ -9486,7 +9698,7 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { wantGatewayStatusUpdate: validGatewayStatusUpdate("http", gatewayapi_v1.HTTPProtocolType, 1), }) - run(t, "route rule with only timeouts.backendRequest specified", testcase{ + run(t, "route rule with invalid timeouts.backendRequest specified", testcase{ objs: []any{ kuardService, &gatewayapi_v1.HTTPRoute{ @@ -9506,7 +9718,7 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { Matches: gatewayapi.HTTPRouteMatch(gatewayapi_v1.PathMatchPathPrefix, "/"), BackendRefs: gatewayapi.HTTPBackendRef("kuard", 8080, 1), Timeouts: &gatewayapi_v1.HTTPRouteTimeouts{ - BackendRequest: ptr.To(gatewayapi_v1.Duration("30s")), + BackendRequest: ptr.To(gatewayapi_v1.Duration("invalid")), }, }, }, @@ -9520,7 +9732,7 @@ func TestGatewayAPIHTTPRouteDAGStatus(t *testing.T) { ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), Conditions: []meta_v1.Condition{ routeResolvedRefsCondition(), - routeAcceptedFalse(gatewayapi_v1.RouteReasonUnsupportedValue, "HTTPRoute.Spec.Rules.Timeouts.BackendRequest is not supported, use HTTPRoute.Spec.Rules.Timeouts.Request instead"), + routeAcceptedFalse(gatewayapi_v1.RouteReasonUnsupportedValue, "invalid HTTPRoute.Spec.Rules.Timeouts.BackendRequest: unable to parse timeout string \"invalid\": time: invalid duration \"invalid\""), }, }, }, @@ -9702,16 +9914,16 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ - BackendRefs: []gatewayapi_v1alpha2.BackendRef{ + BackendRefs: []gatewayapi_v1.BackendRef{ { - BackendObjectReference: gatewayapi_v1alpha2.BackendObjectReference{ + BackendObjectReference: gatewayapi_v1.BackendObjectReference{ Kind: ptr.To(gatewayapi_v1.Kind("Service")), Port: ptr.To(gatewayapi_v1.PortNumber(8080)), }, @@ -9750,12 +9962,12 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{ {BackendRefs: gatewayapi.TLSRouteBackendRef("invalid-one", 8080, nil)}, {BackendRefs: gatewayapi.TLSRouteBackendRef("invalid-two", 8080, nil)}, @@ -9795,16 +10007,16 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ - BackendRefs: []gatewayapi_v1alpha2.BackendRef{ + BackendRefs: []gatewayapi_v1.BackendRef{ { - BackendObjectReference: gatewayapi_v1alpha2.BackendObjectReference{ + BackendObjectReference: gatewayapi_v1.BackendObjectReference{ Kind: ptr.To(gatewayapi_v1.Kind("Service")), Name: "kuard", }, @@ -9844,15 +10056,15 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, Rules: []gatewayapi_v1alpha2.TLSRouteRule{ {}, // rule with no backend refs }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, }, }, }, @@ -9886,12 +10098,12 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"*.*.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"*.*.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("kuard", 8080, nil), }}, @@ -9930,12 +10142,12 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"#projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"#projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("kuard", 8080, nil), }}, @@ -9974,12 +10186,12 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"1.2.3.4"}, + Hostnames: []gatewayapi_v1.Hostname{"1.2.3.4"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("kuard", 8080, nil), }}, @@ -10016,12 +10228,12 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef(gw.Namespace, gw.Name), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef(kuardService.Name, 8080, ptr.To(int32(0))), }}, @@ -10064,13 +10276,13 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ // Wrong port. gatewayapi.GatewayListenerParentRef(gw.Namespace, gw.Name, "tls-passthrough", 444), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("invalid-one", 8080, nil), }}, @@ -10132,12 +10344,12 @@ func TestGatewayAPITLSRouteDAGStatus(t *testing.T) { Namespace: "default", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayListenerParentRef(gw.Namespace, gw.Name, "tls", 443), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("kuard", 8080, nil), }}, @@ -10349,21 +10561,21 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "simple grpcroute", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), }}, @@ -10388,22 +10600,22 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: regular expression method match type is not yet supported", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ + Rules: []gatewayapi_v1.GRPCRouteRule{{ // RegularExpression type not yet supported - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchRegularExpression, "com.example.service", "Login"), + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchRegularExpression, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), }}, @@ -10433,21 +10645,21 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: method match must have Service configured", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), }}, @@ -10477,21 +10689,21 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: method match must have Method configured", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", ""), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", ""), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), }}, @@ -10521,29 +10733,29 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: invalid header match type is not supported", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: &gatewayapi_v1alpha2.GRPCMethodMatch{ - Type: ptr.To(gatewayapi_v1alpha2.GRPCMethodMatchExact), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: &gatewayapi_v1.GRPCMethodMatch{ + Type: ptr.To(gatewayapi_v1.GRPCMethodMatchExact), Service: ptr.To("come.example.service"), Method: ptr.To("Login"), }, - Headers: []gatewayapi_v1alpha2.GRPCHeaderMatch{ + Headers: []gatewayapi_v1.GRPCHeaderMatch{ { Type: ptr.To(gatewayapi_v1.HeaderMatchType("UNKNOWN")), // <---- unknown type to break the test - Name: gatewayapi_v1alpha2.GRPCHeaderName("foo"), + Name: gatewayapi_v1.GRPCHeaderName("foo"), Value: "bar", }, }, @@ -10576,29 +10788,29 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: regular expression header match has invalid value", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: &gatewayapi_v1alpha2.GRPCMethodMatch{ - Type: ptr.To(gatewayapi_v1alpha2.GRPCMethodMatchExact), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: &gatewayapi_v1.GRPCMethodMatch{ + Type: ptr.To(gatewayapi_v1.GRPCMethodMatchExact), Service: ptr.To("come.example.service"), Method: ptr.To("Login"), }, - Headers: []gatewayapi_v1alpha2.GRPCHeaderMatch{ + Headers: []gatewayapi_v1.GRPCHeaderMatch{ { Type: ptr.To(gatewayapi_v1.HeaderMatchRegularExpression), - Name: gatewayapi_v1alpha2.GRPCHeaderName("foo"), + Name: gatewayapi_v1.GRPCHeaderName("foo"), Value: "invalid(-)regex)", }, }, @@ -10631,25 +10843,25 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: invalid RequestHeaderModifier due to duplicated headers", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{{ - Type: gatewayapi_v1alpha2.GRPCRouteFilterRequestHeaderModifier, + Filters: []gatewayapi_v1.GRPCRouteFilter{{ + Type: gatewayapi_v1.GRPCRouteFilterRequestHeaderModifier, RequestHeaderModifier: &gatewayapi_v1.HTTPHeaderFilter{ Set: []gatewayapi_v1.HTTPHeader{ {Name: "custom", Value: "duplicated"}, @@ -10680,25 +10892,25 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: invalid ResponseHeaderModifier due to invalid headers", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{{ - Type: gatewayapi_v1alpha2.GRPCRouteFilterResponseHeaderModifier, + Filters: []gatewayapi_v1.GRPCRouteFilter{{ + Type: gatewayapi_v1.GRPCRouteFilterResponseHeaderModifier, ResponseHeaderModifier: &gatewayapi_v1.HTTPHeaderFilter{ Add: []gatewayapi_v1.HTTPHeader{ {Name: "!invalid-header", Value: "foo"}, @@ -10732,31 +10944,31 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { kuardService, kuardService2, kuardService3, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{ + Filters: []gatewayapi_v1.GRPCRouteFilter{ { - Type: gatewayapi_v1alpha2.GRPCRouteFilterRequestMirror, + Type: gatewayapi_v1.GRPCRouteFilterRequestMirror, RequestMirror: &gatewayapi_v1.HTTPRequestMirrorFilter{ BackendRef: gatewayapi.ServiceBackendObjectRef("kuard2", 8080), }, }, { - Type: gatewayapi_v1alpha2.GRPCRouteFilterRequestMirror, + Type: gatewayapi_v1.GRPCRouteFilterRequestMirror, RequestMirror: &gatewayapi_v1.HTTPRequestMirrorFilter{ BackendRef: gatewayapi.ServiceBackendObjectRef("kuard3", 8080), }, @@ -10785,25 +10997,25 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { objs: []any{ kuardService, kuardService2, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{{ - Type: gatewayapi_v1alpha2.GRPCRouteFilterRequestMirror, + Filters: []gatewayapi_v1.GRPCRouteFilter{{ + Type: gatewayapi_v1.GRPCRouteFilterRequestMirror, RequestMirror: &gatewayapi_v1.HTTPRequestMirrorFilter{ BackendRef: gatewayapi_v1.BackendObjectReference{ Group: ptr.To(gatewayapi_v1.Group("")), @@ -10835,24 +11047,24 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: custom filter type is not supported", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{{ + Filters: []gatewayapi_v1.GRPCRouteFilter{{ Type: "custom-filter", }}, }}, @@ -10883,24 +11095,24 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: at lease one backend need to be specified", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{ + Rules: []gatewayapi_v1.GRPCRouteRule{ { - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, - BackendRefs: []gatewayapi_v1alpha2.GRPCBackendRef{}, + BackendRefs: []gatewayapi_v1.GRPCBackendRef{}, }, }, }, @@ -10924,14 +11136,14 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: still validate backendrefs when not accepted", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + ParentRefs: []gatewayapi_v1.ParentReference{ // Wrong port. gatewayapi.GatewayListenerParentRef("projectcontour", "contour", "http", 900), }, @@ -10939,9 +11151,9 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, BackendRefs: gatewayapi.GRPCRouteBackendRef("invalid", 8080, 1), }}, @@ -10976,30 +11188,30 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: invalid RequestHeaderModifier on backend due to duplicated headers", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{ + Rules: []gatewayapi_v1.GRPCRouteRule{ { - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, - BackendRefs: []gatewayapi_v1alpha2.GRPCBackendRef{ + BackendRefs: []gatewayapi_v1.GRPCBackendRef{ { BackendRef: gatewayapi_v1.BackendRef{ BackendObjectReference: gatewayapi.ServiceBackendObjectRef("kuard", 8080), }, - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{{ - Type: gatewayapi_v1alpha2.GRPCRouteFilterRequestHeaderModifier, + Filters: []gatewayapi_v1.GRPCRouteFilter{{ + Type: gatewayapi_v1.GRPCRouteFilterRequestHeaderModifier, RequestHeaderModifier: &gatewayapi_v1.HTTPHeaderFilter{ Set: []gatewayapi_v1.HTTPHeader{ {Name: "custom", Value: "duplicated"}, @@ -11033,29 +11245,29 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { run(t, "grpcroute: invalid ResponseHeaderModifier on backend due to invalid headers", testcase{ objs: []any{ kuardService, - &gatewayapi_v1alpha2.GRPCRoute{ + &gatewayapi_v1.GRPCRoute{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.GRPCRouteSpec{ + Spec: gatewayapi_v1.GRPCRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, }, Hostnames: []gatewayapi_v1.Hostname{ "test.projectcontour.io", }, - Rules: []gatewayapi_v1alpha2.GRPCRouteRule{{ - Matches: []gatewayapi_v1alpha2.GRPCRouteMatch{{ - Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1alpha2.GRPCMethodMatchExact, "com.example.service", "Login"), + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{{ + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), }}, - BackendRefs: []gatewayapi_v1alpha2.GRPCBackendRef{ + BackendRefs: []gatewayapi_v1.GRPCBackendRef{ { BackendRef: gatewayapi_v1.BackendRef{ BackendObjectReference: gatewayapi.ServiceBackendObjectRef("kuard", 8080), }, - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{{ - Type: gatewayapi_v1alpha2.GRPCRouteFilterResponseHeaderModifier, + Filters: []gatewayapi_v1.GRPCRouteFilter{{ + Type: gatewayapi_v1.GRPCRouteFilterResponseHeaderModifier, ResponseHeaderModifier: &gatewayapi_v1.HTTPHeaderFilter{ Set: []gatewayapi_v1.HTTPHeader{ {Name: "!invalid-header", Value: "foo"}, @@ -11085,6 +11297,148 @@ func TestGatewayAPIGRPCRouteDAGStatus(t *testing.T) { // Invalid filters still result in an attached route. wantGatewayStatusUpdate: validGatewayStatusUpdate("http", gatewayapi_v1.HTTPProtocolType, 1), }) + + run(t, "grpcroute: 3 grpcroutes, but duplicate match condition between these 3. The 2 out of 3 rank lower gets Conflict condition ", testcase{ + objs: []any{ + kuardService, + // first GRPCRoute with oldest creationTimestamp + &gatewayapi_v1.GRPCRoute{ + TypeMeta: meta_v1.TypeMeta{ + Kind: KindGRPCRoute, + }, + ObjectMeta: meta_v1.ObjectMeta{ + Name: "basic-1", + Namespace: "default", + CreationTimestamp: meta_v1.Date(2020, time.Month(2), 21, 1, 10, 30, 0, time.UTC), + }, + Spec: gatewayapi_v1.GRPCRouteSpec{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, + }, + Hostnames: []gatewayapi_v1.Hostname{ + "test.projectcontour.io", + }, + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "ok.service", "Login"), + }, + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "foo.ok.service", "Login"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), + }}, + }, + }, + // second GRPCRoute with 2nd oldest creationTimestamp, conflict with 1st GRPCRoute + &gatewayapi_v1.GRPCRoute{ + TypeMeta: meta_v1.TypeMeta{ + Kind: KindGRPCRoute, + }, + ObjectMeta: meta_v1.ObjectMeta{ + Name: "basic-2", + Namespace: "default", + CreationTimestamp: meta_v1.Date(2021, time.Month(2), 21, 1, 10, 30, 0, time.UTC), + }, + Spec: gatewayapi_v1.GRPCRouteSpec{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, + }, + Hostnames: []gatewayapi_v1.Hostname{ + "test.projectcontour.io", + }, + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "ok.service", "Login"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), + }}, + }, + }, + // 3rd GRPCRoute with newest creationTimestamp, partially conflict with 1st GRPCRoute + &gatewayapi_v1.GRPCRoute{ + TypeMeta: meta_v1.TypeMeta{ + Kind: KindGRPCRoute, + }, + ObjectMeta: meta_v1.ObjectMeta{ + Name: "basic-3", + Namespace: "default", + CreationTimestamp: meta_v1.Date(2022, time.Month(2), 21, 1, 10, 30, 0, time.UTC), + }, + Spec: gatewayapi_v1.GRPCRouteSpec{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{gatewayapi.GatewayParentRef("projectcontour", "contour")}, + }, + Hostnames: []gatewayapi_v1.Hostname{ + "test.projectcontour.io", + }, + Rules: []gatewayapi_v1.GRPCRouteRule{ + { + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "foo.ok.service", "Login"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), + }, + { + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "bar.ok.service", "Logout"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("kuard", 8080, 1), + }, + }, + }, + }, + }, + + wantRouteConditions: []*status.RouteStatusUpdate{ + { + FullName: types.NamespacedName{Namespace: "default", Name: "basic-1"}, + RouteParentStatuses: []*gatewayapi_v1.RouteParentStatus{ + { + ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), + Conditions: []meta_v1.Condition{ + routeResolvedRefsCondition(), + routeAcceptedGRPCRouteCondition(), + }, + }, + }, + }, + { + FullName: types.NamespacedName{Namespace: "default", Name: "basic-2"}, + RouteParentStatuses: []*gatewayapi_v1.RouteParentStatus{ + { + ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), + Conditions: []meta_v1.Condition{ + routeAcceptedFalse(status.ReasonRouteRuleMatchConflict, fmt.Sprintf(status.MessageRouteRuleMatchConflict, KindGRPCRoute, KindGRPCRoute)), + routeResolvedRefsCondition(), + }, + }, + }, + }, + { + FullName: types.NamespacedName{Namespace: "default", Name: "basic-3"}, + RouteParentStatuses: []*gatewayapi_v1.RouteParentStatus{ + { + ParentRef: gatewayapi.GatewayParentRef("projectcontour", "contour"), + Conditions: []meta_v1.Condition{ + routeAcceptedGRPCRouteCondition(), + routePartialMatchConflict(status.ReasonRouteRuleMatchPartiallyConflict, fmt.Sprintf(status.MessageRouteRuleMatchPartiallyConflict, KindGRPCRoute, KindGRPCRoute)), + routeResolvedRefsCondition(), + }, + }, + }, + }, + }, + // is it ok to show the listeners are attached, just it's not accepted because of the conflict + wantGatewayStatusUpdate: validGatewayStatusUpdate("http", gatewayapi_v1.HTTPProtocolType, 3), + }) } func TestGatewayAPITCPRouteDAGStatus(t *testing.T) { @@ -11520,20 +11874,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "ConfigMap", Name: gatewayapi_v1.ObjectName(configMapCert1.Name), }}, @@ -11565,20 +11921,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "nonexistent", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "nonexistent", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "ConfigMap", Name: gatewayapi_v1.ObjectName(configMapCert1.Name), }}, @@ -11595,20 +11953,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "Invalid", Name: gatewayapi_v1.ObjectName(configMapCert1.Name), }}, @@ -11627,7 +11987,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "BackendTLSPolicy.Spec.TLS.CACertRef.Kind \"Invalid\" is unsupported. Only ConfigMap or Secret Kind is supported.", + Message: "BackendTLSPolicy.Spec.Validation.CACertificateRef.Kind \"Invalid\" is unsupported. Only ConfigMap or Secret Kind is supported.", }, }, }, @@ -11639,20 +11999,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { objs: []any{ tlsService, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "ConfigMap", Name: gatewayapi_v1.ObjectName("missing"), }}, @@ -11671,7 +12033,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "Could not find CACertRef ConfigMap: projectcontour/missing", + Message: "Could not find CACertificateRef ConfigMap: projectcontour/missing", }, }, }, @@ -11683,20 +12045,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { objs: []any{ tlsService, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "Secret", Name: gatewayapi_v1.ObjectName("missing"), }}, @@ -11715,7 +12079,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "Could not find CACertRef Secret: projectcontour/missing", + Message: "Could not find CACertificateRef Secret: projectcontour/missing", }, }, }, @@ -11728,20 +12092,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{ { Kind: "Invalid", Name: gatewayapi_v1.ObjectName(configMapCert1.Name), @@ -11770,7 +12136,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "BackendTLSPolicy.Spec.TLS.CACertRef.Kind \"Invalid\" is unsupported. Only ConfigMap or Secret Kind is supported., Could not find CACertRef ConfigMap: projectcontour/missing", + Message: "BackendTLSPolicy.Spec.Validation.CACertificateRef.Kind \"Invalid\" is unsupported. Only ConfigMap or Secret Kind is supported., Could not find CACertificateRef ConfigMap: projectcontour/missing", }, }, }, @@ -11783,21 +12149,23 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - WellKnownCACerts: ptr.To(gatewayapi_v1alpha2.WellKnownCACertSystem), - Hostname: "example.com", + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + WellKnownCACertificates: ptr.To(gatewayapi_v1alpha3.WellKnownCACertificatesSystem), + Hostname: "example.com", }, }, }, @@ -11812,7 +12180,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "BackendTLSPolicy.Spec.TLS.WellKnownCACerts is unsupported.", + Message: "BackendTLSPolicy.Spec.Validation.WellKnownCACertificates is unsupported.", }, }, }, @@ -11825,20 +12193,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "ConfigMap", Name: gatewayapi_v1.ObjectName(configMapCert1.Name), }}, @@ -11857,7 +12227,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "BackendTLSPolicy.Spec.TLS.Hostname \"-bad-hostname.example.com\" is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", + Message: "BackendTLSPolicy.Spec.Validation.Hostname \"-bad-hostname.example.com\" is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", }, }, }, @@ -11870,20 +12240,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "ConfigMap", Name: gatewayapi_v1.ObjectName(configMapCert1.Name), }}, @@ -11902,7 +12274,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "BackendTLSPolicy.Spec.TLS.Hostname \"*.example.com\" is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", + Message: "BackendTLSPolicy.Spec.Validation.Hostname \"*.example.com\" is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", }, }, }, @@ -11915,20 +12287,22 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { tlsService, configMapCert1, makeHTTPRoute("basic", "projectcontour", "", makeHTTPRouteRule(gatewayapi_v1.PathMatchPathPrefix, "/", "tlssvc", 443, 1)), - &gatewayapi_v1alpha2.BackendTLSPolicy{ + &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "basic", Namespace: "projectcontour", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "tlssvc", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "tlssvc", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "ConfigMap", Name: gatewayapi_v1.ObjectName(configMapCert1.Name), }}, @@ -11947,7 +12321,7 @@ func TestGatewayAPIBackendTLSPolicyDAGStatus(t *testing.T) { Type: string(gatewayapi_v1alpha2.PolicyConditionAccepted), Status: meta_v1.ConditionFalse, Reason: string(gatewayapi_v1alpha2.PolicyReasonInvalid), - Message: "BackendTLSPolicy.Spec.TLS.Hostname \"127.0.0.1\" is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", + Message: "BackendTLSPolicy.Spec.Validation.Hostname \"127.0.0.1\" is invalid. Hostname must be a valid RFC 1123 fully qualified domain name. Wildcard domains and numeric IP addresses are not allowed", }, }, }, @@ -11983,6 +12357,15 @@ func routeAcceptedHTTPRouteCondition() meta_v1.Condition { } } +func routePartialMatchConflict(reason gatewayapi_v1.RouteConditionReason, message string) meta_v1.Condition { + return meta_v1.Condition{ + Type: string(gatewayapi_v1.RouteConditionPartiallyInvalid), + Status: contour_v1.ConditionTrue, + Reason: string(reason), + Message: message, + } +} + func routeAcceptedFalse(reason gatewayapi_v1.RouteConditionReason, message string) meta_v1.Condition { return meta_v1.Condition{ Type: string(gatewayapi_v1.RouteConditionAccepted), diff --git a/internal/envoy/v3/bootstrap.go b/internal/envoy/v3/bootstrap.go index 2552dee7602..a70d3268c8f 100644 --- a/internal/envoy/v3/bootstrap.go +++ b/internal/envoy/v3/bootstrap.go @@ -219,12 +219,14 @@ func bootstrapConfig(c *envoy.BootstrapConfig) *envoy_config_bootstrap_v3.Bootst MaxPendingRequests: wrapperspb.UInt32(100000), MaxRequests: wrapperspb.UInt32(60000000), MaxRetries: wrapperspb.UInt32(50), + TrackRemaining: true, }, { Priority: envoy_config_core_v3.RoutingPriority_DEFAULT, MaxConnections: wrapperspb.UInt32(100000), MaxPendingRequests: wrapperspb.UInt32(100000), MaxRequests: wrapperspb.UInt32(60000000), MaxRetries: wrapperspb.UInt32(50), + TrackRemaining: true, }}, }, }, { diff --git a/internal/envoy/v3/bootstrap_test.go b/internal/envoy/v3/bootstrap_test.go index 2012179f900..cc1c9a9fd87 100644 --- a/internal/envoy/v3/bootstrap_test.go +++ b/internal/envoy/v3/bootstrap_test.go @@ -74,13 +74,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -253,13 +255,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -432,13 +436,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -612,13 +618,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -792,13 +800,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -972,13 +982,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -1153,13 +1165,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -1336,13 +1350,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -1553,13 +1569,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, @@ -1810,13 +1828,15 @@ func TestBootstrap(t *testing.T) { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true }, { "max_connections": 100000, "max_pending_requests": 100000, "max_requests": 60000000, - "max_retries": 50 + "max_retries": 50, + "track_remaining": true } ] }, diff --git a/internal/envoy/v3/cluster.go b/internal/envoy/v3/cluster.go index 8a388799b06..24346c48421 100644 --- a/internal/envoy/v3/cluster.go +++ b/internal/envoy/v3/cluster.go @@ -79,19 +79,7 @@ func Cluster(c *dag.Cluster) *envoy_config_cluster_v3.Cluster { cluster.IgnoreHealthOnHostRemoval = true } - if envoy.AnyPositive(service.MaxConnections, service.MaxPendingRequests, service.MaxRequests, service.MaxRetries, service.PerHostMaxConnections) { - cluster.CircuitBreakers = &envoy_config_cluster_v3.CircuitBreakers{ - Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ - MaxConnections: protobuf.UInt32OrNil(service.MaxConnections), - MaxPendingRequests: protobuf.UInt32OrNil(service.MaxPendingRequests), - MaxRequests: protobuf.UInt32OrNil(service.MaxRequests), - MaxRetries: protobuf.UInt32OrNil(service.MaxRetries), - }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ - MaxConnections: protobuf.UInt32OrNil(service.PerHostMaxConnections), - }}, - } - } + applyCircuitBreakers(cluster, service.CircuitBreakers) httpVersion := HTTPVersionAuto switch c.Protocol { @@ -196,9 +184,29 @@ func ExtensionCluster(ext *dag.ExtensionCluster) *envoy_config_cluster_v3.Cluste } cluster.TypedExtensionProtocolOptions = protocolOptions(http2Version, ext.ClusterTimeoutPolicy.IdleConnectionTimeout, nil) + applyCircuitBreakers(cluster, ext.CircuitBreakers) + return cluster } +func applyCircuitBreakers(cluster *envoy_config_cluster_v3.Cluster, settings dag.CircuitBreakers) { + if envoy.AnyPositive(settings.MaxConnections, settings.MaxPendingRequests, settings.MaxRequests, settings.MaxRetries, settings.PerHostMaxConnections) { + cluster.CircuitBreakers = &envoy_config_cluster_v3.CircuitBreakers{ + Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: protobuf.UInt32OrNil(settings.MaxConnections), + MaxPendingRequests: protobuf.UInt32OrNil(settings.MaxPendingRequests), + MaxRequests: protobuf.UInt32OrNil(settings.MaxRequests), + MaxRetries: protobuf.UInt32OrNil(settings.MaxRetries), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: protobuf.UInt32OrNil(settings.PerHostMaxConnections), + TrackRemaining: true, + }}, + } + } +} + // DNSNameCluster builds a envoy_config_cluster_v3.Cluster for the given *dag.DNSNameCluster. func DNSNameCluster(c *dag.DNSNameCluster) *envoy_config_cluster_v3.Cluster { cluster := clusterDefaults() diff --git a/internal/envoy/v3/cluster_test.go b/internal/envoy/v3/cluster_test.go index 79ea1525873..cc9f64bcec5 100644 --- a/internal/envoy/v3/cluster_test.go +++ b/internal/envoy/v3/cluster_test.go @@ -406,7 +406,9 @@ func TestCluster(t *testing.T) { "projectcontour.io/max-connections": { cluster: &dag.Cluster{ Upstream: &dag.Service{ - MaxConnections: 9000, + CircuitBreakers: dag.CircuitBreakers{ + MaxConnections: 9000, + }, Weighted: dag.WeightedService{ Weight: 1, ServiceName: s1.Name, @@ -427,15 +429,20 @@ func TestCluster(t *testing.T) { CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ MaxConnections: wrapperspb.UInt32(9000), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }, }, "projectcontour.io/max-pending-requests": { cluster: &dag.Cluster{ Upstream: &dag.Service{ - MaxPendingRequests: 4096, + CircuitBreakers: dag.CircuitBreakers{ + MaxPendingRequests: 4096, + }, Weighted: dag.WeightedService{ Weight: 1, ServiceName: s1.Name, @@ -456,15 +463,20 @@ func TestCluster(t *testing.T) { CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ MaxPendingRequests: wrapperspb.UInt32(4096), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }, }, "projectcontour.io/max-requests": { cluster: &dag.Cluster{ Upstream: &dag.Service{ - MaxRequests: 404, + CircuitBreakers: dag.CircuitBreakers{ + MaxRequests: 404, + }, Weighted: dag.WeightedService{ Weight: 1, ServiceName: s1.Name, @@ -484,16 +496,21 @@ func TestCluster(t *testing.T) { }, CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ - MaxRequests: wrapperspb.UInt32(404), + MaxRequests: wrapperspb.UInt32(404), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }, }, "projectcontour.io/max-retries": { cluster: &dag.Cluster{ Upstream: &dag.Service{ - MaxRetries: 7, + CircuitBreakers: dag.CircuitBreakers{ + MaxRetries: 7, + }, Weighted: dag.WeightedService{ Weight: 1, ServiceName: s1.Name, @@ -513,16 +530,21 @@ func TestCluster(t *testing.T) { }, CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ - MaxRetries: wrapperspb.UInt32(7), + MaxRetries: wrapperspb.UInt32(7), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }, }, "projectcontour.io/per-host-max-connections": { cluster: &dag.Cluster{ Upstream: &dag.Service{ - PerHostMaxConnections: 45, + CircuitBreakers: dag.CircuitBreakers{ + PerHostMaxConnections: 45, + }, Weighted: dag.WeightedService{ Weight: 1, ServiceName: s1.Name, @@ -541,9 +563,12 @@ func TestCluster(t *testing.T) { ServiceName: "default/kuard/http", }, CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ - Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, + Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, + }}, PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ MaxConnections: wrapperspb.UInt32(45), + TrackRemaining: true, }}, }, }, diff --git a/internal/envoy/v3/route.go b/internal/envoy/v3/route.go index ecc2a4934fa..0dc875082c6 100644 --- a/internal/envoy/v3/route.go +++ b/internal/envoy/v3/route.go @@ -122,6 +122,15 @@ func buildRoute(dagRoute *dag.Route, vhostName string, secure bool) *envoy_confi // redirect routes to *both* the insecure and secure vhosts. route.Action = UpgradeHTTPS() case dagRoute.DirectResponse != nil: + route.TypedPerFilterConfig = map[string]*anypb.Any{} + + // Apply per-route authorization policy modifications. + if dagRoute.AuthDisabled { + route.TypedPerFilterConfig["envoy.filters.http.ext_authz"] = routeAuthzDisabled() + } else if len(dagRoute.AuthContext) > 0 { + route.TypedPerFilterConfig["envoy.filters.http.ext_authz"] = routeAuthzContext(dagRoute.AuthContext) + } + route.Action = routeDirectResponse(dagRoute.DirectResponse) case dagRoute.Redirect != nil: // TODO request/response headers? diff --git a/internal/envoy/v3/route_test.go b/internal/envoy/v3/route_test.go index 2f91680d7e4..152776134ae 100644 --- a/internal/envoy/v3/route_test.go +++ b/internal/envoy/v3/route_test.go @@ -993,6 +993,81 @@ func TestRouteDirectResponse(t *testing.T) { } } +func TestBuildRouteWithDirectResponse(t *testing.T) { + tests := map[string]struct { + dagRoute *dag.Route + vhostName string + secure bool + want *envoy_config_route_v3.Route + }{ + "direct-response-with-auth": { + dagRoute: &dag.Route{ + DirectResponse: &dag.DirectResponse{ + StatusCode: 500, + Body: "Internal Server Error", + }, + AuthContext: map[string]string{ + "PrincipalName": "user", + }, + PathMatchCondition: &dag.PrefixMatchCondition{ + Prefix: "/foo", + PrefixMatchType: dag.PrefixMatchString, + }, + }, + vhostName: "example", + secure: true, + want: &envoy_config_route_v3.Route{ + TypedPerFilterConfig: map[string]*anypb.Any{ + "envoy.filters.http.ext_authz": routeAuthzContext(map[string]string{ + "PrincipalName": "user", + }), + }, + Action: routeDirectResponse(&dag.DirectResponse{ + StatusCode: 500, + Body: "Internal Server Error", + }), + Match: &envoy_config_route_v3.RouteMatch{ + PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{ + Prefix: "/foo", + }, + }, + }, + }, + "direct-response-auth-disabled": { + dagRoute: &dag.Route{ + DirectResponse: &dag.DirectResponse{ + StatusCode: 403, + }, + AuthDisabled: true, + PathMatchCondition: &dag.PrefixMatchCondition{ + Prefix: "/foo", + PrefixMatchType: dag.PrefixMatchString, + }, + }, + vhostName: "example", + secure: false, + want: &envoy_config_route_v3.Route{ + TypedPerFilterConfig: map[string]*anypb.Any{ + "envoy.filters.http.ext_authz": routeAuthzDisabled(), + }, + Action: routeDirectResponse(&dag.DirectResponse{StatusCode: 403}), + Match: &envoy_config_route_v3.RouteMatch{ + PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{ + Prefix: "/foo", + }, + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got := buildRoute(tc.dagRoute, tc.vhostName, tc.secure) + protobuf.ExpectEqual(t, tc.want, got) + }) + } +} + func TestWeightedClusters(t *testing.T) { tests := map[string]struct { route *dag.Route diff --git a/internal/envoy/v3/runtime.go b/internal/envoy/v3/runtime.go index 4429800693c..135eddab56b 100644 --- a/internal/envoy/v3/runtime.go +++ b/internal/envoy/v3/runtime.go @@ -40,13 +40,8 @@ func RuntimeLayers(configurableRuntimeFields map[string]*structpb.Value) []*envo func baseRuntimeLayer() *structpb.Struct { return &structpb.Struct{ Fields: map[string]*structpb.Value{ - // Disable Envoy removing the client TE request header. Removing - // the header was added by default in Envoy v1.29.0. - // Can remove once https://github.com/envoyproxy/envoy/pull/32255 is - // backported or present in a new release of Envoy. - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), - "re2.max_program_size.error_level": structpb.NewNumberValue(maxRegexProgramSizeError), - "re2.max_program_size.warn_level": structpb.NewNumberValue(maxRegexProgramSizeWarn), + "re2.max_program_size.error_level": structpb.NewNumberValue(maxRegexProgramSizeError), + "re2.max_program_size.warn_level": structpb.NewNumberValue(maxRegexProgramSizeWarn), }, } } diff --git a/internal/envoy/v3/runtime_test.go b/internal/envoy/v3/runtime_test.go index ac55923b0b4..9e84d136b65 100644 --- a/internal/envoy/v3/runtime_test.go +++ b/internal/envoy/v3/runtime_test.go @@ -39,9 +39,8 @@ func TestRuntimeLayers(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { expectedFields := map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), - "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), - "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), + "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), + "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), } for k, v := range tc.configurableFields { expectedFields[k] = v diff --git a/internal/envoy/v3/stats.go b/internal/envoy/v3/stats.go index 21cc7b57c1f..a444218db88 100644 --- a/internal/envoy/v3/stats.go +++ b/internal/envoy/v3/stats.go @@ -20,6 +20,7 @@ import ( envoy_filter_http_router_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3" envoy_filter_network_http_connection_manager_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" envoy_transport_socket_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" "google.golang.org/protobuf/types/known/wrapperspb" @@ -49,7 +50,7 @@ func StatsListeners(metrics contour_v1alpha1.MetricsConfig, health contour_v1alp SocketOptions: NewSocketOptions().TCPKeepalive().Build(), FilterChains: filterChain("stats", DownstreamTLSTransportSocket( - downstreamTLSContext(metrics.TLS.CAFile != "")), routeForAdminInterface("/stats")), + downstreamTLSContext(metrics.TLS.CAFile != "")), routeForAdminInterface("/stats", "/stats/prometheus")), }, { Name: "health", Address: SocketAddress(health.Address, health.Port), @@ -64,7 +65,11 @@ func StatsListeners(metrics contour_v1alpha1.MetricsConfig, health contour_v1alp Name: "stats-health", Address: SocketAddress(metrics.Address, metrics.Port), SocketOptions: NewSocketOptions().TCPKeepalive().Build(), - FilterChains: filterChain("stats", nil, routeForAdminInterface("/ready", "/stats")), + FilterChains: filterChain("stats", nil, routeForAdminInterface( + "/ready", + "/stats", + "/stats/prometheus", + )), }} // Create separate HTTP listeners for metrics and health. @@ -73,7 +78,7 @@ func StatsListeners(metrics contour_v1alpha1.MetricsConfig, health contour_v1alp Name: "stats", Address: SocketAddress(metrics.Address, metrics.Port), SocketOptions: NewSocketOptions().TCPKeepalive().Build(), - FilterChains: filterChain("stats", nil, routeForAdminInterface("/stats")), + FilterChains: filterChain("stats", nil, routeForAdminInterface("/stats", "/stats/prometheus")), }, { Name: "health", Address: SocketAddress(health.Address, health.Port), @@ -133,8 +138,8 @@ func filterChain(statsPrefix string, transportSocket *envoy_config_core_v3.Trans }} } -// routeForAdminInterface creates static RouteConfig that forwards requested prefixes to Envoy admin interface. -func routeForAdminInterface(prefixes ...string) *envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_RouteConfig { +// routeForAdminInterface creates static RouteConfig that forwards requested paths to Envoy admin interface. +func routeForAdminInterface(paths ...string) *envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_RouteConfig { config := &envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_RouteConfig{ RouteConfig: &envoy_config_route_v3.RouteConfiguration{ VirtualHosts: []*envoy_config_route_v3.VirtualHost{{ @@ -144,12 +149,25 @@ func routeForAdminInterface(prefixes ...string) *envoy_filter_network_http_conne }, } - for _, prefix := range prefixes { + for _, p := range paths { config.RouteConfig.VirtualHosts[0].Routes = append(config.RouteConfig.VirtualHosts[0].Routes, &envoy_config_route_v3.Route{ Match: &envoy_config_route_v3.RouteMatch{ - PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{ - Prefix: prefix, + PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{ + Path: p, + }, + Headers: []*envoy_config_route_v3.HeaderMatcher{ + { + Name: ":method", + HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + IgnoreCase: true, + MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ + Exact: "GET", + }, + }, + }, + }, }, }, Action: &envoy_config_route_v3.Route_Route{ diff --git a/internal/envoy/v3/stats_test.go b/internal/envoy/v3/stats_test.go index dc10c34808f..cdabc908bf5 100644 --- a/internal/envoy/v3/stats_test.go +++ b/internal/envoy/v3/stats_test.go @@ -22,6 +22,7 @@ import ( envoy_filter_http_router_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3" envoy_filter_network_http_connection_manager_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" envoy_transport_socket_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" "google.golang.org/protobuf/types/known/wrapperspb" @@ -32,8 +33,21 @@ import ( func TestStatsListeners(t *testing.T) { readyRoute := &envoy_config_route_v3.Route{ Match: &envoy_config_route_v3.RouteMatch{ - PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{ - Prefix: "/ready", + PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{ + Path: "/ready", + }, + Headers: []*envoy_config_route_v3.HeaderMatcher{ + { + Name: ":method", + HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + IgnoreCase: true, + MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ + Exact: "GET", + }, + }, + }, + }, }, }, Action: &envoy_config_route_v3.Route_Route{ @@ -47,8 +61,49 @@ func TestStatsListeners(t *testing.T) { statsRoute := &envoy_config_route_v3.Route{ Match: &envoy_config_route_v3.RouteMatch{ - PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{ - Prefix: "/stats", + PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{ + Path: "/stats", + }, + Headers: []*envoy_config_route_v3.HeaderMatcher{ + { + Name: ":method", + HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + IgnoreCase: true, + MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ + Exact: "GET", + }, + }, + }, + }, + }, + }, + Action: &envoy_config_route_v3.Route_Route{ + Route: &envoy_config_route_v3.RouteAction{ + ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{ + Cluster: "envoy-admin", + }, + }, + }, + } + + prometheusStatsRoute := &envoy_config_route_v3.Route{ + Match: &envoy_config_route_v3.RouteMatch{ + PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{ + Path: "/stats/prometheus", + }, + Headers: []*envoy_config_route_v3.HeaderMatcher{ + { + Name: ":method", + HeaderMatchSpecifier: &envoy_config_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + IgnoreCase: true, + MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ + Exact: "GET", + }, + }, + }, + }, }, }, Action: &envoy_config_route_v3.Route_Route{ @@ -92,7 +147,7 @@ func TestStatsListeners(t *testing.T) { VirtualHosts: []*envoy_config_route_v3.VirtualHost{{ Name: "backend", Domains: []string{"*"}, - Routes: []*envoy_config_route_v3.Route{readyRoute, statsRoute}, + Routes: []*envoy_config_route_v3.Route{readyRoute, statsRoute, prometheusStatsRoute}, }}, }, }, @@ -138,7 +193,7 @@ func TestStatsListeners(t *testing.T) { VirtualHosts: []*envoy_config_route_v3.VirtualHost{{ Name: "backend", Domains: []string{"*"}, - Routes: []*envoy_config_route_v3.Route{statsRoute}, + Routes: []*envoy_config_route_v3.Route{statsRoute, prometheusStatsRoute}, }}, }, }, @@ -229,7 +284,7 @@ func TestStatsListeners(t *testing.T) { VirtualHosts: []*envoy_config_route_v3.VirtualHost{{ Name: "backend", Domains: []string{"*"}, - Routes: []*envoy_config_route_v3.Route{statsRoute}, + Routes: []*envoy_config_route_v3.Route{statsRoute, prometheusStatsRoute}, }}, }, }, @@ -322,7 +377,7 @@ func TestStatsListeners(t *testing.T) { VirtualHosts: []*envoy_config_route_v3.VirtualHost{{ Name: "backend", Domains: []string{"*"}, - Routes: []*envoy_config_route_v3.Route{statsRoute}, + Routes: []*envoy_config_route_v3.Route{statsRoute, prometheusStatsRoute}, }}, }, }, diff --git a/internal/envoy/v3/tracing.go b/internal/envoy/v3/tracing.go index 37eaed2d5f5..f66ca8b3ba8 100644 --- a/internal/envoy/v3/tracing.go +++ b/internal/envoy/v3/tracing.go @@ -55,6 +55,7 @@ func TracingConfig(tracing *EnvoyTracingConfig) *envoy_filter_network_http_conne }), }, }, + SpawnUpstreamSpan: wrapperspb.Bool(true), } } diff --git a/internal/envoy/v3/tracing_test.go b/internal/envoy/v3/tracing_test.go index 0c4bea5f936..e02ed7d114f 100644 --- a/internal/envoy/v3/tracing_test.go +++ b/internal/envoy/v3/tracing_test.go @@ -111,6 +111,7 @@ func TestTracingConfig(t *testing.T) { }), }, }, + SpawnUpstreamSpan: wrapperspb.Bool(true), }, }, "no custom tag": { @@ -146,6 +147,7 @@ func TestTracingConfig(t *testing.T) { }), }, }, + SpawnUpstreamSpan: wrapperspb.Bool(true), }, }, "no SNI set": { @@ -181,6 +183,7 @@ func TestTracingConfig(t *testing.T) { }), }, }, + SpawnUpstreamSpan: wrapperspb.Bool(true), }, }, } diff --git a/internal/featuretests/v3/cluster_test.go b/internal/featuretests/v3/cluster_test.go index 6569461cf04..2680585ba4b 100644 --- a/internal/featuretests/v3/cluster_test.go +++ b/internal/featuretests/v3/cluster_test.go @@ -391,7 +391,7 @@ func TestCDSResourceFiltering(t *testing.T) { }) } -func circuitBreakerGlobalOpt(t *testing.T, g *contour_v1alpha1.GlobalCircuitBreakerDefaults) func(*dag.Builder) { +func circuitBreakerGlobalOpt(t *testing.T, g *contour_v1alpha1.CircuitBreakers) func(*dag.Builder) { return func(b *dag.Builder) { log := fixture.NewTestLogger(t) log.SetLevel(logrus.DebugLevel) @@ -414,7 +414,7 @@ func circuitBreakerGlobalOpt(t *testing.T, g *contour_v1alpha1.GlobalCircuitBrea } func TestClusterCircuitbreakerAnnotationsIngress(t *testing.T) { - g := &contour_v1alpha1.GlobalCircuitBreakerDefaults{ + g := &contour_v1alpha1.CircuitBreakers{ MaxConnections: 13, MaxPendingRequests: 14, MaxRequests: 15, @@ -461,9 +461,11 @@ func TestClusterCircuitbreakerAnnotationsIngress(t *testing.T) { MaxPendingRequests: wrapperspb.UInt32(4096), MaxRequests: wrapperspb.UInt32(404), MaxRetries: wrapperspb.UInt32(7), + TrackRemaining: true, }}, PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ MaxConnections: wrapperspb.UInt32(45), + TrackRemaining: true, }}, }, }), @@ -497,8 +499,11 @@ func TestClusterCircuitbreakerAnnotationsIngress(t *testing.T) { MaxConnections: wrapperspb.UInt32(13), MaxRequests: wrapperspb.UInt32(15), MaxRetries: wrapperspb.UInt32(17), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), @@ -531,8 +536,11 @@ func TestClusterCircuitbreakerAnnotationsIngress(t *testing.T) { MaxPendingRequests: wrapperspb.UInt32(14), MaxRequests: wrapperspb.UInt32(15), MaxRetries: wrapperspb.UInt32(17), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), @@ -541,7 +549,7 @@ func TestClusterCircuitbreakerAnnotationsIngress(t *testing.T) { } func TestClusterCircuitbreakerAnnotationsHTTPProxy(t *testing.T) { - g := &contour_v1alpha1.GlobalCircuitBreakerDefaults{ + g := &contour_v1alpha1.CircuitBreakers{ MaxConnections: 13, MaxPendingRequests: 14, MaxRequests: 15, @@ -597,8 +605,11 @@ func TestClusterCircuitbreakerAnnotationsHTTPProxy(t *testing.T) { MaxPendingRequests: wrapperspb.UInt32(4096), MaxRequests: wrapperspb.UInt32(404), MaxRetries: wrapperspb.UInt32(7), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), @@ -631,8 +642,11 @@ func TestClusterCircuitbreakerAnnotationsHTTPProxy(t *testing.T) { MaxConnections: wrapperspb.UInt32(13), MaxRequests: wrapperspb.UInt32(15), MaxRetries: wrapperspb.UInt32(17), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), @@ -665,8 +679,11 @@ func TestClusterCircuitbreakerAnnotationsHTTPProxy(t *testing.T) { MaxPendingRequests: wrapperspb.UInt32(14), MaxRequests: wrapperspb.UInt32(15), MaxRetries: wrapperspb.UInt32(17), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), @@ -675,7 +692,7 @@ func TestClusterCircuitbreakerAnnotationsHTTPProxy(t *testing.T) { } func TestClusterCircuitbreakerAnnotationsGateway(t *testing.T) { - g := &contour_v1alpha1.GlobalCircuitBreakerDefaults{ + g := &contour_v1alpha1.CircuitBreakers{ MaxConnections: 13, MaxPendingRequests: 14, MaxRequests: 15, @@ -774,8 +791,11 @@ func TestClusterCircuitbreakerAnnotationsGateway(t *testing.T) { MaxPendingRequests: wrapperspb.UInt32(4096), MaxRequests: wrapperspb.UInt32(404), MaxRetries: wrapperspb.UInt32(7), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), @@ -808,8 +828,11 @@ func TestClusterCircuitbreakerAnnotationsGateway(t *testing.T) { MaxConnections: wrapperspb.UInt32(13), MaxRequests: wrapperspb.UInt32(15), MaxRetries: wrapperspb.UInt32(17), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), @@ -842,8 +865,11 @@ func TestClusterCircuitbreakerAnnotationsGateway(t *testing.T) { MaxPendingRequests: wrapperspb.UInt32(14), MaxRequests: wrapperspb.UInt32(15), MaxRetries: wrapperspb.UInt32(17), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + TrackRemaining: true, }}, - PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{}}, }, }), ), diff --git a/internal/featuretests/v3/envoy.go b/internal/featuretests/v3/envoy.go index 6d3187a66bd..b95c9074c0d 100644 --- a/internal/featuretests/v3/envoy.go +++ b/internal/featuretests/v3/envoy.go @@ -460,6 +460,34 @@ func filterchaintlsfallback(fallbackSecret *core_v1.Secret, peerValidationContex ) } +// filterchaintlsfallbackauthz does same thing as filterchaintlsfallback but inserts a +// `ext_authz` filter with the specified configuration into the filter chain. +func filterchaintlsfallbackauthz(fallbackSecret *core_v1.Secret, authz *envoy_filter_http_ext_authz_v3.ExtAuthz, peerValidationContext *dag.PeerValidationContext, alpn ...string) *envoy_config_listener_v3.FilterChain { + return envoy_v3.FilterChainTLSFallback( + envoy_v3.DownstreamTLSContext( + &dag.Secret{Object: fallbackSecret}, + envoy_transport_socket_tls_v3.TlsParameters_TLSv1_2, + envoy_transport_socket_tls_v3.TlsParameters_TLSv1_3, + nil, + peerValidationContext, + alpn...), + envoy_v3.Filters( + envoy_v3.HTTPConnectionManagerBuilder(). + DefaultFilters(). + AddFilter(&envoy_filter_network_http_connection_manager_v3.HttpFilter{ + Name: envoy_v3.ExtAuthzFilterName, + ConfigType: &envoy_filter_network_http_connection_manager_v3.HttpFilter_TypedConfig{ + TypedConfig: protobuf.MustMarshalAny(authz), + }, + }). + RouteConfigName(xdscache_v3.ENVOY_FALLBACK_ROUTECONFIG). + MetricsPrefix(xdscache_v3.ENVOY_HTTPS_LISTENER). + AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_v1alpha1.LogLevelInfo)). + Get(), + ), + ) +} + func httpsFilterFor(vhost string) *envoy_config_listener_v3.Filter { return envoy_v3.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)). diff --git a/internal/featuretests/v3/extensionservice_test.go b/internal/featuretests/v3/extensionservice_test.go index 93314db9505..b341882e4d7 100644 --- a/internal/featuretests/v3/extensionservice_test.go +++ b/internal/featuretests/v3/extensionservice_test.go @@ -23,11 +23,13 @@ import ( envoy_transport_socket_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" envoy_service_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" + "google.golang.org/protobuf/types/known/wrapperspb" core_v1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" + "github.com/projectcontour/contour/internal/dag" envoy_v3 "github.com/projectcontour/contour/internal/envoy/v3" "github.com/projectcontour/contour/internal/featuretests" "github.com/projectcontour/contour/internal/fixture" @@ -402,23 +404,341 @@ func extInvalidLoadBalancerPolicy(t *testing.T, rh ResourceEventHandlerWrapper, }) } +func extCircuitBreakers(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + ext := &contour_v1alpha1.ExtensionService{ + ObjectMeta: fixture.ObjectMeta("ns/ext"), + Spec: contour_v1alpha1.ExtensionServiceSpec{ + Services: []contour_v1alpha1.ExtensionServiceTarget{ + {Name: "svc1", Port: 8081}, + {Name: "svc2", Port: 8082}, + }, + LoadBalancerPolicy: &contour_v1.LoadBalancerPolicy{ + Strategy: "Cookie", + }, + CircuitBreakerPolicy: &contour_v1alpha1.CircuitBreakers{ + MaxConnections: 10000, + MaxPendingRequests: 1048, + MaxRequests: 494, + MaxRetries: 10, + PerHostMaxConnections: 1, + }, + }, + } + + rh.OnAdd(ext) + + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, + Resources: resources(t, + DefaultCluster( + // Default load balancer policy should be set as we were passed + // an invalid value, we can assert we get a basic cluster. + h2cCluster(cluster("extension/ns/ext", "extension/ns/ext", "extension_ns_ext")), + &envoy_config_cluster_v3.Cluster{ + TransportSocket: envoy_v3.UpstreamTLSTransportSocket( + &envoy_transport_socket_tls_v3.UpstreamTlsContext{ + CommonTlsContext: &envoy_transport_socket_tls_v3.CommonTlsContext{ + AlpnProtocols: []string{"h2"}, + }, + }, + ), + CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ + Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(10000), + MaxPendingRequests: wrapperspb.UInt32(1048), + MaxRequests: wrapperspb.UInt32(494), + MaxRetries: wrapperspb.UInt32(10), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(1), + TrackRemaining: true, + }}, + }, + }, + ), + ), + }) + + rh.OnUpdate(ext, &contour_v1alpha1.ExtensionService{ + ObjectMeta: fixture.ObjectMeta("ns/ext"), + Spec: contour_v1alpha1.ExtensionServiceSpec{ + Services: []contour_v1alpha1.ExtensionServiceTarget{ + {Name: "svc1", Port: 8081}, + {Name: "svc2", Port: 8082}, + }, + LoadBalancerPolicy: &contour_v1.LoadBalancerPolicy{ + Strategy: "RequestHash", + }, + }, + }) + + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, + Resources: resources(t, + DefaultCluster( + // Default load balancer policy should be set as we were passed + // an invalid value, we can assert we get a basic cluster. + h2cCluster(cluster("extension/ns/ext", "extension/ns/ext", "extension_ns_ext")), + &envoy_config_cluster_v3.Cluster{ + TransportSocket: envoy_v3.UpstreamTLSTransportSocket( + &envoy_transport_socket_tls_v3.UpstreamTlsContext{ + CommonTlsContext: &envoy_transport_socket_tls_v3.CommonTlsContext{ + AlpnProtocols: []string{"h2"}, + }, + }, + ), + }, + ), + ), + }) +} + +func extGlobalCircuitBreakers(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + ext := &contour_v1alpha1.ExtensionService{ + ObjectMeta: fixture.ObjectMeta("ns/ext"), + Spec: contour_v1alpha1.ExtensionServiceSpec{ + Services: []contour_v1alpha1.ExtensionServiceTarget{ + {Name: "svc1", Port: 8081}, + {Name: "svc2", Port: 8082}, + }, + LoadBalancerPolicy: &contour_v1.LoadBalancerPolicy{ + Strategy: "Cookie", + }, + }, + } + + rh.OnAdd(ext) + + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, + Resources: resources(t, + DefaultCluster( + // Default load balancer policy should be set as we were passed + // an invalid value, we can assert we get a basic cluster. + h2cCluster(cluster("extension/ns/ext", "extension/ns/ext", "extension_ns_ext")), + &envoy_config_cluster_v3.Cluster{ + TransportSocket: envoy_v3.UpstreamTLSTransportSocket( + &envoy_transport_socket_tls_v3.UpstreamTlsContext{ + CommonTlsContext: &envoy_transport_socket_tls_v3.CommonTlsContext{ + AlpnProtocols: []string{"h2"}, + }, + }, + ), + CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ + Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(20000), + MaxPendingRequests: wrapperspb.UInt32(2048), + MaxRequests: wrapperspb.UInt32(294), + MaxRetries: wrapperspb.UInt32(20), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(10), + TrackRemaining: true, + }}, + }, + }, + ), + ), + }) + + rh.OnUpdate(ext, &contour_v1alpha1.ExtensionService{ + ObjectMeta: fixture.ObjectMeta("ns/ext"), + Spec: contour_v1alpha1.ExtensionServiceSpec{ + Services: []contour_v1alpha1.ExtensionServiceTarget{ + {Name: "svc1", Port: 8081}, + {Name: "svc2", Port: 8082}, + }, + LoadBalancerPolicy: &contour_v1.LoadBalancerPolicy{ + Strategy: "RequestHash", + }, + }, + }) + + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, + Resources: resources(t, + DefaultCluster( + // Default load balancer policy should be set as we were passed + // an invalid value, we can assert we get a basic cluster. + h2cCluster(cluster("extension/ns/ext", "extension/ns/ext", "extension_ns_ext")), + &envoy_config_cluster_v3.Cluster{ + TransportSocket: envoy_v3.UpstreamTLSTransportSocket( + &envoy_transport_socket_tls_v3.UpstreamTlsContext{ + CommonTlsContext: &envoy_transport_socket_tls_v3.CommonTlsContext{ + AlpnProtocols: []string{"h2"}, + }, + }, + ), + CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ + Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(20000), + MaxPendingRequests: wrapperspb.UInt32(2048), + MaxRequests: wrapperspb.UInt32(294), + MaxRetries: wrapperspb.UInt32(20), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(10), + TrackRemaining: true, + }}, + }, + }, + ), + ), + }) +} + +func overrideExtGlobalCircuitBreakers(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + ext := &contour_v1alpha1.ExtensionService{ + ObjectMeta: fixture.ObjectMeta("ns/ext"), + Spec: contour_v1alpha1.ExtensionServiceSpec{ + Services: []contour_v1alpha1.ExtensionServiceTarget{ + {Name: "svc1", Port: 8081}, + {Name: "svc2", Port: 8082}, + }, + LoadBalancerPolicy: &contour_v1.LoadBalancerPolicy{ + Strategy: "Cookie", + }, + CircuitBreakerPolicy: &contour_v1alpha1.CircuitBreakers{ + MaxConnections: 30000, + MaxPendingRequests: 3048, + MaxRequests: 394, + MaxRetries: 30, + PerHostMaxConnections: 30, + }, + }, + } + + rh.OnAdd(ext) + + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, + Resources: resources(t, + DefaultCluster( + // Default load balancer policy should be set as we were passed + // an invalid value, we can assert we get a basic cluster. + h2cCluster(cluster("extension/ns/ext", "extension/ns/ext", "extension_ns_ext")), + &envoy_config_cluster_v3.Cluster{ + TransportSocket: envoy_v3.UpstreamTLSTransportSocket( + &envoy_transport_socket_tls_v3.UpstreamTlsContext{ + CommonTlsContext: &envoy_transport_socket_tls_v3.CommonTlsContext{ + AlpnProtocols: []string{"h2"}, + }, + }, + ), + CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ + Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(30000), + MaxPendingRequests: wrapperspb.UInt32(3048), + MaxRequests: wrapperspb.UInt32(394), + MaxRetries: wrapperspb.UInt32(30), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(30), + TrackRemaining: true, + }}, + }, + }, + ), + ), + }) + + rh.OnUpdate(ext, &contour_v1alpha1.ExtensionService{ + ObjectMeta: fixture.ObjectMeta("ns/ext"), + Spec: contour_v1alpha1.ExtensionServiceSpec{ + Services: []contour_v1alpha1.ExtensionServiceTarget{ + {Name: "svc1", Port: 8081}, + {Name: "svc2", Port: 8082}, + }, + LoadBalancerPolicy: &contour_v1.LoadBalancerPolicy{ + Strategy: "RequestHash", + }, + }, + }) + + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, + Resources: resources(t, + DefaultCluster( + // Default load balancer policy should be set as we were passed + // an invalid value, we can assert we get a basic cluster. + h2cCluster(cluster("extension/ns/ext", "extension/ns/ext", "extension_ns_ext")), + &envoy_config_cluster_v3.Cluster{ + TransportSocket: envoy_v3.UpstreamTLSTransportSocket( + &envoy_transport_socket_tls_v3.UpstreamTlsContext{ + CommonTlsContext: &envoy_transport_socket_tls_v3.CommonTlsContext{ + AlpnProtocols: []string{"h2"}, + }, + }, + ), + CircuitBreakers: &envoy_config_cluster_v3.CircuitBreakers{ + Thresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(20000), + MaxPendingRequests: wrapperspb.UInt32(2048), + MaxRequests: wrapperspb.UInt32(294), + MaxRetries: wrapperspb.UInt32(20), + TrackRemaining: true, + }}, + PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ + MaxConnections: wrapperspb.UInt32(10), + TrackRemaining: true, + }}, + }, + }, + ), + ), + }) +} + func TestExtensionService(t *testing.T) { subtests := map[string]func(*testing.T, ResourceEventHandlerWrapper, *Contour){ - "Basic": extBasic, - "Cleartext": extCleartext, - "UpstreamValidation": extUpstreamValidation, - "ExternalName": extExternalName, - "IdleConnectionTimeout": extIdleConnectionTimeout, - "MissingService": extMissingService, - "InconsistentProto": extInconsistentProto, - "InvalidTimeout": extInvalidTimeout, - "InvalidLoadBalancerPolicy": extInvalidLoadBalancerPolicy, + "Basic": extBasic, + "Cleartext": extCleartext, + "UpstreamValidation": extUpstreamValidation, + "ExternalName": extExternalName, + "IdleConnectionTimeout": extIdleConnectionTimeout, + "MissingService": extMissingService, + "InconsistentProto": extInconsistentProto, + "InvalidTimeout": extInvalidTimeout, + "InvalidLoadBalancerPolicy": extInvalidLoadBalancerPolicy, + "CircuitBreakers": extCircuitBreakers, + "GlobalCircuitBreakers": extGlobalCircuitBreakers, + "OverrideGlobalCircuitBreakers": overrideExtGlobalCircuitBreakers, } for n, f := range subtests { f := f t.Run(n, func(t *testing.T) { - rh, c, done := setup(t) + var ( + rh ResourceEventHandlerWrapper + c *Contour + done func() + ) + + switch n { + case "GlobalCircuitBreakers", "OverrideGlobalCircuitBreakers": + rh, c, done = setup(t, + func(b *dag.Builder) { + for _, processor := range b.Processors { + if extensionProcessor, ok := processor.(*dag.ExtensionServiceProcessor); ok { + extensionProcessor.GlobalCircuitBreakerDefaults = &contour_v1alpha1.CircuitBreakers{ + MaxConnections: 20000, + MaxPendingRequests: 2048, + MaxRequests: 294, + MaxRetries: 20, + PerHostMaxConnections: 10, + } + } + } + }) + + default: + rh, c, done = setup(t) + } + defer done() // Add common test fixtures. diff --git a/internal/featuretests/v3/featuretests.go b/internal/featuretests/v3/featuretests.go index 67e0f428890..2e1dbce8817 100644 --- a/internal/featuretests/v3/featuretests.go +++ b/internal/featuretests/v3/featuretests.go @@ -188,7 +188,7 @@ func setup(t *testing.T, opts ...any) (ResourceEventHandlerWrapper, *Contour, fu wg.Done() }() - cc, err := grpc.Dial(l.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) + cc, err := grpc.NewClient(l.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) rh := &resourceEventHandler{ diff --git a/internal/featuretests/v3/global_authorization_test.go b/internal/featuretests/v3/global_authorization_test.go index dbafac189e1..7bb0e0e4aaa 100644 --- a/internal/featuretests/v3/global_authorization_test.go +++ b/internal/featuretests/v3/global_authorization_test.go @@ -27,6 +27,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" core_v1 "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" @@ -470,6 +471,99 @@ func globalExternalAuthorizationWithTLSAuthOverride(t *testing.T, rh ResourceEve }).Status(p).IsValid() } +func globalExternalAuthorizationFilterTLSWithFallbackCertificate(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + p := fixture.NewProxy("TLSProxy"). + WithFQDN("foo.com"). + WithSpec(contour_v1.HTTPProxySpec{ + VirtualHost: &contour_v1.VirtualHost{ + Fqdn: "foo.com", + TLS: &contour_v1.TLS{ + SecretName: "certificate", + EnableFallbackCertificate: true, + }, + }, + Routes: []contour_v1.Route{ + { + Services: []contour_v1.Service{ + { + Name: "s1", + Port: 80, + }, + }, + }, + }, + }) + + rh.OnAdd(p) + + // Add Fallback Certificate Secret + fallbackSecret := featuretests.TLSSecret(t, "admin/fallbacksecret", &featuretests.ServerCertificate) + rh.OnAdd(fallbackSecret) + + // Add Fallback Cert Delegation + certDelegationAll := &contour_v1.TLSCertificateDelegation{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: "fallbackcertdelegation", + Namespace: "admin", + }, + Spec: contour_v1.TLSCertificateDelegationSpec{ + Delegations: []contour_v1.CertificateDelegation{{ + SecretName: "fallbacksecret", + TargetNamespaces: []string{"*"}, + }}, + }, + } + + rh.OnAdd(certDelegationAll) + + httpListener := defaultHTTPListener() + httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM()) + + httpsListener := &envoy_config_listener_v3.Listener{ + Name: "ingress_https", + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + FilterChains: []*envoy_config_listener_v3.FilterChain{ + filterchaintls("foo.com", + featuretests.TLSSecret(t, "certificate", &featuretests.ServerCertificate), + authzFilterFor( + "foo.com", + &envoy_filter_http_ext_authz_v3.ExtAuthz{ + Services: grpcCluster("extension/auth/extension"), + ClearRouteCache: true, + IncludePeerCertificate: true, + StatusOnError: &envoy_type_v3.HttpStatus{ + Code: envoy_type_v3.StatusCode_Forbidden, + }, + TransportApiVersion: envoy_config_core_v3.ApiVersion_V3, + }, + ), + nil, "h2", "http/1.1"), + filterchaintlsfallbackauthz(fallbackSecret, + &envoy_filter_http_ext_authz_v3.ExtAuthz{ + Services: grpcCluster("extension/auth/extension"), + ClearRouteCache: true, + IncludePeerCertificate: true, + StatusOnError: &envoy_type_v3.HttpStatus{ + Code: envoy_type_v3.StatusCode_Forbidden, + }, + TransportApiVersion: envoy_config_core_v3.ApiVersion_V3, + }, nil, "h2", "http/1.1"), + }, + SocketOptions: envoy_v3.NewSocketOptions().TCPKeepalive().Build(), + } + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, + httpListener, + httpsListener, + statsListener()), + }).Status(p).IsValid() +} + func TestGlobalAuthorization(t *testing.T) { subtests := map[string]func(*testing.T, ResourceEventHandlerWrapper, *Contour){ // Default extAuthz on non TLS host. @@ -484,6 +578,8 @@ func TestGlobalAuthorization(t *testing.T) { "GlobalExternalAuthorizationWithMergedAuthPolicy": globalExternalAuthorizationWithMergedAuthPolicy, // extAuthz authpolicy merge for TLS hosts. "GlobalExternalAuthorizationWithMergedAuthPolicyTLS": globalExternalAuthorizationWithMergedAuthPolicyTLS, + // extAuthz on TLS host with Fallback Certificate enabled. + "GlobalExternalAuthorizationFilterTLSWithFallbackCertificate": globalExternalAuthorizationFilterTLSWithFallbackCertificate, } for n, f := range subtests { @@ -520,6 +616,10 @@ func TestGlobalAuthorization(t *testing.T) { }, }, } + httpProxyProcessor.FallbackCertificate = &types.NamespacedName{ + Namespace: "admin", + Name: "fallbacksecret", + } } } }) diff --git a/internal/featuretests/v3/listeners_test.go b/internal/featuretests/v3/listeners_test.go index 55ed7208cab..8167dc6dfe5 100644 --- a/internal/featuretests/v3/listeners_test.go +++ b/internal/featuretests/v3/listeners_test.go @@ -1370,12 +1370,12 @@ func TestGatewayListenersSetAddress(t *testing.T) { rh.OnAdd(&gatewayapi_v1alpha2.TLSRoute{ ObjectMeta: fixture.ObjectMeta("basic"), Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayListenerParentRef("projectcontour", "contour", "tls", 0), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"tcp.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"tcp.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("svc1", 80, nil), }}, diff --git a/internal/featuretests/v3/routeweight_test.go b/internal/featuretests/v3/routeweight_test.go index 1e056950693..9725e34b15c 100644 --- a/internal/featuretests/v3/routeweight_test.go +++ b/internal/featuretests/v3/routeweight_test.go @@ -502,12 +502,12 @@ func TestTLSRoute_RouteWithAServiceWeight(t *testing.T) { "type": "controller", }), Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("svc1", 443, ptr.To(int32(1))), }}, @@ -549,12 +549,12 @@ func TestTLSRoute_RouteWithAServiceWeight(t *testing.T) { "type": "controller", }), Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"test.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"test.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRefs( gatewayapi.TLSRouteBackendRef("svc1", 443, ptr.To(int32(1))), diff --git a/internal/featuretests/v3/tcproute_test.go b/internal/featuretests/v3/tcproute_test.go index 0682b5f4a5b..c864165a933 100644 --- a/internal/featuretests/v3/tcproute_test.go +++ b/internal/featuretests/v3/tcproute_test.go @@ -132,8 +132,8 @@ func TestTCPRoute(t *testing.T) { route2 := &gatewayapi_v1alpha2.TCPRoute{ ObjectMeta: fixture.ObjectMeta("tcproute-2"), Spec: gatewayapi_v1alpha2.TCPRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ { Namespace: ptr.To(gatewayapi_v1.Namespace("projectcontour")), Name: gatewayapi_v1.ObjectName("contour"), diff --git a/internal/featuretests/v3/tlsroute_test.go b/internal/featuretests/v3/tlsroute_test.go index ed59422e5f8..f7422d4199d 100644 --- a/internal/featuretests/v3/tlsroute_test.go +++ b/internal/featuretests/v3/tlsroute_test.go @@ -84,12 +84,12 @@ func TestTLSRoute_TLSPassthrough(t *testing.T) { route1 := &gatewayapi_v1alpha2.TLSRoute{ ObjectMeta: fixture.ObjectMeta("basic"), Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"tcp.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"tcp.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("correct-backend", 80, nil), }}, @@ -128,8 +128,8 @@ func TestTLSRoute_TLSPassthrough(t *testing.T) { route2 := &gatewayapi_v1alpha2.TLSRoute{ ObjectMeta: fixture.ObjectMeta("basic"), Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, @@ -170,12 +170,12 @@ func TestTLSRoute_TLSPassthrough(t *testing.T) { route3 := &gatewayapi_v1alpha2.TLSRoute{ ObjectMeta: fixture.ObjectMeta("basic"), Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, - Hostnames: []gatewayapi_v1alpha2.Hostname{"tcp.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"tcp.projectcontour.io"}, Rules: []gatewayapi_v1alpha2.TLSRouteRule{{ BackendRefs: gatewayapi.TLSRouteBackendRef("correct-backend", 80, nil), }}, @@ -185,8 +185,8 @@ func TestTLSRoute_TLSPassthrough(t *testing.T) { route4 := &gatewayapi_v1alpha2.TLSRoute{ ObjectMeta: fixture.ObjectMeta("basic-wildcard"), Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - CommonRouteSpec: gatewayapi_v1alpha2.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ gatewayapi.GatewayParentRef("projectcontour", "contour"), }, }, diff --git a/internal/featuretests/v3/upstreamtls_test.go b/internal/featuretests/v3/upstreamtls_test.go index 76ca2408ce6..584be3312ca 100644 --- a/internal/featuretests/v3/upstreamtls_test.go +++ b/internal/featuretests/v3/upstreamtls_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/utils/ptr" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" @@ -302,20 +303,22 @@ func TestUpstreamTLSWithHTTPRoute(t *testing.T) { }, }) - rh.OnAdd(&gatewayapi_v1alpha2.BackendTLSPolicy{ + rh.OnAdd(&gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "authenticated", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "backend", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "backend", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "Secret", Name: gatewayapi_v1.ObjectName(sec2.Name), }}, @@ -416,20 +419,22 @@ func TestBackendTLSPolicyPrecedenceOverUpstreamProtocolAnnotationWithHTTPRoute(t }, }) - rh.OnAdd(&gatewayapi_v1alpha2.BackendTLSPolicy{ + rh.OnAdd(&gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "authenticated", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "backend", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "backend", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "Secret", Name: gatewayapi_v1.ObjectName(sec1.Name), }}, @@ -559,20 +564,22 @@ func TestUpstreamTLSWithHTTPRouteANDHTTPProxy(t *testing.T) { }, }) - rh.OnAdd(&gatewayapi_v1alpha2.BackendTLSPolicy{ + rh.OnAdd(&gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "authenticated", Namespace: "default", }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Kind: "Service", - Name: "backend", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Kind: "Service", + Name: "backend", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1alpha2.LocalObjectReference{{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{{ Kind: "Secret", Name: gatewayapi_v1.ObjectName(sec1.Name), }}, diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 3e374429fdb..707f97f5397 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -17,7 +17,6 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) func CertificateRef(name, namespace string) gatewayapi_v1.SecretObjectReference { @@ -126,8 +125,8 @@ func HTTPBackendRef(serviceName string, port int, weight int32) []gatewayapi_v1. } } -func TLSRouteBackendRefs(backendRefs ...[]gatewayapi_v1alpha2.BackendRef) []gatewayapi_v1alpha2.BackendRef { - var res []gatewayapi_v1alpha2.BackendRef +func TLSRouteBackendRefs(backendRefs ...[]gatewayapi_v1.BackendRef) []gatewayapi_v1.BackendRef { + var res []gatewayapi_v1.BackendRef for _, ref := range backendRefs { res = append(res, ref...) @@ -135,13 +134,13 @@ func TLSRouteBackendRefs(backendRefs ...[]gatewayapi_v1alpha2.BackendRef) []gate return res } -func TLSRouteBackendRef(serviceName string, port int, weight *int32) []gatewayapi_v1alpha2.BackendRef { - return []gatewayapi_v1alpha2.BackendRef{ +func TLSRouteBackendRef(serviceName string, port int, weight *int32) []gatewayapi_v1.BackendRef { + return []gatewayapi_v1.BackendRef{ { - BackendObjectReference: gatewayapi_v1alpha2.BackendObjectReference{ + BackendObjectReference: gatewayapi_v1.BackendObjectReference{ Group: ptr.To(gatewayapi_v1.Group("")), Kind: ptr.To(gatewayapi_v1.Kind("Service")), - Name: gatewayapi_v1alpha2.ObjectName(serviceName), + Name: gatewayapi_v1.ObjectName(serviceName), Port: ptr.To(gatewayapi_v1.PortNumber(port)), }, Weight: weight, @@ -149,36 +148,36 @@ func TLSRouteBackendRef(serviceName string, port int, weight *int32) []gatewayap } } -func GRPCRouteBackendRef(serviceName string, port int, weight int32) []gatewayapi_v1alpha2.GRPCBackendRef { - return []gatewayapi_v1alpha2.GRPCBackendRef{ +func GRPCRouteBackendRef(serviceName string, port int, weight int32) []gatewayapi_v1.GRPCBackendRef { + return []gatewayapi_v1.GRPCBackendRef{ { - BackendRef: gatewayapi_v1alpha2.BackendRef{ - BackendObjectReference: gatewayapi_v1alpha2.BackendObjectReference{ + BackendRef: gatewayapi_v1.BackendRef{ + BackendObjectReference: gatewayapi_v1.BackendObjectReference{ Group: ptr.To(gatewayapi_v1.Group("")), Kind: ptr.To(gatewayapi_v1.Kind("Service")), - Name: gatewayapi_v1alpha2.ObjectName(serviceName), + Name: gatewayapi_v1.ObjectName(serviceName), Port: ptr.To(gatewayapi_v1.PortNumber(port)), }, Weight: &weight, }, - Filters: []gatewayapi_v1alpha2.GRPCRouteFilter{}, + Filters: []gatewayapi_v1.GRPCRouteFilter{}, }, } } -func GRPCMethodMatch(matchType gatewayapi_v1alpha2.GRPCMethodMatchType, service, method string) *gatewayapi_v1alpha2.GRPCMethodMatch { - return &gatewayapi_v1alpha2.GRPCMethodMatch{ +func GRPCMethodMatch(matchType gatewayapi_v1.GRPCMethodMatchType, service, method string) *gatewayapi_v1.GRPCMethodMatch { + return &gatewayapi_v1.GRPCMethodMatch{ Type: ptr.To(matchType), Service: ptr.To(service), Method: ptr.To(method), } } -func GRPCHeaderMatch(matchType gatewayapi_v1.HeaderMatchType, name, value string) []gatewayapi_v1alpha2.GRPCHeaderMatch { - return []gatewayapi_v1alpha2.GRPCHeaderMatch{ +func GRPCHeaderMatch(matchType gatewayapi_v1.HeaderMatchType, name, value string) []gatewayapi_v1.GRPCHeaderMatch { + return []gatewayapi_v1.GRPCHeaderMatch{ { Type: ptr.To(matchType), - Name: gatewayapi_v1alpha2.GRPCHeaderName(name), + Name: gatewayapi_v1.GRPCHeaderName(name), Value: value, }, } diff --git a/internal/k8s/helpers.go b/internal/k8s/helpers.go index adbcfd242d0..36d069990c1 100644 --- a/internal/k8s/helpers.go +++ b/internal/k8s/helpers.go @@ -26,6 +26,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -117,9 +118,9 @@ func IsObjectEqual(oldObj, newObj client.Object) (bool, error) { *gatewayapi_v1beta1.ReferenceGrant, *gatewayapi_v1.HTTPRoute, *gatewayapi_v1alpha2.TLSRoute, - *gatewayapi_v1alpha2.GRPCRoute, + *gatewayapi_v1.GRPCRoute, *gatewayapi_v1alpha2.TCPRoute, - *gatewayapi_v1alpha2.BackendTLSPolicy: + *gatewayapi_v1alpha3.BackendTLSPolicy: return isGenerationEqual(oldObj, newObj), nil // Slow path: compare the content of the objects. diff --git a/internal/k8s/helpers_test.go b/internal/k8s/helpers_test.go index bd303656f50..42f5b237394 100644 --- a/internal/k8s/helpers_test.go +++ b/internal/k8s/helpers_test.go @@ -208,6 +208,6 @@ func TestIsEqualForGeneration(t *testing.T) { run(t, &gatewayapi_v1.HTTPRoute{}) run(t, &gatewayapi_v1alpha2.TLSRoute{}) run(t, &gatewayapi_v1beta1.ReferenceGrant{}) - run(t, &gatewayapi_v1alpha2.GRPCRoute{}) + run(t, &gatewayapi_v1.GRPCRoute{}) run(t, &gatewayapi_v1alpha2.TCPRoute{}) } diff --git a/internal/k8s/kind.go b/internal/k8s/kind.go index 1e4d420910e..0de1fd90225 100644 --- a/internal/k8s/kind.go +++ b/internal/k8s/kind.go @@ -21,6 +21,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -52,7 +53,7 @@ func KindOf(obj any) string { return "HTTPProxy" case *gatewayapi_v1.HTTPRoute: return "HTTPRoute" - case *gatewayapi_v1alpha2.GRPCRoute: + case *gatewayapi_v1.GRPCRoute: return "GRPCRoute" case *gatewayapi_v1alpha2.TLSRoute: return "TLSRoute" @@ -64,7 +65,7 @@ func KindOf(obj any) string { return "GatewayClass" case *gatewayapi_v1beta1.ReferenceGrant: return "ReferenceGrant" - case *gatewayapi_v1alpha2.BackendTLSPolicy: + case *gatewayapi_v1alpha3.BackendTLSPolicy: return "BackendTLSPolicy" case *contour_v1.TLSCertificateDelegation: return "TLSCertificateDelegation" diff --git a/internal/k8s/kind_test.go b/internal/k8s/kind_test.go index 659b45269b5..da90fb7ddea 100644 --- a/internal/k8s/kind_test.go +++ b/internal/k8s/kind_test.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -44,14 +45,14 @@ func TestKindOf(t *testing.T) { {"ExtensionService", &contour_v1alpha1.ExtensionService{}}, {"ContourConfiguration", &contour_v1alpha1.ContourConfiguration{}}, {"ContourDeployment", &contour_v1alpha1.ContourDeployment{}}, - {"GRPCRoute", &gatewayapi_v1alpha2.GRPCRoute{}}, + {"GRPCRoute", &gatewayapi_v1.GRPCRoute{}}, {"HTTPRoute", &gatewayapi_v1.HTTPRoute{}}, {"TLSRoute", &gatewayapi_v1alpha2.TLSRoute{}}, {"TCPRoute", &gatewayapi_v1alpha2.TCPRoute{}}, {"Gateway", &gatewayapi_v1.Gateway{}}, {"GatewayClass", &gatewayapi_v1.GatewayClass{}}, {"ReferenceGrant", &gatewayapi_v1beta1.ReferenceGrant{}}, - {"BackendTLSPolicy", &gatewayapi_v1alpha2.BackendTLSPolicy{}}, + {"BackendTLSPolicy", &gatewayapi_v1alpha3.BackendTLSPolicy{}}, { "Foo", &unstructured.Unstructured{ Object: map[string]any{ diff --git a/internal/k8s/scheme.go b/internal/k8s/scheme.go index 6f7aa9c2d29..c13d04360d6 100644 --- a/internal/k8s/scheme.go +++ b/internal/k8s/scheme.go @@ -18,6 +18,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -33,9 +34,10 @@ func NewContourScheme() (*runtime.Scheme, error) { contour_v1.AddToScheme, contour_v1alpha1.AddToScheme, scheme.AddToScheme, - gatewayapi_v1alpha2.AddToScheme, - gatewayapi_v1beta1.AddToScheme, - gatewayapi_v1.AddToScheme, + gatewayapi_v1alpha2.Install, + gatewayapi_v1alpha3.Install, + gatewayapi_v1beta1.Install, + gatewayapi_v1.Install, } if err := b.AddToScheme(s); err != nil { diff --git a/internal/provisioner/controller/gateway.go b/internal/provisioner/controller/gateway.go index 4de51141b6c..b1daaf114d1 100644 --- a/internal/provisioner/controller/gateway.go +++ b/internal/provisioner/controller/gateway.go @@ -68,9 +68,9 @@ func NewGatewayController(mgr manager.Manager, gatewayController, contourImage, } if err := c.Watch( - source.Kind(mgr.GetCache(), &gatewayapi_v1.Gateway{}), - &handler.EnqueueRequestForObject{}, - predicate.NewPredicateFuncs(r.forReconcilableGatewayClass), + source.Kind(mgr.GetCache(), &gatewayapi_v1.Gateway{}, + &handler.TypedEnqueueRequestForObject[*gatewayapi_v1.Gateway]{}, + predicate.NewTypedPredicateFuncs(r.forReconcilableGatewayClass)), ); err != nil { return nil, err } @@ -79,9 +79,9 @@ func NewGatewayController(mgr manager.Manager, gatewayController, contourImage, // Gateways when a provisioner-controlled GatewayClass becomes // "Accepted: true". if err := c.Watch( - source.Kind(mgr.GetCache(), &gatewayapi_v1.GatewayClass{}), - handler.EnqueueRequestsFromMapFunc(r.getGatewayClassGateways), - predicate.NewPredicateFuncs(r.isGatewayClassReconcilable), + source.Kind(mgr.GetCache(), &gatewayapi_v1.GatewayClass{}, + handler.TypedEnqueueRequestsFromMapFunc(r.getGatewayClassGateways), + predicate.NewTypedPredicateFuncs(r.isGatewayClassReconcilable)), ); err != nil { return nil, err } @@ -92,14 +92,9 @@ func NewGatewayController(mgr manager.Manager, gatewayController, contourImage, // forReconcilableGatewayClass returns true if the provided Gateway uses a GatewayClass // controlled by the provisioner, and that GatewayClass has a condition of // "Accepted: true". -func (r *gatewayReconciler) forReconcilableGatewayClass(obj client.Object) bool { - gw, ok := obj.(*gatewayapi_v1.Gateway) - if !ok { - return false - } - +func (r *gatewayReconciler) forReconcilableGatewayClass(gateway *gatewayapi_v1.Gateway) bool { gatewayClass := &gatewayapi_v1.GatewayClass{} - if err := r.client.Get(context.Background(), client.ObjectKey{Name: string(gw.Spec.GatewayClassName)}, gatewayClass); err != nil { + if err := r.client.Get(context.Background(), client.ObjectKey{Name: string(gateway.Spec.GatewayClassName)}, gatewayClass); err != nil { return false } @@ -109,12 +104,7 @@ func (r *gatewayReconciler) forReconcilableGatewayClass(obj client.Object) bool // isGatewayClassReconcilable returns true if the provided object is a // GatewayClass controlled by the provisioner that has an "Accepted: true" // condition. -func (r *gatewayReconciler) isGatewayClassReconcilable(obj client.Object) bool { - gatewayClass, ok := obj.(*gatewayapi_v1.GatewayClass) - if !ok { - return false - } - +func (r *gatewayReconciler) isGatewayClassReconcilable(gatewayClass *gatewayapi_v1.GatewayClass) bool { if gatewayClass.Spec.ControllerName != r.gatewayController { return false } @@ -132,7 +122,7 @@ func (r *gatewayReconciler) isGatewayClassReconcilable(obj client.Object) bool { return accepted } -func (r *gatewayReconciler) getGatewayClassGateways(ctx context.Context, gatewayClass client.Object) []reconcile.Request { +func (r *gatewayReconciler) getGatewayClassGateways(ctx context.Context, gatewayClass *gatewayapi_v1.GatewayClass) []reconcile.Request { var gateways gatewayapi_v1.GatewayList if err := r.client.List(ctx, &gateways); err != nil { r.log.Error(err, "error listing gateways") diff --git a/internal/provisioner/controller/gateway_test.go b/internal/provisioner/controller/gateway_test.go index 4df131b9486..908ab1094c8 100644 --- a/internal/provisioner/controller/gateway_test.go +++ b/internal/provisioner/controller/gateway_test.go @@ -1098,7 +1098,7 @@ func TestGatewayReconcile(t *testing.T) { }, } require.NoError(t, r.client.Get(context.Background(), keyFor(ds), ds)) - assert.Contains(t, ds.Spec.Template.ObjectMeta.Annotations, "key", "prometheus.io/scrape", "prometheus.io/port") + assert.Contains(t, ds.Spec.Template.ObjectMeta.Annotations, "key") }, }, @@ -1212,7 +1212,7 @@ func TestGatewayReconcile(t *testing.T) { } require.NoError(t, r.client.Get(context.Background(), keyFor(deploy), deploy)) - assert.Contains(t, deploy.Spec.Template.ObjectMeta.Annotations, "key", "prometheus.io/scrape", "prometheus.io/port") + assert.Contains(t, deploy.Spec.Template.ObjectMeta.Annotations, "key") }, }, diff --git a/internal/provisioner/controller/gatewayclass.go b/internal/provisioner/controller/gatewayclass.go index 030fb2c821d..e6462071d68 100644 --- a/internal/provisioner/controller/gatewayclass.go +++ b/internal/provisioner/controller/gatewayclass.go @@ -39,7 +39,7 @@ import ( const ( gatewayAPIBundleVersionAnnotation = "gateway.networking.k8s.io/bundle-version" - gatewayAPICRDBundleSupportedVersion = "v1.0.0" + gatewayAPICRDBundleSupportedVersion = "v1.1.0" ) // gatewayClassReconciler reconciles GatewayClass objects. @@ -62,9 +62,9 @@ func NewGatewayClassController(mgr manager.Manager, gatewayController string) (c } if err := c.Watch( - source.Kind(mgr.GetCache(), &gatewayapi_v1.GatewayClass{}), - &handler.EnqueueRequestForObject{}, - predicate.NewPredicateFuncs(r.hasMatchingController), + source.Kind(mgr.GetCache(), &gatewayapi_v1.GatewayClass{}, + &handler.TypedEnqueueRequestForObject[*gatewayapi_v1.GatewayClass]{}, + predicate.NewTypedPredicateFuncs(r.hasMatchingController)), ); err != nil { return nil, err } @@ -72,8 +72,8 @@ func NewGatewayClassController(mgr manager.Manager, gatewayController string) (c // Watch ContourDeployments since they can be used as parameters for // GatewayClasses. if err := c.Watch( - source.Kind(mgr.GetCache(), &contour_v1alpha1.ContourDeployment{}), - handler.EnqueueRequestsFromMapFunc(r.mapContourDeploymentToGatewayClasses), + source.Kind(mgr.GetCache(), &contour_v1alpha1.ContourDeployment{}, + handler.TypedEnqueueRequestsFromMapFunc(r.mapContourDeploymentToGatewayClasses)), ); err != nil { return nil, err } @@ -81,19 +81,14 @@ func NewGatewayClassController(mgr manager.Manager, gatewayController string) (c return c, nil } -func (r *gatewayClassReconciler) hasMatchingController(obj client.Object) bool { - gatewayClass, ok := obj.(*gatewayapi_v1.GatewayClass) - if !ok { - return false - } - +func (r *gatewayClassReconciler) hasMatchingController(gatewayClass *gatewayapi_v1.GatewayClass) bool { return gatewayClass.Spec.ControllerName == r.gatewayController } // mapContourDeploymentToGatewayClasses returns a list of reconcile requests // for all provisioner-controlled GatewayClasses that have a ParametersRef to // the specified ContourDeployment object. -func (r *gatewayClassReconciler) mapContourDeploymentToGatewayClasses(ctx context.Context, contourDeployment client.Object) []reconcile.Request { +func (r *gatewayClassReconciler) mapContourDeploymentToGatewayClasses(ctx context.Context, contourDeployment *contour_v1alpha1.ContourDeployment) []reconcile.Request { var gatewayClasses gatewayapi_v1.GatewayClassList if err := r.client.List(ctx, &gatewayClasses); err != nil { r.log.Error(err, "error listing gateway classes") diff --git a/internal/provisioner/controller/gatewayclass_test.go b/internal/provisioner/controller/gatewayclass_test.go index 261a6b01892..90ccb3149e0 100644 --- a/internal/provisioner/controller/gatewayclass_test.go +++ b/internal/provisioner/controller/gatewayclass_test.go @@ -556,7 +556,7 @@ func TestGatewayClassReconcile(t *testing.T) { // contrived way to cause this scenario. Name: "gatewayclasses-wrong.gateway.networking.k8s.io", Annotations: map[string]string{ - "gateway.networking.k8s.io/bundle-version": "v1.0.0", + "gateway.networking.k8s.io/bundle-version": "v1.1.0", }, }, }, @@ -589,7 +589,7 @@ func TestGatewayClassReconcile(t *testing.T) { ObjectMeta: meta_v1.ObjectMeta{ Name: "gatewayclasses.gateway.networking.k8s.io", Annotations: map[string]string{ - "gateway.networking.k8s.io/bundle-version-wrong": "v1.0.0", + "gateway.networking.k8s.io/bundle-version-wrong": "v1.1.0", }, }, }, @@ -676,7 +676,7 @@ func TestGatewayClassReconcile(t *testing.T) { ObjectMeta: meta_v1.ObjectMeta{ Name: "gatewayclasses.gateway.networking.k8s.io", Annotations: map[string]string{ - "gateway.networking.k8s.io/bundle-version": "v1.0.0", + "gateway.networking.k8s.io/bundle-version": "v1.1.0", }, }, }) diff --git a/internal/provisioner/model/model.go b/internal/provisioner/model/model.go index 74105f8c5c0..ea713299bff 100644 --- a/internal/provisioner/model/model.go +++ b/internal/provisioner/model/model.go @@ -223,11 +223,9 @@ type ContourSpec struct { EnvoyExtraVolumeMounts []core_v1.VolumeMount // EnvoyPodAnnotations holds the annotations that will be add to the envoy‘s pod. - // the annotations: "prometheus.io/scrape", "prometheus.io/port", "prometheus.io/path" will be overwritten with predefined value. EnvoyPodAnnotations map[string]string // ContourPodAnnotations holds the annotations that will be add to the contour's pod. - // the annotations: "prometheus.io/scrape", "prometheus.io/port" will be overwritten with predefined value. ContourPodAnnotations map[string]string // Compute Resources required by envoy container. diff --git a/internal/provisioner/objects/dataplane/dataplane.go b/internal/provisioner/objects/dataplane/dataplane.go index 19d9d1d184e..aca4a3f8430 100644 --- a/internal/provisioner/objects/dataplane/dataplane.go +++ b/internal/provisioner/objects/dataplane/dataplane.go @@ -351,8 +351,6 @@ func DesiredDaemonSet(contour *model.Contour, contourImage, envoyImage string) * UpdateStrategy: contour.Spec.EnvoyDaemonSetUpdateStrategy, Template: core_v1.PodTemplateSpec{ ObjectMeta: meta_v1.ObjectMeta{ - // TODO [danehans]: Remove the prometheus annotations when Contour is updated to - // show how the Prometheus Operator is used to scrape Contour/Envoy metrics. Annotations: envoyPodAnnotations(contour), Labels: envoyPodLabels(contour), }, @@ -425,8 +423,6 @@ func desiredDeployment(contour *model.Contour, contourImage, envoyImage string) Strategy: contour.Spec.EnvoyDeploymentStrategy, Template: core_v1.PodTemplateSpec{ ObjectMeta: meta_v1.ObjectMeta{ - // TODO [danehans]: Remove the prometheus annotations when Contour is updated to - // show how the Prometheus Operator is used to scrape Contour/Envoy metrics. Annotations: envoyPodAnnotations(contour), Labels: envoyPodLabels(contour), }, @@ -550,18 +546,6 @@ func envoyPodAnnotations(contour *model.Contour) map[string]string { annotations[k] = v } - metricsPort := objects.EnvoyMetricsPort - if contour.Spec.RuntimeSettings != nil && - contour.Spec.RuntimeSettings.Envoy != nil && - contour.Spec.RuntimeSettings.Envoy.Metrics != nil && - contour.Spec.RuntimeSettings.Envoy.Metrics.Port > 0 { - metricsPort = int32(contour.Spec.RuntimeSettings.Envoy.Metrics.Port) - } - - annotations["prometheus.io/scrape"] = "true" - annotations["prometheus.io/port"] = fmt.Sprint(metricsPort) - annotations["prometheus.io/path"] = "/stats/prometheus" - // Annotations specified on the Gateway take precedence // over annotations specified on the GatewayClass/its parameters. for k, v := range contour.CommonAnnotations() { diff --git a/internal/provisioner/objects/dataplane/dataplane_test.go b/internal/provisioner/objects/dataplane/dataplane_test.go index 590b835b163..68de6d936be 100644 --- a/internal/provisioner/objects/dataplane/dataplane_test.go +++ b/internal/provisioner/objects/dataplane/dataplane_test.go @@ -17,6 +17,7 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" apps_v1 "k8s.io/api/apps/v1" core_v1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" @@ -55,6 +56,13 @@ func checkDaemonSetHasEnvVar(t *testing.T, ds *apps_v1.DaemonSet, container, nam t.Errorf("daemonset is missing environment variable %q", name) } +func checkDaemonSetHasAnnotation(t *testing.T, ds *apps_v1.DaemonSet, key, value string) { + t.Helper() + + require.Contains(t, ds.Spec.Template.Annotations, key) + require.Equal(t, value, ds.Spec.Template.Annotations[key]) +} + func checkDaemonSetHasContainer(t *testing.T, ds *apps_v1.DaemonSet, name string, expect bool) *core_v1.Container { t.Helper() @@ -251,15 +259,6 @@ func checkContainerHasReadinessPort(t *testing.T, container *core_v1.Container, t.Errorf("container has unexpected readiness port %d", port) } -func checkDaemonSetHasMetricsPort(t *testing.T, ds *apps_v1.DaemonSet, port int32) { - t.Helper() - - if ds.Spec.Template.ObjectMeta.Annotations["prometheus.io/port"] == fmt.Sprint(port) { - return - } - t.Errorf("container has unexpected metrics port %d", port) -} - func checkEnvoyDeploymentHasAffinity(t *testing.T, d *apps_v1.Deployment, contour *model.Contour) { t.Helper() if apiequality.Semantic.DeepEqual(*d.Spec.Template.Spec.Affinity, @@ -291,6 +290,9 @@ func TestDesiredDaemonSet(t *testing.T) { "annotation": "value", "prometheus.io/scrape": "false", } + cntr.Spec.ResourceAnnotations = map[string]string{ + "other-annotation": "other-val", + } volTest := core_v1.Volume{ Name: "vol-test-mount", @@ -367,7 +369,9 @@ func TestDesiredDaemonSet(t *testing.T) { checkDaemonSecurityContext(t, ds) checkDaemonSetHasVolume(t, ds, volTest, volTestMount) checkDaemonSetHasPodAnnotations(t, ds, envoyPodAnnotations(cntr)) - checkDaemonSetHasMetricsPort(t, ds, objects.EnvoyMetricsPort) + checkDaemonSetHasAnnotation(t, ds, "annotation", "value") + checkDaemonSetHasAnnotation(t, ds, "other-annotation", "other-val") + checkDaemonSetHasAnnotation(t, ds, "prometheus.io/scrape", "false") checkDaemonSetHasResourceRequirements(t, ds, resQutoa) checkDaemonSetHasUpdateStrategy(t, ds, cntr.Spec.EnvoyDaemonSetUpdateStrategy) @@ -430,7 +434,6 @@ func TestEnvoyCustomPorts(t *testing.T) { testContourImage := "ghcr.io/projectcontour/contour:test" testEnvoyImage := "docker.io/envoyproxy/envoy:test" ds := DesiredDaemonSet(cntr, testContourImage, testEnvoyImage) - checkDaemonSetHasMetricsPort(t, ds, int32(metricPort)) checkContainerHasPort(t, ds, int32(metricPort)) container := checkDaemonSetHasContainer(t, ds, EnvoyContainerName, true) diff --git a/internal/provisioner/objects/deployment/deployment.go b/internal/provisioner/objects/deployment/deployment.go index 237e91867c6..4986d071ed4 100644 --- a/internal/provisioner/objects/deployment/deployment.go +++ b/internal/provisioner/objects/deployment/deployment.go @@ -111,7 +111,9 @@ func DesiredDeployment(contour *model.Contour, image string) *apps_v1.Deployment } if contour.Spec.DisabledFeatures != nil && len(contour.Spec.DisabledFeatures) > 0 { - args = append(args, fmt.Sprintf("--disable-feature=%s", strings.Join(model.FeaturesToStrings(contour.Spec.DisabledFeatures), ","))) + for _, f := range contour.Spec.DisabledFeatures { + args = append(args, fmt.Sprintf("--disable-feature=%s", string(f))) + } } // Pass the insecure/secure flags to Contour if using non-default ports. @@ -222,8 +224,6 @@ func DesiredDeployment(contour *model.Contour, image string) *apps_v1.Deployment Strategy: contour.Spec.ContourDeploymentStrategy, Template: core_v1.PodTemplateSpec{ ObjectMeta: meta_v1.ObjectMeta{ - // TODO [danehans]: Remove the prometheus annotations when Contour is updated to - // show how the Prometheus Operator is used to scrape Contour/Envoy metrics. Annotations: contourPodAnnotations(contour), Labels: contourPodLabels(contour), }, @@ -320,16 +320,6 @@ func contourPodAnnotations(contour *model.Contour) map[string]string { annotations[k] = v } - port := metricsPort - if contour.Spec.RuntimeSettings != nil && - contour.Spec.RuntimeSettings.Metrics != nil && - contour.Spec.RuntimeSettings.Metrics.Port > 0 { - port = contour.Spec.RuntimeSettings.Metrics.Port - } - - annotations["prometheus.io/scrape"] = "true" - annotations["prometheus.io/port"] = fmt.Sprint(port) - // Annotations specified on the Gateway take precedence // over annotations specified on the GatewayClass/its parameters. for k, v := range contour.CommonAnnotations() { diff --git a/internal/provisioner/objects/deployment/deployment_test.go b/internal/provisioner/objects/deployment/deployment_test.go index 96aa3fe47ee..2f4554be852 100644 --- a/internal/provisioner/objects/deployment/deployment_test.go +++ b/internal/provisioner/objects/deployment/deployment_test.go @@ -18,6 +18,7 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" apps_v1 "k8s.io/api/apps/v1" core_v1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" @@ -70,14 +71,11 @@ func checkDeploymentHasLabels(t *testing.T, deploy *apps_v1.Deployment, expected t.Errorf("deployment has unexpected %q labels", deploy.Labels) } -func checkPodHasAnnotations(t *testing.T, tmpl *core_v1.PodTemplateSpec, annotations map[string]string) { +func checkPodHasAnnotation(t *testing.T, tmpl core_v1.PodTemplateSpec, key, value string) { t.Helper() - for k, v := range annotations { - if val, ok := tmpl.Annotations[k]; !ok || val != v { - t.Errorf("pod template has unexpected %q annotations", tmpl.Annotations) - } - } + require.Contains(t, tmpl.Annotations, key) + require.Equal(t, value, tmpl.Annotations[key]) } func checkContainerHasArg(t *testing.T, container *core_v1.Container, arg string) { @@ -153,10 +151,6 @@ func TestDesiredDeployment(t *testing.T) { }, } - annotations := map[string]string{ - "key": "value", - "prometheus.io/scrape": "false", - } cntr.Spec.ContourResources = resQutoa // Change the Kubernetes log level to test --kubernetes-debug. @@ -168,7 +162,13 @@ func TestDesiredDeployment(t *testing.T) { cntr.Spec.ResourceLabels = map[string]string{ "key": "value", } - cntr.Spec.ContourPodAnnotations = annotations + cntr.Spec.ContourPodAnnotations = map[string]string{ + "key": "value", + "prometheus.io/scrape": "false", + } + cntr.Spec.ResourceAnnotations = map[string]string{ + "other-annotation": "other-val", + } // Use non-default container ports to test that --envoy-service-http(s)-port // flags are added. @@ -185,7 +185,9 @@ func TestDesiredDeployment(t *testing.T) { checkDeploymentHasEnvVar(t, deploy, contourNsEnvVar) checkDeploymentHasEnvVar(t, deploy, contourPodEnvVar) checkDeploymentHasLabels(t, deploy, cntr.WorkloadLabels()) - checkPodHasAnnotations(t, &deploy.Spec.Template, contourPodAnnotations(cntr)) + checkPodHasAnnotation(t, deploy.Spec.Template, "key", "value") + checkPodHasAnnotation(t, deploy.Spec.Template, "prometheus.io/scrape", "false") + checkPodHasAnnotation(t, deploy.Spec.Template, "other-annotation", "other-val") for _, port := range cntr.Spec.NetworkPublishing.Envoy.Ports { switch port.Name { @@ -278,7 +280,7 @@ func TestDesiredDeploymentWhenSettingDisabledFeature(t *testing.T) { disabledFeatures []contour_v1.Feature }{ { - description: "disable 2 featuers", + description: "disable 2 features", disabledFeatures: []contour_v1.Feature{"tlsroutes", "grpcroutes"}, }, { @@ -297,8 +299,10 @@ func TestDesiredDeploymentWhenSettingDisabledFeature(t *testing.T) { // Change the Contour watch namespaces flag deploy := DesiredDeployment(cntr, "ghcr.io/projectcontour/contour:test") container := checkDeploymentHasContainer(t, deploy, contourContainerName, true) - arg := fmt.Sprintf("--disable-feature=%s", strings.Join(model.FeaturesToStrings(tc.disabledFeatures), ",")) - checkContainerHasArg(t, container, arg) + for _, f := range tc.disabledFeatures { + arg := fmt.Sprintf("--disable-feature=%s", string(f)) + checkContainerHasArg(t, container, arg) + } }) } } diff --git a/internal/provisioner/objects/rbac/clusterrole/cluster_role_test.go b/internal/provisioner/objects/rbac/clusterrole/cluster_role_test.go index ecd4a69b1ee..15fc0ad0d3d 100644 --- a/internal/provisioner/objects/rbac/clusterrole/cluster_role_test.go +++ b/internal/provisioner/objects/rbac/clusterrole/cluster_role_test.go @@ -21,7 +21,7 @@ import ( rbac_v1 "k8s.io/api/rbac/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/utils/diff" - gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" "github.com/projectcontour/contour/internal/provisioner/model" @@ -101,7 +101,7 @@ func TestDesiredClusterRoleFilterResources(t *testing.T) { for _, rule := range policyRules { for _, apigroup := range rule.APIGroups { // gatewayclass is in isolate rule - if apigroup == gatewayapi_v1alpha2.GroupName && rule.Resources[0] != "gatewayclasses" && rule.Resources[0] != "gatewayclasses/status" { + if apigroup == gatewayapi_v1.GroupName && rule.Resources[0] != "gatewayclasses" && rule.Resources[0] != "gatewayclasses/status" { gatewayResources = append(gatewayResources, rule.Resources) break } diff --git a/internal/provisioner/objects/rbac/role/role_test.go b/internal/provisioner/objects/rbac/role/role_test.go index 20ac751c121..da7a57b8b79 100644 --- a/internal/provisioner/objects/rbac/role/role_test.go +++ b/internal/provisioner/objects/rbac/role/role_test.go @@ -20,7 +20,7 @@ import ( rbac_v1 "k8s.io/api/rbac/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/utils/diff" - gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" "github.com/projectcontour/contour/internal/provisioner/model" @@ -106,7 +106,7 @@ func TestDesiredRoleFilterResources(t *testing.T) { gatewayResources := [][]string{} for _, rule := range policyRules { for _, apigroup := range rule.APIGroups { - if apigroup == gatewayapi_v1alpha2.GroupName { + if apigroup == gatewayapi_v1.GroupName { gatewayResources = append(gatewayResources, rule.Resources) break } diff --git a/internal/provisioner/objects/rbac/util/util.go b/internal/provisioner/objects/rbac/util/util.go index 6a80ad24fe8..288c9d09238 100644 --- a/internal/provisioner/objects/rbac/util/util.go +++ b/internal/provisioner/objects/rbac/util/util.go @@ -20,7 +20,7 @@ import ( discovery_v1 "k8s.io/api/discovery/v1" networking_v1 "k8s.io/api/networking/v1" rbac_v1 "k8s.io/api/rbac/v1" - gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" "github.com/projectcontour/contour/internal/provisioner/model" @@ -64,8 +64,8 @@ func NamespacedResourcePolicyRules(resourcesToSkip []contour_v1.Feature) []rbac_ // Gateway API resources. // Note, ReferenceGrant does not currently have a .status field so it's omitted from the status rule. - PolicyRuleFor(gatewayapi_v1alpha2.GroupName, getListWatch, filterResources(resourcesToSkip, GatewayGroupNamespacedResource...)...), - PolicyRuleFor(gatewayapi_v1alpha2.GroupName, update, filterResources(resourcesToSkip, GatewayGroupNamespacedResourceStatus...)...), + PolicyRuleFor(gatewayapi_v1.GroupName, getListWatch, filterResources(resourcesToSkip, GatewayGroupNamespacedResource...)...), + PolicyRuleFor(gatewayapi_v1.GroupName, update, filterResources(resourcesToSkip, GatewayGroupNamespacedResourceStatus...)...), // Ingress resources. PolicyRuleFor(networking_v1.GroupName, getListWatch, "ingresses"), @@ -82,8 +82,8 @@ func NamespacedResourcePolicyRules(resourcesToSkip []contour_v1.Feature) []rbac_ func ClusterScopedResourcePolicyRules() []rbac_v1.PolicyRule { return []rbac_v1.PolicyRule{ // GatewayClass. - PolicyRuleFor(gatewayapi_v1alpha2.GroupName, getListWatch, "gatewayclasses"), - PolicyRuleFor(gatewayapi_v1alpha2.GroupName, update, "gatewayclasses/status"), + PolicyRuleFor(gatewayapi_v1.GroupName, getListWatch, "gatewayclasses"), + PolicyRuleFor(gatewayapi_v1.GroupName, update, "gatewayclasses/status"), // Namespaces PolicyRuleFor(core_v1.GroupName, getListWatch, "namespaces"), diff --git a/internal/provisioner/scheme.go b/internal/provisioner/scheme.go index 342140ce87f..bd472fbe558 100644 --- a/internal/provisioner/scheme.go +++ b/internal/provisioner/scheme.go @@ -32,9 +32,9 @@ func CreateScheme() (*runtime.Scheme, error) { b := runtime.SchemeBuilder{ clientgoscheme.AddToScheme, apiextensions_v1.AddToScheme, - gatewayapi_v1alpha2.AddToScheme, - gatewayapi_v1beta1.AddToScheme, - gatewayapi_v1.AddToScheme, + gatewayapi_v1alpha2.Install, + gatewayapi_v1beta1.Install, + gatewayapi_v1.Install, contour_v1alpha1.AddToScheme, } diff --git a/internal/status/backendtlspolicyconditions.go b/internal/status/backendtlspolicyconditions.go index 7b765c49992..e72aae96e6e 100644 --- a/internal/status/backendtlspolicyconditions.go +++ b/internal/status/backendtlspolicyconditions.go @@ -22,6 +22,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "github.com/projectcontour/contour/internal/gatewayapi" ) @@ -117,7 +118,7 @@ func (b *BackendTLSPolicyStatusUpdate) ConditionsForAncestorRef(ancestorRef gate } func (b *BackendTLSPolicyStatusUpdate) Mutate(obj client.Object) client.Object { - o, ok := obj.(*gatewayapi_v1alpha2.BackendTLSPolicy) + o, ok := obj.(*gatewayapi_v1alpha3.BackendTLSPolicy) if !ok { panic(fmt.Sprintf("Unsupported %T object %s/%s in status mutator", obj, b.FullName.Namespace, b.FullName.Name, diff --git a/internal/status/backendtlspolicyconditions_test.go b/internal/status/backendtlspolicyconditions_test.go index 3c55128e3d3..6c5b922a995 100644 --- a/internal/status/backendtlspolicyconditions_test.go +++ b/internal/status/backendtlspolicyconditions_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/require" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" "github.com/projectcontour/contour/internal/gatewayapi" @@ -72,7 +73,7 @@ func TestBackendTLSPolicyMutate(t *testing.T) { }, } - btp := &gatewayapi_v1alpha2.BackendTLSPolicy{ + btp := &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "test", Namespace: "test", @@ -94,7 +95,7 @@ func TestBackendTLSPolicyMutate(t *testing.T) { }, } - wantBackendTLSPolicy := &gatewayapi_v1alpha2.BackendTLSPolicy{ + wantBackendTLSPolicy := &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "test", Namespace: "test", @@ -129,7 +130,7 @@ func TestBackendTLSPolicyMutate(t *testing.T) { }, } - btp, ok := bsu.Mutate(btp).(*gatewayapi_v1alpha2.BackendTLSPolicy) + btp, ok := bsu.Mutate(btp).(*gatewayapi_v1alpha3.BackendTLSPolicy) require.True(t, ok) assert.Equal(t, wantBackendTLSPolicy, btp, 1) } diff --git a/internal/status/cache.go b/internal/status/cache.go index b197d12c2cc..16670cec309 100644 --- a/internal/status/cache.go +++ b/internal/status/cache.go @@ -22,7 +22,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" "github.com/projectcontour/contour/internal/k8s" @@ -103,7 +103,7 @@ func (c *Cache) GetStatusUpdates() []k8s.StatusUpdate { for fullname, backendTLSPolicyUpdate := range c.backendTLSPolicyUpdates { update := k8s.StatusUpdate{ NamespacedName: fullname, - Resource: &gatewayapi_v1alpha2.BackendTLSPolicy{}, + Resource: &gatewayapi_v1alpha3.BackendTLSPolicy{}, Mutator: backendTLSPolicyUpdate, } diff --git a/internal/status/routeconditions.go b/internal/status/routeconditions.go index b90d212d9fb..95d68557d04 100644 --- a/internal/status/routeconditions.go +++ b/internal/status/routeconditions.go @@ -32,11 +32,16 @@ const ( ) const ( - ReasonDegraded gatewayapi_v1.RouteConditionReason = "Degraded" - ReasonAllBackendRefsHaveZeroWeights gatewayapi_v1.RouteConditionReason = "AllBackendRefsHaveZeroWeights" - ReasonInvalidPathMatch gatewayapi_v1.RouteConditionReason = "InvalidPathMatch" - ReasonInvalidMethodMatch gatewayapi_v1.RouteConditionReason = "InvalidMethodMatch" - ReasonInvalidGateway gatewayapi_v1.RouteConditionReason = "InvalidGateway" + ReasonDegraded gatewayapi_v1.RouteConditionReason = "Degraded" + ReasonAllBackendRefsHaveZeroWeights gatewayapi_v1.RouteConditionReason = "AllBackendRefsHaveZeroWeights" + ReasonInvalidPathMatch gatewayapi_v1.RouteConditionReason = "InvalidPathMatch" + ReasonInvalidMethodMatch gatewayapi_v1.RouteConditionReason = "InvalidMethodMatch" + ReasonInvalidGateway gatewayapi_v1.RouteConditionReason = "InvalidGateway" + ReasonRouteRuleMatchConflict gatewayapi_v1.RouteConditionReason = "RuleMatchConflict" + ReasonRouteRuleMatchPartiallyConflict gatewayapi_v1.RouteConditionReason = "RuleMatchPartiallyConflict" + + MessageRouteRuleMatchConflict string = "%s's Match has conflict with other %s's Match" + MessageRouteRuleMatchPartiallyConflict string = "Dropped Rule: some of %s's rule(s) has(ve) been dropped because of conflict against other %s's rule(s)" ) // RouteStatusUpdate represents an atomic update to a @@ -178,7 +183,7 @@ func (r *RouteStatusUpdate) Mutate(obj client.Object) client.Object { route.Status.Parents = newRouteParentStatuses return route - case *gatewayapi_v1alpha2.GRPCRoute: + case *gatewayapi_v1.GRPCRoute: route := o.DeepCopy() // Get all the RouteParentStatuses that are for other Gateways. diff --git a/internal/xdscache/v3/cluster_test.go b/internal/xdscache/v3/cluster_test.go index fca970072af..b370948c6e8 100644 --- a/internal/xdscache/v3/cluster_test.go +++ b/internal/xdscache/v3/cluster_test.go @@ -724,7 +724,7 @@ func TestClusterVisit(t *testing.T) { }, ), }, - "circuitbreaker annotations": { + "CircuitBreakers annotations": { objs: []any{ &networking_v1.Ingress{ ObjectMeta: meta_v1.ObjectMeta{ @@ -772,9 +772,11 @@ func TestClusterVisit(t *testing.T) { MaxPendingRequests: wrapperspb.UInt32(4096), MaxRequests: wrapperspb.UInt32(404), MaxRetries: wrapperspb.UInt32(7), + TrackRemaining: true, }}, PerHostThresholds: []*envoy_config_cluster_v3.CircuitBreakers_Thresholds{{ MaxConnections: wrapperspb.UInt32(45), + TrackRemaining: true, }}, }, }, diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go index 975c0654743..6176fdcaad0 100644 --- a/internal/xdscache/v3/listener.go +++ b/internal/xdscache/v3/listener.go @@ -543,8 +543,14 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { alpnProtos..., ) + var authzFilter *envoy_filter_network_http_connection_manager_v3.HttpFilter + if vh.ExternalAuthorization != nil { + authzFilter = envoy_v3.FilterExternalAuthz(vh.ExternalAuthorization) + } + cm := envoy_v3.HTTPConnectionManagerBuilder(). DefaultFilters(). + AddFilter(authzFilter). RouteConfigName(fallbackCertRouteConfigName(listener)). MetricsPrefix(listener.Name). AccessLoggers(cfg.newSecureAccessLog()). diff --git a/internal/xdscache/v3/runtime_test.go b/internal/xdscache/v3/runtime_test.go index 8de43046b03..da68821341f 100644 --- a/internal/xdscache/v3/runtime_test.go +++ b/internal/xdscache/v3/runtime_test.go @@ -59,9 +59,8 @@ func TestRuntimeCacheContents(t *testing.T) { t.Run(name, func(t *testing.T) { rc := NewRuntimeCache(tc.runtimeSettings) fields := map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), - "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), - "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), + "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), + "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), } for k, v := range tc.additionalFields { fields[k] = v @@ -84,9 +83,8 @@ func TestRuntimeCacheQuery(t *testing.T) { Name: "dynamic", Layer: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), - "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), - "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), + "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), + "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), }, }, }, @@ -151,9 +149,8 @@ func TestRuntimeVisit(t *testing.T) { Name: "dynamic", Layer: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), - "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), - "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), + "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), + "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), }, }, }, @@ -191,7 +188,6 @@ func TestRuntimeVisit(t *testing.T) { Name: "dynamic", Layer: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), "envoy.resource_limits.listener.ingress_http.connection_limit": structpb.NewNumberValue(100), "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), @@ -236,7 +232,6 @@ func TestRuntimeVisit(t *testing.T) { Name: "dynamic", Layer: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), "envoy.resource_limits.listener.ingress_http.connection_limit": structpb.NewNumberValue(100), "envoy.resource_limits.listener.ingress_https.connection_limit": structpb.NewNumberValue(100), "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), @@ -304,7 +299,6 @@ func TestRuntimeCacheOnChangeDelete(t *testing.T) { Name: "dynamic", Layer: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), "envoy.resource_limits.listener.ingress_http.connection_limit": structpb.NewNumberValue(100), "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), @@ -319,9 +313,8 @@ func TestRuntimeCacheOnChangeDelete(t *testing.T) { Name: "dynamic", Layer: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "envoy.reloadable_features.sanitize_te": structpb.NewBoolValue(false), - "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), - "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), + "re2.max_program_size.error_level": structpb.NewNumberValue(1 << 20), + "re2.max_program_size.warn_level": structpb.NewNumberValue(1000), }, }, }, diff --git a/internal/xdscache/v3/server_test.go b/internal/xdscache/v3/server_test.go index a98490723e2..71d4cec431d 100644 --- a/internal/xdscache/v3/server_test.go +++ b/internal/xdscache/v3/server_test.go @@ -270,7 +270,7 @@ func TestGRPC(t *testing.T) { cancel() <-done }() - cc, err := grpc.Dial(l.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) + cc, err := grpc.NewClient(l.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer cc.Close() fn(t, cc) diff --git a/netlify.toml b/netlify.toml index 331aadeb3f6..03103522249 100644 --- a/netlify.toml +++ b/netlify.toml @@ -42,7 +42,7 @@ # kubectl apply https://projectcontour.io/quickstart/contour.yaml [[redirects]] from = "/quickstart/contour.yaml" - to = "https://raw.githubusercontent.com/projectcontour/contour/release-1.28/examples/render/contour.yaml" + to = "https://raw.githubusercontent.com/projectcontour/contour/release-1.30/examples/render/contour.yaml" status = 302 # Redirect versioned quickstarts so that they can easily be referenced by @@ -59,7 +59,7 @@ # kubectl apply https://projectcontour.io/quickstart/contour-gateway.yaml [[redirects]] from = "/quickstart/contour-gateway.yaml" - to = "https://raw.githubusercontent.com/projectcontour/contour/release-1.28/examples/render/contour-gateway.yaml" + to = "https://raw.githubusercontent.com/projectcontour/contour/release-1.30/examples/render/contour-gateway.yaml" status = 302 # Redirect versioned quickstarts so that they can easily be referenced by @@ -76,7 +76,7 @@ # kubectl apply https://projectcontour.io/quickstart/contour-gateway-provisioner.yaml [[redirects]] from = "/quickstart/contour-gateway-provisioner.yaml" - to = "https://raw.githubusercontent.com/projectcontour/contour/release-1.28/examples/render/contour-gateway-provisioner.yaml" + to = "https://raw.githubusercontent.com/projectcontour/contour/release-1.30/examples/render/contour-gateway-provisioner.yaml" status = 302 # Redirect versioned quickstarts so that they can easily be referenced by diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go index e1bafe249f9..04931c8d349 100644 --- a/pkg/config/parameters.go +++ b/pkg/config/parameters.go @@ -242,6 +242,8 @@ func (t ProtocolParameters) Validate() error { type ServerParameters struct { // Defines the XDSServer to use for `contour serve`. // Defaults to "envoy" + // Deprecated: this field will be removed in a future release when + // the `contour` xDS server implementation is removed. XDSServerType ServerType `yaml:"xds-server-type,omitempty"` } @@ -441,7 +443,7 @@ type ClusterParameters struct { // GlobalCircuitBreakerDefaults holds configurable global defaults for the circuit breakers. // // +optional - GlobalCircuitBreakerDefaults *contour_v1alpha1.GlobalCircuitBreakerDefaults `yaml:"circuit-breakers,omitempty"` + GlobalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers `yaml:"circuit-breakers,omitempty"` // UpstreamTLS contains the TLS policy parameters for upstream connections UpstreamTLS ProtocolParameters `yaml:"upstream-tls,omitempty"` @@ -709,8 +711,8 @@ type Parameters struct { // FeatureFlags defines toggle to enable new contour features. // available toggles are // useEndpointSlices - configures contour to fetch endpoint data - // from k8s endpoint slices. defaults to false and reading endpoint - // data from the k8s endpoints. + // from k8s endpoint slices. defaults to true, + // if false then reading endpoint data from the k8s endpoints. FeatureFlags []string `yaml:"featureFlags,omitempty"` } diff --git a/site/config.yaml b/site/config.yaml index 53a7502e048..c1b990cf946 100644 --- a/site/config.yaml +++ b/site/config.yaml @@ -4,7 +4,6 @@ title: "Contour" theme: "contour" outputs: home: ["HTML", "REDIRECTS"] - posts: ["HTML", "RSS"] pygmentsCodefences: true pygmentsStyle: "pygments" markup: @@ -29,7 +28,7 @@ params: github_url: "https://github.com/projectcontour/contour" github_raw_url: "https://raw.githubusercontent.com/projectcontour/contour" slack_url: "https://kubernetes.slack.com/messages/contour" - latest_version: "1.28" + latest_version: "1.30" use_advanced_docs: true docs_right_sidebar: true docs_search: true @@ -39,6 +38,8 @@ params: docs_versioning: true docs_versions: - main + - "1.30" + - "1.29" - "1.28" - "1.27" - "1.26" @@ -61,5 +62,3 @@ outputFormats: collections: guides: output: true -permalinks: - posts: /:slug diff --git a/site/content/docs/1.29/_index.md b/site/content/docs/1.29/_index.md new file mode 100644 index 00000000000..7e76e77d6df --- /dev/null +++ b/site/content/docs/1.29/_index.md @@ -0,0 +1,48 @@ +--- +cascade: + layout: docs + version: "1.29" + branch: release-1.29 +--- + +## Overview +Contour is an Ingress controller for Kubernetes that works by deploying the [Envoy proxy][1] as a reverse proxy and load balancer. +Contour supports dynamic configuration updates out of the box while maintaining a lightweight profile. + +## Philosophy +- Follow an opinionated approach which allows us to better serve most users +- Design Contour to serve both the cluster administrator and the application developer +- Use our experience with ingress to define reasonable defaults for both cluster administrators and application developers. +- Meet users where they are by understanding and adapting Contour to their use cases + +See the full [Contour Philosophy][8] page. + +## Why Contour? +Contour bridges other solution gaps in several ways: +- Dynamically update the ingress configuration with minimal dropped connections +- Safely support multiple types of ingress config in multi-team Kubernetes clusters + - [Ingress/v1][10] + - [HTTPProxy (Contour custom resource)][2] + - [Gateway API][9] +- Cleanly integrate with the Kubernetes object model + +## Prerequisites +Contour is tested with Kubernetes clusters running version [1.21 and later][4]. + +## Get started +Getting started with Contour is as simple as one command. +See the [Getting Started][3] document. + +## Troubleshooting +If you encounter issues review the [troubleshooting][5] page, [file an issue][6], or talk to us on the [#contour channel][7] on Kubernetes slack. + +[1]: https://www.envoyproxy.io/ +[2]: config/fundamentals.md +[3]: /getting-started +[4]: /resources/compatibility-matrix.md +[5]: /docs/main/troubleshooting +[6]: https://github.com/projectcontour/contour/issues +[7]: https://kubernetes.slack.com/messages/contour +[8]: /resources/philosophy +[9]: guides/gateway-api +[10]: /docs/{{< param version >}}/config/ingress diff --git a/site/content/docs/1.29/architecture.md b/site/content/docs/1.29/architecture.md new file mode 100644 index 00000000000..b29cb409d39 --- /dev/null +++ b/site/content/docs/1.29/architecture.md @@ -0,0 +1,74 @@ +# Contour Architecture + +The Contour Ingress controller is a collaboration between: + +* Envoy, which provides the high performance reverse proxy. +* Contour, which acts as a management server for Envoy and provides it with configuration. + +These containers are deployed separately, Contour as a Deployment and Envoy as a Kubernetes Daemonset or Deployment, although other configurations are possible. + +In the Envoy Pods, Contour runs as an initcontainer in `bootstrap` mode and writes an Envoy bootstrap configuration to a temporary volume. +This volume is passed to the Envoy container and directs Envoy to treat Contour as its [management server][1]. + +After initialization is complete, the Envoy container starts, retrieves the bootstrap configuration written by Contour's `bootstrap` mode, and establishes a GRPC session with Contour to receive configuration. + +Envoy will gracefully retry if the management server is unavailable, which removes any container startup ordering issues. + +Contour is a client of the Kubernetes API. +Contour watches Ingress, HTTPProxy, Gateway API, Secret, Service, and Endpoint objects, and acts as the management server for its Envoy sibling by translating its cache of objects into the relevant JSON stanzas: Service objects for CDS, Ingress for RDS, Endpoint objects for EDS, and so on). + +The transfer of information from Kubernetes to Contour is by watching the Kubernetes API utilizing [controller-runtime][4] primitives. + +Kubernetes readiness probes are configured to check whether Envoy is ready to accept connections. +The Envoy readiness probe sends GET requests to `/ready` in Envoy's administration endpoint. + +For Contour, a liveness probe checks the `/healthz` running on the Pod's metrics port. +Readiness probe is a check that Contour can access the Kubernetes API. + +## Architectural Overview +Below are a couple of high level architectural diagrams of how Contour works inside a Kubernetes cluster as well as showing the data path of a request to a backend pod. + +A request to `projectcontour.io/blog` gets routed via a load balancer to an instance of an Envoy proxy which then sends the request to a pod. + +![architectural overview][2] + +Following is a diagram of how Contour and Envoy are deployed in a Kubernetes cluster. + +### Kubernetes API Server + +The following API objects are watched: +- Services +- Endpoints +- Secrets +- Ingress +- HTTPProxy +- Gateway API (Optional) + +### Contour Deployment + +Contour is deployed in the cluster using a Kubernetes Deployment. +It has built-in leader election which is responsible for updating httproxy/ingress/gateway api resources via Kube API server. +All instances are able to serve xDS configuration to any Envoy instance, but only the leader can write status back to the API server. + +The data being served from contour instances are eventually consistent in an HA based deployment. +However HA mode is operationally scalable when you have high request rate from envoy to contour as requests are loadbalanced among contour instances. +This also helps availability zone /data center degradation events as your service continue to function. + +### Envoy Deployment + +Envoy can be deployed in two different models, as a Kubernetes Daemonset or as a Kubernetes Deployment. + +Daemonset is the standard deployment model where a single instance of Envoy is deployed per Kubernetes Node. +This allows for simple Envoy pod distribution across the cluster as well as being able to expose Envoy using `hostPorts` to improve network performance. +One potential downside of this deployment model is when a node is removed from the cluster (e.g. on a cluster scale down, etc) then the configured `preStop` hooks are not available so connections can be dropped. +This is a limitation that applies to any Daemonset in Kubernetes. + +An alternative Envoy deployment model is utilizing a Kubernetes Deployment with a configured `podAntiAffinity` which attempts to mirror the Daemonset deployment model. +A benefit of this model compared to the Daemonset version is when a node is removed from the cluster, the proper shutdown events are available so connections can be cleanly drained from Envoy before terminating. + +![architectural overview 2][3] + +[1]: https://www.envoyproxy.io/docs/envoy/v1.13.0/api-docs/xds_protocol +[2]: ../img/archoverview.png +[3]: ../img/contour_deployment_in_k8s.png +[4]: https://github.com/kubernetes-sigs/controller-runtime diff --git a/site/content/docs/1.29/config/access-logging.md b/site/content/docs/1.29/config/access-logging.md new file mode 100644 index 00000000000..0c5b6e1583c --- /dev/null +++ b/site/content/docs/1.29/config/access-logging.md @@ -0,0 +1,148 @@ +# Access Logging + +## Overview + +Contour allows you to control Envoy's access logging. +By default, HTTP and HTTPS access logs are written to `/dev/stdout` by the Envoy containers and look like following: + +``` +[2021-04-14T16:36:00.361Z] "GET /foo HTTP/1.1" 200 - 0 463 6 3 "-" "HTTPie/1.0.3" "837aa8dc-344f-4faa-b7d5-c9cce1028519" "localhost:8080" "127.0.0.1:8081" +``` + +The detailed description of each field can be found in [Envoy access logging documentation][7]. + + +## Customizing Access Log Destination + +You can change the destination file where the access log is written by using Contour [command line parameters][1] `--envoy-http-access-log` and `--envoy-https-access-log`. + +## Customizing Access Log Format + +The access log can take two different formats, both can be customized + +* Text based access logs, like shown in the example above. +* Structured JSON logging. + +### Text Based Access Logging + +Ensure that you have selected `envoy` as the access log format. +Note that this is the default format if the parameters are not given. + +- Add `--accesslog-format=envoy` to your Contour startup line, or +- Add `accesslog-format: envoy` to your configuration file. + +Customize the access log format by defining `accesslog-format-string` in your configuration file. + +```yaml +accesslog-format-string: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %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" +``` +After restarting Contour and successful validation of the configuration, the new format will take effect in a short while. + +Refer to [Envoy access logging documentation][7] for the description of the command operators, and note that the format string needs to end in a linefeed `\n`. + +### Structured JSON Logging + +Contour allows you to choose from a set of JSON fields that will be expanded into Envoy templates and sent to Envoy. +There is a default set of fields if you enable JSON logging, and you may customize which fields you log. + +The list of available fields are discoverable in the following objects: +- [jsonFields][2] are fields that have built in mappings to commonly used envoy operators. +- [envoySimpleOperators][3] are the names of simple envoy operators that don't require arguments, they are case-insensitive when configured. +- [envoyComplexOperators][4] are the names of complex envoy operators that require arguments. + +The default list of fields is available at [DefaultAccessLogJSONFields][5]. + +#### Enabling the Feature + +To enable the feature you have two options: + +- Add `--accesslog-format=json` to your Contour startup line. +- Add `accesslog-format: json` to your configuration file. + +Without any further customization, the [default fields][5] will be used. + +#### Customizing Logged Fields + +To customize the logged fields, add a `json-fields` list of strings to your configuration file. +If the `json-fields` key is not specified, the [default fields][5] will be configured. + +To use a value from [jsonFields][2] or [envoySimpleOperators][3], simply include the name of the value in the list of strings. +The jsonFields are case-sensitive, but envoySimpleOperators are not. + +To use [envoyComplexOperators][4] or to use alternative field names, specify strings as key/value pairs like `"fieldName=%OPERATOR(...)%"`. + +Unknown field names in non key/value fields will result in validation errors, as will unknown Envoy operators in key/value fields. +Note that the `DYNAMIC_METADATA` and `FILTER_STATE` Envoy logging operators are not supported at this time due to the complexity of their validation. + +See the [example config file][6] to see this used in context. + +#### Omitting Logs with Empty Values + +Contour automatically omits empty fields in Envoy JSON access logs, enhancing clarity and delivering more concise and relevant log outputs by default. + +#### Sample Configuration File + +Here is a sample config: + +```yaml +accesslog-format: json +json-fields: + - "@timestamp" + - "authority" + - "bytes_received" + - "bytes_sent" + - "customer_id=%REQ(X-CUSTOMER-ID)%" + - "downstream_local_address" + - "downstream_remote_address" + - "duration" + - "method" + - "path" + - "protocol" + - "request_id" + - "requested_server_name" + - "response_code" + - "response_flags" + - "uber_trace_id" + - "upstream_cluster" + - "upstream_host" + - "upstream_local_address" + - "upstream_service_time" + - "user_agent" + - "x_forwarded_for" +``` + +### Logging the route source + +Contour can log the kind, namespace and name of the Kubernetes resource that generated the route for a given access log entry. + +For text-based access logging, the following command operators can be used: +- `%METADATA(ROUTE:envoy.access_loggers.file:io.projectcontour.kind)%` +- `%METADATA(ROUTE:envoy.access_loggers.file:io.projectcontour.namespace)%` +- `%METADATA(ROUTE:envoy.access_loggers.file:io.projectcontour.name)%` + +For JSON access logging, the following fields can be added (these are Contour-specific aliases to the above command operators): +- `contour_config_kind` +- `contour_config_namespace` +- `contour_config_name` + +## Using Access Log Formatter Extensions + +Envoy allows implementing custom access log command operators as extensions. +Following extensions are supported by Contour: + +| Command operator | Description | +|------------------|-------------| +| [REQ_WITHOUT_QUERY][8] | Works the same way as REQ except that it will remove the query string. It is used to avoid logging any sensitive information into the access log. | +| [METADATA][9] | Prints all types of metadata. | + + + +[1]: ../configuration#serve-flags +[2]: https://github.com/search?q=%22var+jsonFields%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[3]: https://github.com/search?q=%22var+envoySimpleOperators%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[4]: https://github.com/search?q=%22var+envoyComplexOperators%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[5]: https://github.com/search?q=%22var+DefaultAccessLogJSONFields%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[6]: {{< param github_url >}}/tree/{{< param latest_version >}}/examples/contour/01-contour-config.yaml +[7]: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/formatter/req_without_query/v3/req_without_query.proto +[9]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/formatter/metadata/v3/metadata.proto \ No newline at end of file diff --git a/site/content/docs/1.29/config/annotations.md b/site/content/docs/1.29/config/annotations.md new file mode 100644 index 00000000000..4d805f8f0f1 --- /dev/null +++ b/site/content/docs/1.29/config/annotations.md @@ -0,0 +1,98 @@ +# Annotations Reference + + + +Annotations are used in Ingress Controllers to configure features that are not covered by the Kubernetes Ingress API. + +Some of the features that have been historically configured via annotations are supported as first-class features in Contour's [HTTPProxy API][15], which provides a more robust configuration interface over annotations. + +However, Contour still supports a number of annotations on the Ingress resources. + +## Standard Kubernetes Ingress annotations + +The following Kubernetes annotations are supported on `Ingress` objects: + +### Ingress Class + +The Ingress class annotation can be used to specify which Ingress controller should serve a particular Ingress object. +This annotation may be specified as the standard `kubernetes.io/ingress.class` or a Contour-specific `projectcontour.io/ingress.class`. +In both cases, they will behave as follows, by default: + +* If not set, then all Ingress controllers serve the Ingress. +* If specified as `kubernetes.io/ingress.class: contour`, then Contour serves the Ingress. +* If any other value, Contour ignores the Ingress definition. + +You can override the default class `contour` by providing the `--ingress-class-name` flag to Contour. +This can be useful while you are migrating from another controller, or if you need multiple instances of Contour. +If you do this, the behavior is as follows: +* If the annotation is not set, Contour will ignore the Ingress. +* If the annotation is set to any value other than the one passed to the `--ingress-class-name` flag, Contour will ignore the Ingress. +* If the annotation matches the value that you passed to `--ingress-class-name` flag, Contour will serve the Ingress. + +This same logic applies for these annotations on HTTPProxy objects. + +_Note: Both `Ingress` and `HTTPProxy` now have an `IngressClassName` field in their spec. Going forward this is the preferred way to specify an ingress class, rather than using an annotation. If both the annotation and the spec field are specified on an object, the annotation takes preference for backwards compatibility._ + +_Note: The `--ingress-class-name` value can be a comma-separated list of class names to match against. Contour will serve the Ingress or HTTPProxy if the annotation or IngressClassName matches any of the specified class name values. + +### Other annotations + + - `ingress.kubernetes.io/force-ssl-redirect`: Requires TLS/SSL for the Ingress to Envoy by setting the [Envoy virtual host option require_tls][16]. + - `kubernetes.io/ingress.allow-http`: Instructs Contour to not create an Envoy HTTP route for the virtual host. The Ingress exists only for HTTPS requests. Specify `"false"` for Envoy to mark the endpoint as HTTPS only. All other values are ignored. + +The `ingress.kubernetes.io/force-ssl-redirect` annotation takes precedence over `kubernetes.io/ingress.allow-http`. If they are set to `"true"` and `"false"` respectively, Contour *will* create an Envoy HTTP route for the Virtual host, and set the `require_tls` virtual host option. + +## Contour specific Ingress annotations + + - `projectcontour.io/ingress.class`: The Ingress class that should interpret and serve the Ingress. See the [main Ingress class annotation section](#ingress-class) for more details. + - `projectcontour.io/num-retries`: [The maximum number of retries][1] Envoy should make before abandoning and returning an error to the client. Applies only if `projectcontour.io/retry-on` is specified. Set to -1 to disable retries. + - `projectcontour.io/per-try-timeout`: [The timeout per retry attempt][2], if there should be one. Applies only if `projectcontour.io/retry-on` is specified. + - `projectcontour.io/response-timeout`: [The Envoy HTTP route timeout][3], specified as a [golang duration][4]. By default, Envoy has a 15 second timeout for a backend service to respond. Set this to `infinity` to specify that Envoy should never timeout the connection to the backend. Note that the value `0s` / zero has special semantics for Envoy. + - `projectcontour.io/retry-on`: [The conditions for Envoy to retry a request][5]. See also [possible values and their meanings for `retry-on`][6]. + - `projectcontour.io/tls-minimum-protocol-version`: [The minimum TLS protocol version][7] the TLS listener should support. Valid options are `1.3`, `1.2` (default). + - `projectcontour.io/tls-maximum-protocol-version`: [The maximum TLS protocol version][7] the TLS listener should support. Valid options are `1.2`, `1.3` (default). + - `projectcontour.io/websocket-routes`: [The routes supporting websocket protocol][8], the annotation value contains a list of route paths separated by a comma that must match with the ones defined in the `Ingress` definition. Defaults to Envoy's default behavior which is `use_websocket` to `false`. + - `projectcontour.io/tls-cert-namespace`: The namespace where all TLS secrets of this Ingress are searched. This is necessary to use [TLS Certificate Delegation][18] with Ingress v1 because the slash notation (ex: different-ns/app-cert) used by HTTPProxy and Ingress v1beta1 is not accepted. See [this issue][19] for details. + +## Contour specific Service annotations + +A [Kubernetes Service][9] maps to an [Envoy Cluster][10]. Envoy clusters have many settings to control specific behaviors. These annotations allow access to some of those settings. + +- `projectcontour.io/max-connections`: [The maximum number of connections][11] that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. +- `projectcontour.io/max-pending-requests`: [The maximum number of pending requests][13] that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. +- `projectcontour.io/max-requests`: [The maximum parallel requests][13] a single Envoy instance allows to the Kubernetes Service; defaults to 1024 +- `projectcontour.io/max-retries`: [The maximum number of parallel retries][14] a single Envoy instance allows to the Kubernetes Service; defaults to 3. This is independent of the per-Kubernetes Ingress number of retries (`projectcontour.io/num-retries`) and retry-on (`projectcontour.io/retry-on`), which control whether retries are attempted and how many times a single request can retry. +- `projectcontour.io/per-host-max-connections`: [The maximum number of connections][20] that a single Envoy instance allows to an individual Kubernetes Service endpoint; no default (unlimited). +- `projectcontour.io/upstream-protocol.{protocol}` : The protocol used to proxy requests to the upstream service. + The annotation value contains a comma-separated list of port names and/or numbers that must match with the ones defined in the `Service` definition. + This value can also be specified in the `spec.routes.services[].protocol` field on the HTTPProxy object, where it takes precedence over the Service annotation. + Supported protocol names are: `h2`, `h2c`, and `tls`: + - The `tls` protocol allows for requests which terminate at Envoy to proxy via TLS to the upstream. + This protocol should be used for HTTP/1.1 services over TLS. + _Note that validating the upstream TLS certificate requires additionally setting the [validation][17] field._ + - The `h2` protocol proxies requests to the upstream using HTTP/2 over TLS. + - The `h2c` protocol proxies requests to the upstream using cleartext HTTP/2. + +## Contour specific HTTPProxy annotations +- `projectcontour.io/ingress.class`: The Ingress class that should interpret and serve the HTTPProxy. See the [main Ingress class annotation section](#ingress-class) for more details. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries +[2]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-retrypolicy-retry-on +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-timeout +[4]: https://golang.org/pkg/time/#ParseDuration +[5]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-retrypolicy-retry-on +[6]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-retry-on +[7]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto.html#extensions-transport-sockets-tls-v3-tlsparameters +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-upgrade-configs +[9]: https://kubernetes.io/docs/concepts/services-networking/service/ +[10]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/intro/terminology +[11]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-connections +[12]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-pending-requests +[13]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-requests +[14]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-retries +[15]: fundamentals.md +[16]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-virtualhost-require-tls +[17]: api/#projectcontour.io/v1.UpstreamValidation +[18]: ../config/tls-delegation/ +[19]: https://github.com/projectcontour/contour/issues/3544 +[20]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-per-host-thresholds \ No newline at end of file diff --git a/site/content/docs/1.29/config/api-reference.html b/site/content/docs/1.29/config/api-reference.html new file mode 100644 index 00000000000..b9ba8f7400d --- /dev/null +++ b/site/content/docs/1.29/config/api-reference.html @@ -0,0 +1,9109 @@ +

Packages:

+ +

projectcontour.io/v1

+

+

Package v1 holds the specification for the projectcontour.io Custom Resource Definitions (CRDs).

+

In building this CRD, we’ve inadvertently overloaded the word “Condition”, so we’ve tried to make +this spec clear as to which types of condition are which.

+

MatchConditions are used by Routes and Includes to specify rules to match requests against for either +routing or inclusion.

+

DetailedConditions are used in the Status of these objects to hold information about the relevant +state of the object and the world around it.

+

SubConditions are used underneath DetailedConditions to give more detail to errors or warnings.

+

+Resource Types: + +

HTTPProxy +

+

+

HTTPProxy is an Ingress CRD specification.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1 + +
+kind
+string +
HTTPProxy
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +HTTPProxySpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+virtualhost +
+ + +VirtualHost + + +
+(Optional) +

Virtualhost appears at most once. If it is present, the object is considered +to be a “root” HTTPProxy.

+
+routes +
+ + +[]Route + + +
+(Optional) +

Routes are the ingress routes. If TCPProxy is present, Routes is ignored.

+
+tcpproxy +
+ + +TCPProxy + + +
+(Optional) +

TCPProxy holds TCP proxy information.

+
+includes +
+ + +[]Include + + +
+(Optional) +

Includes allow for specific routing configuration to be included from another HTTPProxy, +possibly in another namespace.

+
+ingressClassName +
+ +string + +
+(Optional) +

IngressClassName optionally specifies the ingress class to use for this +HTTPProxy. This replaces the deprecated kubernetes.io/ingress.class +annotation. For backwards compatibility, when that annotation is set, it +is given precedence over this field.

+
+
+status +
+ + +HTTPProxyStatus + + +
+(Optional) +

Status is a container for computed information about the HTTPProxy.

+
+

TLSCertificateDelegation +

+

+

TLSCertificateDelegation is an TLS Certificate Delegation CRD specification. +See design/tls-certificate-delegation.md for details.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1 + +
+kind
+string +
TLSCertificateDelegation
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +TLSCertificateDelegationSpec + + +
+
+
+ + + + + +
+delegations +
+ + +[]CertificateDelegation + + +
+
+
+status +
+ + +TLSCertificateDelegationStatus + + +
+(Optional) +
+

AuthorizationPolicy +

+

+(Appears on: +AuthorizationServer, +Route) +

+

+

AuthorizationPolicy modifies how client requests are authenticated.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+disabled +
+ +bool + +
+(Optional) +

When true, this field disables client request authentication +for the scope of the policy.

+
+context +
+ +map[string]string + +
+(Optional) +

Context is a set of key/value pairs that are sent to the +authentication server in the check request. If a context +is provided at an enclosing scope, the entries are merged +such that the inner scope overrides matching keys from the +outer scope.

+
+

AuthorizationServer +

+

+(Appears on: +VirtualHost, +ContourConfigurationSpec) +

+

+

AuthorizationServer configures an external server to authenticate +client requests. The external server must implement the v3 Envoy +external authorization GRPC protocol (https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto).

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+extensionRef +
+ + +ExtensionServiceReference + + +
+(Optional) +

ExtensionServiceRef specifies the extension resource that will authorize client requests.

+
+authPolicy +
+ + +AuthorizationPolicy + + +
+(Optional) +

AuthPolicy sets a default authorization policy for client requests. +This policy will be used unless overridden by individual routes.

+
+responseTimeout +
+ +string + +
+(Optional) +

ResponseTimeout configures maximum time to wait for a check response from the authorization server. +Timeout durations are expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. +The string “infinity” is also a valid input and specifies no timeout.

+
+failOpen +
+ +bool + +
+(Optional) +

If FailOpen is true, the client request is forwarded to the upstream service +even if the authorization server fails to respond. This field should not be +set in most cases. It is intended for use only while migrating applications +from internal authorization to Contour external authorization.

+
+withRequestBody +
+ + +AuthorizationServerBufferSettings + + +
+(Optional) +

WithRequestBody specifies configuration for sending the client request’s body to authorization server.

+
+

AuthorizationServerBufferSettings +

+

+(Appears on: +AuthorizationServer) +

+

+

AuthorizationServerBufferSettings enables ExtAuthz filter to buffer client request data and send it as part of authorization request

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+maxRequestBytes +
+ +uint32 + +
+(Optional) +

MaxRequestBytes sets the maximum size of message body ExtAuthz filter will hold in-memory.

+
+allowPartialMessage +
+ +bool + +
+(Optional) +

If AllowPartialMessage is true, then Envoy will buffer the body until MaxRequestBytes are reached.

+
+packAsBytes +
+ +bool + +
+(Optional) +

If PackAsBytes is true, the body sent to Authorization Server is in raw bytes.

+
+

CORSHeaderValue +(string alias)

+

+(Appears on: +CORSPolicy) +

+

+

CORSHeaderValue specifies the value of the string headers returned by a cross-domain request.

+

+

CORSPolicy +

+

+(Appears on: +VirtualHost) +

+

+

CORSPolicy allows setting the CORS policy

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+allowCredentials +
+ +bool + +
+(Optional) +

Specifies whether the resource allows credentials.

+
+allowOrigin +
+ +[]string + +
+

AllowOrigin specifies the origins that will be allowed to do CORS requests. +Allowed values include “*” which signifies any origin is allowed, an exact +origin of the form “scheme://host[:port]” (where port is optional), or a valid +regex pattern. +Note that regex patterns are validated and a simple “glob” pattern (e.g. *.foo.com) +will be rejected or produce unexpected matches when applied as a regex.

+
+allowMethods +
+ + +[]CORSHeaderValue + + +
+

AllowMethods specifies the content for the access-control-allow-methods header.

+
+allowHeaders +
+ + +[]CORSHeaderValue + + +
+(Optional) +

AllowHeaders specifies the content for the access-control-allow-headers header.

+
+exposeHeaders +
+ + +[]CORSHeaderValue + + +
+(Optional) +

ExposeHeaders Specifies the content for the access-control-expose-headers header.

+
+maxAge +
+ +string + +
+(Optional) +

MaxAge indicates for how long the results of a preflight request can be cached. +MaxAge durations are expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. +Only positive values are allowed while 0 disables the cache requiring a preflight OPTIONS +check for all cross-origin requests.

+
+allowPrivateNetwork +
+ +bool + +
+

AllowPrivateNetwork specifies whether to allow private network requests. +See https://developer.chrome.com/blog/private-network-access-preflight.

+
+

CertificateDelegation +

+

+(Appears on: +TLSCertificateDelegationSpec) +

+

+

CertificateDelegation maps the authority to reference a secret +in the current namespace to a set of namespaces.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+secretName +
+ +string + +
+

required, the name of a secret in the current namespace.

+
+targetNamespaces +
+ +[]string + +
+

required, the namespaces the authority to reference the +secret will be delegated to. +If TargetNamespaces is nil or empty, the CertificateDelegation’ +is ignored. If the TargetNamespace list contains the character, “*” +the secret will be delegated to all namespaces.

+
+

ClientCertificateDetails +

+

+(Appears on: +DownstreamValidation) +

+

+

ClientCertificateDetails defines which parts of the client certificate will be forwarded.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+subject +
+ +bool + +
+(Optional) +

Subject of the client cert.

+
+cert +
+ +bool + +
+(Optional) +

Client cert in URL encoded PEM format.

+
+chain +
+ +bool + +
+(Optional) +

Client cert chain (including the leaf cert) in URL encoded PEM format.

+
+dns +
+ +bool + +
+(Optional) +

DNS type Subject Alternative Names of the client cert.

+
+uri +
+ +bool + +
+(Optional) +

URI type Subject Alternative Name of the client cert.

+
+

CookieDomainRewrite +

+

+(Appears on: +CookieRewritePolicy) +

+

+

+ + + + + + + + + + + + + +
FieldDescription
+value +
+ +string + +
+

Value is the value to rewrite the Domain attribute to. +For now this is required.

+
+

CookiePathRewrite +

+

+(Appears on: +CookieRewritePolicy) +

+

+

+ + + + + + + + + + + + + +
FieldDescription
+value +
+ +string + +
+

Value is the value to rewrite the Path attribute to. +For now this is required.

+
+

CookieRewritePolicy +

+

+(Appears on: +Route, +Service) +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of the cookie for which attributes will be rewritten.

+
+pathRewrite +
+ + +CookiePathRewrite + + +
+(Optional) +

PathRewrite enables rewriting the Set-Cookie Path element. +If not set, Path will not be rewritten.

+
+domainRewrite +
+ + +CookieDomainRewrite + + +
+(Optional) +

DomainRewrite enables rewriting the Set-Cookie Domain element. +If not set, Domain will not be rewritten.

+
+secure +
+ +bool + +
+(Optional) +

Secure enables rewriting the Set-Cookie Secure element. +If not set, Secure attribute will not be rewritten.

+
+sameSite +
+ +string + +
+(Optional) +

SameSite enables rewriting the Set-Cookie SameSite element. +If not set, SameSite attribute will not be rewritten.

+
+

DetailedCondition +

+

+(Appears on: +HTTPProxyStatus, +TLSCertificateDelegationStatus, +ContourConfigurationStatus, +ExtensionServiceStatus) +

+

+

DetailedCondition is an extension of the normal Kubernetes conditions, with two extra +fields to hold sub-conditions, which provide more detailed reasons for the state (True or False) +of the condition.

+

errors holds information about sub-conditions which are fatal to that condition and render its state False.

+

warnings holds information about sub-conditions which are not fatal to that condition and do not force the state to be False.

+

Remember that Conditions have a type, a status, and a reason.

+

The type is the type of the condition, the most important one in this CRD set is Valid. +Valid is a positive-polarity condition: when it is status: true there are no problems.

+

In more detail, status: true means that the object is has been ingested into Contour with no errors. +warnings may still be present, and will be indicated in the Reason field. There must be zero entries in the errors +slice in this case.

+

Valid, status: false means that the object has had one or more fatal errors during processing into Contour. +The details of the errors will be present under the errors field. There must be at least one error in the errors +slice if status is false.

+

For DetailedConditions of types other than Valid, the Condition must be in the negative polarity. +When they have status true, there is an error. There must be at least one entry in the errors Subcondition slice. +When they have status false, there are no serious errors, and there must be zero entries in the errors slice. +In either case, there may be entries in the warnings slice.

+

Regardless of the polarity, the reason and message fields must be updated with either the detail of the reason +(if there is one and only one entry in total across both the errors and warnings slices), or +MultipleReasons if there is more than one entry.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+Condition +
+ + +Kubernetes meta/v1.Condition + + +
+

+(Members of Condition are embedded into this type.) +

+
+errors +
+ + +[]SubCondition + + +
+(Optional) +

Errors contains a slice of relevant error subconditions for this object.

+

Subconditions are expected to appear when relevant (when there is a error), and disappear when not relevant. +An empty slice here indicates no errors.

+
+warnings +
+ + +[]SubCondition + + +
+(Optional) +

Warnings contains a slice of relevant warning subconditions for this object.

+

Subconditions are expected to appear when relevant (when there is a warning), and disappear when not relevant. +An empty slice here indicates no warnings.

+
+

DownstreamValidation +

+

+(Appears on: +TLS) +

+

+

DownstreamValidation defines how to verify the client certificate.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caSecret +
+ +string + +
+(Optional) +

Name of a Kubernetes secret that contains a CA certificate bundle. +The secret must contain key named ca.crt. +The client certificate must validate against the certificates in the bundle. +If specified and SkipClientCertValidation is true, client certificates will +be required on requests. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret.

+
+skipClientCertValidation +
+ +bool + +
+(Optional) +

SkipClientCertValidation disables downstream client certificate +validation. Defaults to false. This field is intended to be used in +conjunction with external authorization in order to enable the external +authorization server to validate client certificates. When this field +is set to true, client certificates are requested but not verified by +Envoy. If CACertificate is specified, client certificates are required on +requests, but not verified. If external authorization is in use, they are +presented to the external authorization server.

+
+forwardClientCertificate +
+ + +ClientCertificateDetails + + +
+(Optional) +

ForwardClientCertificate adds the selected data from the passed client TLS certificate +to the x-forwarded-client-cert header.

+
+crlSecret +
+ +string + +
+(Optional) +

Name of a Kubernetes opaque secret that contains a concatenated list of PEM encoded CRLs. +The secret must contain key named crl.pem. +This field will be used to verify that a client certificate has not been revoked. +CRLs must be available from all CAs, unless crlOnlyVerifyLeafCert is true. +Large CRL lists are not supported since individual secrets are limited to 1MiB in size. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret.

+
+crlOnlyVerifyLeafCert +
+ +bool + +
+(Optional) +

If this option is set to true, only the certificate at the end of the +certificate chain will be subject to validation by CRL.

+
+optionalClientCertificate +
+ +bool + +
+(Optional) +

OptionalClientCertificate when set to true will request a client certificate +but allow the connection to continue if the client does not provide one. +If a client certificate is sent, it will be verified according to the +other properties, which includes disabling validation if +SkipClientCertValidation is set. Defaults to false.

+
+

ExtensionServiceReference +

+

+(Appears on: +AuthorizationServer) +

+

+

ExtensionServiceReference names an ExtensionService resource.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion +
+ +string + +
+(Optional) +

API version of the referent. +If this field is not specified, the default “projectcontour.io/v1alpha1” will be used

+
+namespace +
+ +string + +
+(Optional) +

Namespace of the referent. +If this field is not specifies, the namespace of the resource that targets the referent will be used.

+

More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

+
+name +
+ +string + +
+

Name of the referent.

+

More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

+
+

Feature +(string alias)

+

+(Appears on: +ContourSettings) +

+

+

+

GenericKeyDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

GenericKeyDescriptor defines a descriptor entry with a static key and +value.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+key +
+ +string + +
+(Optional) +

Key defines the key of the descriptor entry. If not set, the +key is set to “generic_key”.

+
+value +
+ +string + +
+

Value defines the value of the descriptor entry.

+
+

GlobalRateLimitPolicy +

+

+(Appears on: +RateLimitPolicy, +RateLimitServiceConfig) +

+

+

GlobalRateLimitPolicy defines global rate limiting parameters.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+disabled +
+ +bool + +
+(Optional) +

Disabled configures the HTTPProxy to not use +the default global rate limit policy defined by the Contour configuration.

+
+descriptors +
+ + +[]RateLimitDescriptor + + +
+(Optional) +

Descriptors defines the list of descriptors that will +be generated and sent to the rate limit service. Each +descriptor contains 1+ key-value pair entries.

+
+

HTTPDirectResponsePolicy +

+

+(Appears on: +Route) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+statusCode +
+ +int + +
+

StatusCode is the HTTP response status to be returned.

+
+body +
+ +string + +
+(Optional) +

Body is the content of the response body. +If this setting is omitted, no body is included in the generated response.

+

Note: Body is not recommended to set too long +otherwise it can have significant resource usage impacts.

+
+

HTTPHealthCheckPolicy +

+

+(Appears on: +Route) +

+

+

HTTPHealthCheckPolicy defines health checks on the upstream service.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+path +
+ +string + +
+

HTTP endpoint used to perform health checks on upstream service

+
+host +
+ +string + +
+

The value of the host header in the HTTP health check request. +If left empty (default value), the name “contour-envoy-healthcheck” +will be used.

+
+intervalSeconds +
+ +int64 + +
+(Optional) +

The interval (seconds) between health checks

+
+timeoutSeconds +
+ +int64 + +
+(Optional) +

The time to wait (seconds) for a health check response

+
+unhealthyThresholdCount +
+ +int64 + +
+(Optional) +

The number of unhealthy health checks required before a host is marked unhealthy

+
+healthyThresholdCount +
+ +int64 + +
+(Optional) +

The number of healthy health checks required before a host is marked healthy

+
+expectedStatuses +
+ + +[]HTTPStatusRange + + +
+(Optional) +

The ranges of HTTP response statuses considered healthy. Follow half-open +semantics, i.e. for each range the start is inclusive and the end is exclusive. +Must be within the range [100,600). If not specified, only a 200 response status +is considered healthy.

+
+

HTTPInternalRedirectPolicy +

+

+(Appears on: +Route) +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+maxInternalRedirects +
+ +uint32 + +
+(Optional) +

MaxInternalRedirects An internal redirect is not handled, unless the number of previous internal +redirects that a downstream request has encountered is lower than this value.

+
+redirectResponseCodes +
+ + +[]RedirectResponseCode + + +
+(Optional) +

RedirectResponseCodes If unspecified, only 302 will be treated as internal redirect. +Only 301, 302, 303, 307 and 308 are valid values.

+
+allowCrossSchemeRedirect +
+ +string + +
+(Optional) +

AllowCrossSchemeRedirect Allow internal redirect to follow a target URI with a different scheme +than the value of x-forwarded-proto. +SafeOnly allows same scheme redirect and safe cross scheme redirect, which means if the downstream +scheme is HTTPS, both HTTPS and HTTP redirect targets are allowed, but if the downstream scheme +is HTTP, only HTTP redirect targets are allowed.

+
+denyRepeatedRouteRedirect +
+ +bool + +
+(Optional) +

If DenyRepeatedRouteRedirect is true, rejects redirect targets that are pointing to a route that has +been followed by a previous redirect from the current route.

+
+

HTTPProxySpec +

+

+(Appears on: +HTTPProxy) +

+

+

HTTPProxySpec defines the spec of the CRD.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+virtualhost +
+ + +VirtualHost + + +
+(Optional) +

Virtualhost appears at most once. If it is present, the object is considered +to be a “root” HTTPProxy.

+
+routes +
+ + +[]Route + + +
+(Optional) +

Routes are the ingress routes. If TCPProxy is present, Routes is ignored.

+
+tcpproxy +
+ + +TCPProxy + + +
+(Optional) +

TCPProxy holds TCP proxy information.

+
+includes +
+ + +[]Include + + +
+(Optional) +

Includes allow for specific routing configuration to be included from another HTTPProxy, +possibly in another namespace.

+
+ingressClassName +
+ +string + +
+(Optional) +

IngressClassName optionally specifies the ingress class to use for this +HTTPProxy. This replaces the deprecated kubernetes.io/ingress.class +annotation. For backwards compatibility, when that annotation is set, it +is given precedence over this field.

+
+

HTTPProxyStatus +

+

+(Appears on: +HTTPProxy) +

+

+

HTTPProxyStatus reports the current state of the HTTPProxy.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+currentStatus +
+ +string + +
+(Optional) +
+description +
+ +string + +
+(Optional) +
+loadBalancer +
+ + +Kubernetes core/v1.LoadBalancerStatus + + +
+(Optional) +

LoadBalancer contains the current status of the load balancer.

+
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains information about the current status of the HTTPProxy, +in an upstream-friendly container.

+

Contour will update a single condition, Valid, that is in normal-true polarity. +That is, when currentStatus is valid, the Valid condition will be status: true, +and vice versa.

+

Contour will leave untouched any other Conditions set in this block, +in case some other controller wants to add a Condition.

+

If you are another controller owner and wish to add a condition, you should +namespace your condition with a label, like controller.domain.com/ConditionName.

+
+

HTTPRequestRedirectPolicy +

+

+(Appears on: +Route) +

+

+

HTTPRequestRedirectPolicy defines configuration for redirecting a request.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+scheme +
+ +string + +
+(Optional) +

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.

+
+hostname +
+ +string + +
+(Optional) +

Hostname is the precise hostname to be used in the value of the Location +header in the response. +When empty, the hostname of the request is used. +No wildcards are allowed.

+
+port +
+ +int32 + +
+(Optional) +

Port is the port to be used in the value of the Location +header in the response. +When empty, port (if specified) of the request is used.

+
+statusCode +
+ +int + +
+(Optional) +

StatusCode is the HTTP status code to be used in response.

+
+path +
+ +string + +
+(Optional) +

Path allows for redirection to a different path from the +original on the request. The path must start with a +leading slash.

+

Note: Only one of Path or Prefix can be defined.

+
+prefix +
+ +string + +
+(Optional) +

Prefix defines the value to swap the matched prefix or path with. +The prefix must start with a leading slash.

+

Note: Only one of Path or Prefix can be defined.

+
+

HTTPStatusRange +

+

+(Appears on: +HTTPHealthCheckPolicy) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+start +
+ +int64 + +
+

The start (inclusive) of a range of HTTP status codes.

+
+end +
+ +int64 + +
+

The end (exclusive) of a range of HTTP status codes.

+
+

HeaderHashOptions +

+

+(Appears on: +RequestHashPolicy) +

+

+

HeaderHashOptions contains options to configure a HTTP request header hash +policy, used in request attribute hash based load balancing.

+

+ + + + + + + + + + + + + +
FieldDescription
+headerName +
+ +string + +
+

HeaderName is the name of the HTTP request header that will be used to +calculate the hash key. If the header specified is not present on a +request, no hash will be produced.

+
+

HeaderMatchCondition +

+

+(Appears on: +MatchCondition, +RequestHeaderValueMatchDescriptor) +

+

+

HeaderMatchCondition specifies how to conditionally match against HTTP +headers. The Name field is required, only one of Present, NotPresent, +Contains, NotContains, Exact, NotExact and Regex can be set. +For negative matching rules only (e.g. NotContains or NotExact) you can set +TreatMissingAsEmpty. +IgnoreCase has no effect for Regex.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of the header to match against. Name is required. +Header names are case insensitive.

+
+present +
+ +bool + +
+(Optional) +

Present specifies that condition is true when the named header +is present, regardless of its value. Note that setting Present +to false does not make the condition true if the named header +is absent.

+
+notpresent +
+ +bool + +
+(Optional) +

NotPresent specifies that condition is true when the named header +is not present. Note that setting NotPresent to false does not +make the condition true if the named header is present.

+
+contains +
+ +string + +
+(Optional) +

Contains specifies a substring that must be present in +the header value.

+
+notcontains +
+ +string + +
+(Optional) +

NotContains specifies a substring that must not be present +in the header value.

+
+ignoreCase +
+ +bool + +
+(Optional) +

IgnoreCase specifies that string matching should be case insensitive. +Note that this has no effect on the Regex parameter.

+
+exact +
+ +string + +
+(Optional) +

Exact specifies a string that the header value must be equal to.

+
+notexact +
+ +string + +
+(Optional) +

NoExact specifies a string that the header value must not be +equal to. The condition is true if the header has any other value.

+
+regex +
+ +string + +
+(Optional) +

Regex specifies a regular expression pattern that must match the header +value.

+
+treatMissingAsEmpty +
+ +bool + +
+(Optional) +

TreatMissingAsEmpty specifies if the header match rule specified header +does not exist, this header value will be treated as empty. Defaults to false. +Unlike the underlying Envoy implementation this is only supported for +negative matches (e.g. NotContains, NotExact).

+
+

HeaderValue +

+

+(Appears on: +HeadersPolicy, +LocalRateLimitPolicy) +

+

+

HeaderValue represents a header name/value pair

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name represents a key of a header

+
+value +
+ +string + +
+

Value represents the value of a header specified by a key

+
+

HeadersPolicy +

+

+(Appears on: +Route, +Service) +

+

+

HeadersPolicy defines how headers are managed during forwarding. +The Host header is treated specially and if set in a HTTP request +will be used as the SNI server name when forwarding over TLS. It is an +error to attempt to set the Host header in a HTTP response.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+set +
+ + +[]HeaderValue + + +
+(Optional) +

Set specifies a list of HTTP header values that will be set in the HTTP header. +If the header does not exist it will be added, otherwise it will be overwritten with the new value.

+
+remove +
+ +[]string + +
+(Optional) +

Remove specifies a list of HTTP header names to remove.

+
+

IPFilterPolicy +

+

+(Appears on: +Route, +VirtualHost) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+source +
+ + +IPFilterSource + + +
+

Source indicates how to determine the ip address to filter on, and can be +one of two values: +- Remote filters on the ip address of the client, accounting for PROXY and +X-Forwarded-For as needed. +- Peer filters on the ip of the network request, ignoring PROXY and +X-Forwarded-For.

+
+cidr +
+ +string + +
+

CIDR is a CIDR block of ipv4 or ipv6 addresses to filter on. This can also be +a bare IP address (without a mask) to filter on exactly one address.

+
+

IPFilterSource +(string alias)

+

+(Appears on: +IPFilterPolicy) +

+

+

IPFilterSource indicates which IP should be considered for filtering

+

+ + + + + + + + + + + + +
ValueDescription

"Peer"

"Remote"

+

Include +

+

+(Appears on: +HTTPProxySpec) +

+

+

Include describes a set of policies that can be applied to an HTTPProxy in a namespace.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name of the HTTPProxy

+
+namespace +
+ +string + +
+(Optional) +

Namespace of the HTTPProxy to include. Defaults to the current namespace if not supplied.

+
+conditions +
+ + +[]MatchCondition + + +
+(Optional) +

Conditions are a set of rules that are applied to included HTTPProxies. +In effect, they are added onto the Conditions of included HTTPProxy Route +structs. +When applied, they are merged using AND, with one exception: +There can be only one Prefix MatchCondition per Conditions slice. +More than one Prefix, or contradictory Conditions, will make the +include invalid. Exact and Regex match conditions are not allowed +on includes.

+
+

JWTProvider +

+

+(Appears on: +VirtualHost) +

+

+

JWTProvider defines how to verify JWTs on requests.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Unique name for the provider.

+
+default +
+ +bool + +
+(Optional) +

Whether the provider should apply to all +routes in the HTTPProxy/its includes by +default. At most one provider can be marked +as the default. If no provider is marked +as the default, individual routes must explicitly +identify the provider they require.

+
+issuer +
+ +string + +
+(Optional) +

Issuer that JWTs are required to have in the “iss” field. +If not provided, JWT issuers are not checked.

+
+audiences +
+ +[]string + +
+(Optional) +

Audiences that JWTs are allowed to have in the “aud” field. +If not provided, JWT audiences are not checked.

+
+remoteJWKS +
+ + +RemoteJWKS + + +
+

Remote JWKS to use for verifying JWT signatures.

+
+forwardJWT +
+ +bool + +
+(Optional) +

Whether the JWT should be forwarded to the backend +service after successful verification. By default, +the JWT is not forwarded.

+
+

JWTVerificationPolicy +

+

+(Appears on: +Route) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+require +
+ +string + +
+(Optional) +

Require names a specific JWT provider (defined in the virtual host) +to require for the route. If specified, this field overrides the +default provider if one exists. If this field is not specified, +the default provider will be required if one exists. At most one of +this field or the “disabled” field can be specified.

+
+disabled +
+ +bool + +
+(Optional) +

Disabled defines whether to disable all JWT verification for this +route. This can be used to opt specific routes out of the default +JWT provider for the HTTPProxy. At most one of this field or the +“require” field can be specified.

+
+

LoadBalancerPolicy +

+

+(Appears on: +Route, +TCPProxy, +ExtensionServiceSpec) +

+

+

LoadBalancerPolicy defines the load balancing policy.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+strategy +
+ +string + +
+

Strategy specifies the policy used to balance requests +across the pool of backend pods. Valid policy names are +Random, RoundRobin, WeightedLeastRequest, Cookie, +and RequestHash. If an unknown strategy name is specified +or no policy is supplied, the default RoundRobin policy +is used.

+
+requestHashPolicies +
+ + +[]RequestHashPolicy + + +
+

RequestHashPolicies contains a list of hash policies to apply when the +RequestHash load balancing strategy is chosen. If an element of the +supplied list of hash policies is invalid, it will be ignored. If the +list of hash policies is empty after validation, the load balancing +strategy will fall back to the default RoundRobin.

+
+

LocalRateLimitPolicy +

+

+(Appears on: +RateLimitPolicy) +

+

+

LocalRateLimitPolicy defines local rate limiting parameters.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+requests +
+ +uint32 + +
+

Requests defines how many requests per unit of time should +be allowed before rate limiting occurs.

+
+unit +
+ +string + +
+

Unit defines the period of time within which requests +over the limit will be rate limited. Valid values are +“second”, “minute” and “hour”.

+
+burst +
+ +uint32 + +
+(Optional) +

Burst defines the number of requests above the requests per +unit that should be allowed within a short period of time.

+
+responseStatusCode +
+ +uint32 + +
+(Optional) +

ResponseStatusCode is the HTTP status code to use for responses +to rate-limited requests. Codes must be in the 400-599 range +(inclusive). If not specified, the Envoy default of 429 (Too +Many Requests) is used.

+
+responseHeadersToAdd +
+ + +[]HeaderValue + + +
+(Optional) +

ResponseHeadersToAdd is an optional list of response headers to +set when a request is rate-limited.

+
+

MatchCondition +

+

+(Appears on: +Include, +Route) +

+

+

MatchCondition are a general holder for matching rules for HTTPProxies. +One of Prefix, Exact, Regex, Header or QueryParameter must be provided.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+prefix +
+ +string + +
+(Optional) +

Prefix defines a prefix match for a request.

+
+exact +
+ +string + +
+(Optional) +

Exact defines a exact match for a request. +This field is not allowed in include match conditions.

+
+regex +
+ +string + +
+(Optional) +

Regex defines a regex match for a request. +This field is not allowed in include match conditions.

+
+header +
+ + +HeaderMatchCondition + + +
+(Optional) +

Header specifies the header condition to match.

+
+queryParameter +
+ + +QueryParameterMatchCondition + + +
+(Optional) +

QueryParameter specifies the query parameter condition to match.

+
+

Namespace +(string alias)

+

+(Appears on: +ContourSettings) +

+

+

Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.

+

This validation is based off of the corresponding Kubernetes validation: +https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187

+

This is used for Namespace name validation here: +https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63

+

Valid values include:

+
    +
  • “example”
  • +
+

Invalid values include:

+
    +
  • “example.com” - “.” is an invalid character
  • +
+

+

PathRewritePolicy +

+

+(Appears on: +Route) +

+

+

PathRewritePolicy specifies how a request URL path should be +rewritten. This rewriting takes place after a request is routed +and has no subsequent effects on the proxy’s routing decision. +No HTTP headers or body content is rewritten.

+

Exactly one field in this struct may be specified.

+

+ + + + + + + + + + + + + +
FieldDescription
+replacePrefix +
+ + +[]ReplacePrefix + + +
+(Optional) +

ReplacePrefix describes how the path prefix should be replaced.

+
+

QueryParameterHashOptions +

+

+(Appears on: +RequestHashPolicy) +

+

+

QueryParameterHashOptions contains options to configure a query parameter based hash +policy, used in request attribute hash based load balancing.

+

+ + + + + + + + + + + + + +
FieldDescription
+parameterName +
+ +string + +
+

ParameterName is the name of the HTTP request query parameter that will be used to +calculate the hash key. If the query parameter specified is not present on a +request, no hash will be produced.

+
+

QueryParameterMatchCondition +

+

+(Appears on: +MatchCondition) +

+

+

QueryParameterMatchCondition specifies how to conditionally match against HTTP +query parameters. The Name field is required, only one of Exact, Prefix, +Suffix, Regex, Contains and Present can be set. IgnoreCase has no effect +for Regex.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of the query parameter to match against. Name is required. +Query parameter names are case insensitive.

+
+exact +
+ +string + +
+(Optional) +

Exact specifies a string that the query parameter value must be equal to.

+
+prefix +
+ +string + +
+(Optional) +

Prefix defines a prefix match for the query parameter value.

+
+suffix +
+ +string + +
+(Optional) +

Suffix defines a suffix match for a query parameter value.

+
+regex +
+ +string + +
+(Optional) +

Regex specifies a regular expression pattern that must match the query +parameter value.

+
+contains +
+ +string + +
+(Optional) +

Contains specifies a substring that must be present in +the query parameter value.

+
+ignoreCase +
+ +bool + +
+(Optional) +

IgnoreCase specifies that string matching should be case insensitive. +Note that this has no effect on the Regex parameter.

+
+present +
+ +bool + +
+(Optional) +

Present specifies that condition is true when the named query parameter +is present, regardless of its value. Note that setting Present +to false does not make the condition true if the named query parameter +is absent.

+
+

RateLimitDescriptor +

+

+(Appears on: +GlobalRateLimitPolicy) +

+

+

RateLimitDescriptor defines a list of key-value pair generators.

+

+ + + + + + + + + + + + + +
FieldDescription
+entries +
+ + +[]RateLimitDescriptorEntry + + +
+

Entries is the list of key-value pair generators.

+
+

RateLimitDescriptorEntry +

+

+(Appears on: +RateLimitDescriptor) +

+

+

RateLimitDescriptorEntry is a key-value pair generator. Exactly +one field on this struct must be non-nil.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+genericKey +
+ + +GenericKeyDescriptor + + +
+(Optional) +

GenericKey defines a descriptor entry with a static key and value.

+
+requestHeader +
+ + +RequestHeaderDescriptor + + +
+(Optional) +

RequestHeader defines a descriptor entry that’s populated only if +a given header is present on the request. The descriptor key is static, +and the descriptor value is equal to the value of the header.

+
+requestHeaderValueMatch +
+ + +RequestHeaderValueMatchDescriptor + + +
+(Optional) +

RequestHeaderValueMatch defines a descriptor entry that’s populated +if the request’s headers match a set of 1+ match criteria. The +descriptor key is “header_match”, and the descriptor value is static.

+
+remoteAddress +
+ + +RemoteAddressDescriptor + + +
+(Optional) +

RemoteAddress defines a descriptor entry with a key of “remote_address” +and a value equal to the client’s IP address (from x-forwarded-for).

+
+

RateLimitPolicy +

+

+(Appears on: +Route, +VirtualHost) +

+

+

RateLimitPolicy defines rate limiting parameters.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+local +
+ + +LocalRateLimitPolicy + + +
+(Optional) +

Local defines local rate limiting parameters, i.e. parameters +for rate limiting that occurs within each Envoy pod as requests +are handled.

+
+global +
+ + +GlobalRateLimitPolicy + + +
+(Optional) +

Global defines global rate limiting parameters, i.e. parameters +defining descriptors that are sent to an external rate limit +service (RLS) for a rate limit decision on each request.

+
+

RedirectResponseCode +(uint32 alias)

+

+(Appears on: +HTTPInternalRedirectPolicy) +

+

+

RedirectResponseCode is a uint32 type alias with validation to ensure that the value is valid.

+

+

RemoteAddressDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

RemoteAddressDescriptor defines a descriptor entry with a key of +“remote_address” and a value equal to the client’s IP address +(from x-forwarded-for).

+

+

RemoteJWKS +

+

+(Appears on: +JWTProvider) +

+

+

RemoteJWKS defines how to fetch a JWKS from an HTTP endpoint.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+uri +
+ +string + +
+

The URI for the JWKS.

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the JWKS’s TLS certificate.

+
+timeout +
+ +string + +
+(Optional) +

How long to wait for a response from the URI. +If not specified, a default of 1s applies.

+
+cacheDuration +
+ +string + +
+(Optional) +

How long to cache the JWKS locally. If not specified, +Envoy’s default of 5m applies.

+
+dnsLookupFamily +
+ +string + +
+(Optional) +

The DNS IP address resolution policy for the JWKS URI. +When configured as “v4”, the DNS resolver will only perform a lookup +for addresses in the IPv4 family. If “v6” is configured, the DNS resolver +will only perform a lookup for addresses in the IPv6 family. +If “all” is configured, the DNS resolver +will perform a lookup for addresses in both the IPv4 and IPv6 family. +If “auto” is configured, the DNS resolver will first perform a lookup +for addresses in the IPv6 family and fallback to a lookup for addresses +in the IPv4 family. If not specified, the Contour-wide setting defined +in the config file or ContourConfiguration applies (defaults to “auto”).

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto.html#envoy-v3-api-enum-config-cluster-v3-cluster-dnslookupfamily +for more information.

+
+

ReplacePrefix +

+

+(Appears on: +PathRewritePolicy) +

+

+

ReplacePrefix describes a path prefix replacement.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+prefix +
+ +string + +
+(Optional) +

Prefix specifies the URL path prefix to be replaced.

+

If Prefix is specified, it must exactly match the MatchCondition +prefix that is rendered by the chain of including HTTPProxies +and only that path prefix will be replaced by Replacement. +This allows HTTPProxies that are included through multiple +roots to only replace specific path prefixes, leaving others +unmodified.

+

If Prefix is not specified, all routing prefixes rendered +by the include chain will be replaced.

+
+replacement +
+ +string + +
+

Replacement is the string that the routing path prefix +will be replaced with. This must not be empty.

+
+

RequestHashPolicy +

+

+(Appears on: +LoadBalancerPolicy) +

+

+

RequestHashPolicy contains configuration for an individual hash policy +on a request attribute.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+terminal +
+ +bool + +
+

Terminal is a flag that allows for short-circuiting computing of a hash +for a given request. If set to true, and the request attribute specified +in the attribute hash options is present, no further hash policies will +be used to calculate a hash for the request.

+
+headerHashOptions +
+ + +HeaderHashOptions + + +
+(Optional) +

HeaderHashOptions should be set when request header hash based load +balancing is desired. It must be the only hash option field set, +otherwise this request hash policy object will be ignored.

+
+queryParameterHashOptions +
+ + +QueryParameterHashOptions + + +
+(Optional) +

QueryParameterHashOptions should be set when request query parameter hash based load +balancing is desired. It must be the only hash option field set, +otherwise this request hash policy object will be ignored.

+
+hashSourceIP +
+ +bool + +
+(Optional) +

HashSourceIP should be set to true when request source IP hash based +load balancing is desired. It must be the only hash option field set, +otherwise this request hash policy object will be ignored.

+
+

RequestHeaderDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

RequestHeaderDescriptor defines a descriptor entry that’s populated only +if a given header is present on the request. The value of the descriptor +entry is equal to the value of the header (if present).

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+headerName +
+ +string + +
+

HeaderName defines the name of the header to look for on the request.

+
+descriptorKey +
+ +string + +
+

DescriptorKey defines the key to use on the descriptor entry.

+
+

RequestHeaderValueMatchDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

RequestHeaderValueMatchDescriptor defines a descriptor entry that’s populated +if the request’s headers match a set of 1+ match criteria. The descriptor key +is “header_match”, and the descriptor value is statically defined.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+headers +
+ + +[]HeaderMatchCondition + + +
+

Headers is a list of 1+ match criteria to apply against the request +to determine whether to populate the descriptor entry or not.

+
+expectMatch +
+ +bool + +
+

ExpectMatch defines whether the request must positively match the match +criteria in order to generate a descriptor entry (i.e. true), or not +match the match criteria in order to generate a descriptor entry (i.e. false). +The default is true.

+
+value +
+ +string + +
+

Value defines the value of the descriptor entry.

+
+

RetryOn +(string alias)

+

+(Appears on: +RetryPolicy) +

+

+

RetryOn is a string type alias with validation to ensure that the value is valid.

+

+

RetryPolicy +

+

+(Appears on: +Route) +

+

+

RetryPolicy defines the attributes associated with retrying policy.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+count +
+ +int64 + +
+(Optional) +

NumRetries is maximum allowed number of retries. +If set to -1, then retries are disabled. +If set to 0 or not supplied, the value is set +to the Envoy default of 1.

+
+perTryTimeout +
+ +string + +
+(Optional) +

PerTryTimeout specifies the timeout per retry attempt. +Ignored if NumRetries is not supplied.

+
+retryOn +
+ + +[]RetryOn + + +
+(Optional) +

RetryOn specifies the conditions on which to retry a request.

+

Supported HTTP conditions:

+
    +
  • 5xx
  • +
  • gateway-error
  • +
  • reset
  • +
  • connect-failure
  • +
  • retriable-4xx
  • +
  • refused-stream
  • +
  • retriable-status-codes
  • +
  • retriable-headers
  • +
+

Supported gRPC conditions:

+
    +
  • cancelled
  • +
  • deadline-exceeded
  • +
  • internal
  • +
  • resource-exhausted
  • +
  • unavailable
  • +
+
+retriableStatusCodes +
+ +[]uint32 + +
+(Optional) +

RetriableStatusCodes specifies the HTTP status codes that should be retried.

+

This field is only respected when you include retriable-status-codes in the RetryOn field.

+
+

Route +

+

+(Appears on: +HTTPProxySpec) +

+

+

Route contains the set of routes for a virtual host.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]MatchCondition + + +
+(Optional) +

Conditions are a set of rules that are applied to a Route. +When applied, they are merged using AND, with one exception: +There can be only one Prefix, Exact or Regex MatchCondition +per Conditions slice. More than one of these condition types, +or contradictory Conditions, will make the route invalid.

+
+services +
+ + +[]Service + + +
+(Optional) +

Services are the services to proxy traffic.

+
+enableWebsockets +
+ +bool + +
+(Optional) +

Enables websocket support for the route.

+
+permitInsecure +
+ +bool + +
+(Optional) +

Allow this path to respond to insecure requests over HTTP which are normally +not permitted when a virtualhost.tls block is present.

+
+authPolicy +
+ + +AuthorizationPolicy + + +
+(Optional) +

AuthPolicy updates the authorization policy that was set +on the root HTTPProxy object for client requests that +match this route.

+
+timeoutPolicy +
+ + +TimeoutPolicy + + +
+(Optional) +

The timeout policy for this route.

+
+retryPolicy +
+ + +RetryPolicy + + +
+(Optional) +

The retry policy for this route.

+
+healthCheckPolicy +
+ + +HTTPHealthCheckPolicy + + +
+(Optional) +

The health check policy for this route.

+
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The load balancing policy for this route.

+
+pathRewritePolicy +
+ + +PathRewritePolicy + + +
+(Optional) +

The policy for rewriting the path of the request URL +after the request has been routed to a Service.

+
+requestHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing request headers during proxying.

+

You may dynamically rewrite the Host header to be forwarded +upstream to the content of a request header using +the below format “%REQ(X-Header-Name)%”. If the value of the header +is empty, it is ignored.

+

*NOTE: Pay attention to the potential security implications of using this option. +Provided header must come from trusted source.

+

**NOTE: The header rewrite is only done while forwarding and has no bearing +on the routing decision.

+
+responseHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing response headers during proxying. +Rewriting the ‘Host’ header is not supported.

+
+cookieRewritePolicies +
+ + +[]CookieRewritePolicy + + +
+(Optional) +

The policies for rewriting Set-Cookie header attributes. Note that +rewritten cookie names must be unique in this list. Order rewrite +policies are specified in does not matter.

+
+rateLimitPolicy +
+ + +RateLimitPolicy + + +
+(Optional) +

The policy for rate limiting on the route.

+
+requestRedirectPolicy +
+ + +HTTPRequestRedirectPolicy + + +
+(Optional) +

RequestRedirectPolicy defines an HTTP redirection.

+
+directResponsePolicy +
+ + +HTTPDirectResponsePolicy + + +
+(Optional) +

DirectResponsePolicy returns an arbitrary HTTP response directly.

+
+internalRedirectPolicy +
+ + +HTTPInternalRedirectPolicy + + +
+(Optional) +

The policy to define when to handle redirects responses internally.

+
+jwtVerificationPolicy +
+ + +JWTVerificationPolicy + + +
+(Optional) +

The policy for verifying JWTs for requests to this route.

+
+ipAllowPolicy +
+ + +[]IPFilterPolicy + + +
+

IPAllowFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be allowed. All other requests will be denied. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here override any rules set on the root HTTPProxy.

+
+ipDenyPolicy +
+ + +[]IPFilterPolicy + + +
+

IPDenyFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be denied. All other requests will be allowed. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here override any rules set on the root HTTPProxy.

+
+

Service +

+

+(Appears on: +Route, +TCPProxy) +

+

+

Service defines an Kubernetes Service to proxy traffic.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of Kubernetes service to proxy traffic. +Names defined here will be used to look up corresponding endpoints which contain the ips to route.

+
+port +
+ +int + +
+

Port (defined as Integer) to proxy traffic to since a service can have multiple defined.

+
+healthPort +
+ +int + +
+(Optional) +

HealthPort is the port for this service healthcheck. +If not specified, Port is used for service healthchecks.

+
+protocol +
+ +string + +
+(Optional) +

Protocol may be used to specify (or override) the protocol used to reach this Service. +Values may be tls, h2, h2c. If omitted, protocol-selection falls back on Service annotations.

+
+weight +
+ +int64 + +
+(Optional) +

Weight defines percentage of traffic to balance traffic

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the backend service’s certificate

+
+mirror +
+ +bool + +
+

If Mirror is true the Service will receive a read only mirror of the traffic for this route. +If Mirror is true, then fractional mirroring can be enabled by optionally setting the Weight +field. Legal values for Weight are 1-100. Omitting the Weight field will result in 100% mirroring. +NOTE: Setting Weight explicitly to 0 will unexpectedly result in 100% traffic mirroring. This +occurs since we cannot distinguish omitted fields from those explicitly set to their default +values

+
+requestHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing request headers during proxying.

+
+responseHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing response headers during proxying. +Rewriting the ‘Host’ header is not supported.

+
+cookieRewritePolicies +
+ + +[]CookieRewritePolicy + + +
+(Optional) +

The policies for rewriting Set-Cookie header attributes.

+
+slowStartPolicy +
+ + +SlowStartPolicy + + +
+(Optional) +

Slow start will gradually increase amount of traffic to a newly added endpoint.

+
+

SlowStartPolicy +

+

+(Appears on: +Service) +

+

+

SlowStartPolicy will gradually increase amount of traffic to a newly added endpoint. +It can be used only with RoundRobin and WeightedLeastRequest load balancing strategies.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+window +
+ +string + +
+

The duration of slow start window. +Duration is expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”.

+
+aggression +
+ +string + +
+(Optional) +

The speed of traffic increase over the slow start window. +Defaults to 1.0, so that endpoint would get linearly increasing amount of traffic. +When increasing the value for this parameter, the speed of traffic ramp-up increases non-linearly. +The value of aggression parameter should be greater than 0.0.

+

More info: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/slow_start

+
+minWeightPercent +
+ +uint32 + +
+(Optional) +

The minimum or starting percentage of traffic to send to new endpoints. +A non-zero value helps avoid a too small initial weight, which may cause endpoints in slow start mode to receive no traffic in the beginning of the slow start window. +If not specified, the default is 10%.

+
+

SubCondition +

+

+(Appears on: +DetailedCondition) +

+

+

SubCondition is a Condition-like type intended for use as a subcondition inside a DetailedCondition.

+

It contains a subset of the Condition fields.

+

It is intended for warnings and errors, so type names should use abnormal-true polarity, +that is, they should be of the form “ErrorPresent: true”.

+

The expected lifecycle for these errors is that they should only be present when the error or warning is, +and should be removed when they are not relevant.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+type +
+ +string + +
+

Type of condition in CamelCase or in foo.example.com/CamelCase.

+

This must be in abnormal-true polarity, that is, ErrorFound or controller.io/ErrorFound.

+

The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)

+
+status +
+ + +Kubernetes meta/v1.ConditionStatus + + +
+

Status of the condition, one of True, False, Unknown.

+
+reason +
+ +string + +
+

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.

+
+message +
+ +string + +
+

Message is a human readable message indicating details about the transition.

+

This may be an empty string.

+
+

TCPHealthCheckPolicy +

+

+(Appears on: +TCPProxy) +

+

+

TCPHealthCheckPolicy defines health checks on the upstream service.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+intervalSeconds +
+ +int64 + +
+(Optional) +

The interval (seconds) between health checks

+
+timeoutSeconds +
+ +int64 + +
+(Optional) +

The time to wait (seconds) for a health check response

+
+unhealthyThresholdCount +
+ +uint32 + +
+(Optional) +

The number of unhealthy health checks required before a host is marked unhealthy

+
+healthyThresholdCount +
+ +uint32 + +
+(Optional) +

The number of healthy health checks required before a host is marked healthy

+
+

TCPProxy +

+

+(Appears on: +HTTPProxySpec) +

+

+

TCPProxy contains the set of services to proxy TCP connections.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The load balancing policy for the backend services. Note that the +Cookie and RequestHash load balancing strategies cannot be used +here.

+
+services +
+ + +[]Service + + +
+(Optional) +

Services are the services to proxy traffic

+
+include +
+ + +TCPProxyInclude + + +
+(Optional) +

Include specifies that this tcpproxy should be delegated to another HTTPProxy.

+
+includes +
+ + +TCPProxyInclude + + +
+(Optional) +

IncludesDeprecated allow for specific routing configuration to be appended to another HTTPProxy in another namespace.

+

Exists due to a mistake when developing HTTPProxy and the field was marked plural +when it should have been singular. This field should stay to not break backwards compatibility to v1 users.

+
+healthCheckPolicy +
+ + +TCPHealthCheckPolicy + + +
+(Optional) +

The health check policy for this tcp proxy

+
+

TCPProxyInclude +

+

+(Appears on: +TCPProxy) +

+

+

TCPProxyInclude describes a target HTTPProxy document which contains the TCPProxy details.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name of the child HTTPProxy

+
+namespace +
+ +string + +
+(Optional) +

Namespace of the HTTPProxy to include. Defaults to the current namespace if not supplied.

+
+

TLS +

+

+(Appears on: +VirtualHost) +

+

+

TLS describes tls properties. The SNI names that will be matched on +are described in the HTTPProxy’s Spec.VirtualHost.Fqdn field.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+secretName +
+ +string + +
+

SecretName is the name of a TLS secret. +Either SecretName or Passthrough must be specified, but not both. +If specified, the named secret must contain a matching certificate +for the virtual host’s FQDN. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret.

+
+minimumProtocolVersion +
+ +string + +
+(Optional) +

MinimumProtocolVersion is the minimum TLS version this vhost should +negotiate. Valid options are 1.2 (default) and 1.3. Any other value +defaults to TLS 1.2.

+
+maximumProtocolVersion +
+ +string + +
+(Optional) +

MaximumProtocolVersion is the maximum TLS version this vhost should +negotiate. Valid options are 1.2 and 1.3 (default). Any other value +defaults to TLS 1.3.

+
+passthrough +
+ +bool + +
+(Optional) +

Passthrough defines whether the encrypted TLS handshake will be +passed through to the backing cluster. Either Passthrough or +SecretName must be specified, but not both.

+
+clientValidation +
+ + +DownstreamValidation + + +
+(Optional) +

ClientValidation defines how to verify the client certificate +when an external client establishes a TLS connection to Envoy.

+

This setting:

+
    +
  1. Enables TLS client certificate validation.
  2. +
  3. Specifies how the client certificate will be validated (i.e. +validation required or skipped).
  4. +
+

Note: Setting client certificate validation to be skipped should +be only used in conjunction with an external authorization server that +performs client validation as Contour will ensure client certificates +are passed along.

+
+enableFallbackCertificate +
+ +bool + +
+

EnableFallbackCertificate defines if the vhost should allow a default certificate to +be applied which handles all requests which don’t match the SNI defined in this vhost.

+
+

TLSCertificateDelegationSpec +

+

+(Appears on: +TLSCertificateDelegation) +

+

+

TLSCertificateDelegationSpec defines the spec of the CRD

+

+ + + + + + + + + + + + + +
FieldDescription
+delegations +
+ + +[]CertificateDelegation + + +
+
+

TLSCertificateDelegationStatus +

+

+(Appears on: +TLSCertificateDelegation) +

+

+

TLSCertificateDelegationStatus allows for the status of the delegation +to be presented to the user.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains information about the current status of the HTTPProxy, +in an upstream-friendly container.

+

Contour will update a single condition, Valid, that is in normal-true polarity. +That is, when currentStatus is valid, the Valid condition will be status: true, +and vice versa.

+

Contour will leave untouched any other Conditions set in this block, +in case some other controller wants to add a Condition.

+

If you are another controller owner and wish to add a condition, you should +namespace your condition with a label, like controller.domain.com\ConditionName.

+
+

TimeoutPolicy +

+

+(Appears on: +Route, +ExtensionServiceSpec) +

+

+

TimeoutPolicy configures timeouts that are used for handling network requests.

+

TimeoutPolicy durations are expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. +The string “infinity” is also a valid input and specifies no timeout. +A value of “0s” will be treated as if the field were not set, i.e. by using Envoy’s default behavior.

+

Example input values: “300ms”, “5s”, “1m”.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+response +
+ +string + +
+(Optional) +

Timeout for receiving a response from the server after processing a request from client. +If not supplied, Envoy’s default value of 15s applies.

+
+idle +
+ +string + +
+(Optional) +

Timeout for how long the proxy should wait while there is no activity during single request/response (for HTTP/1.1) or stream (for HTTP/2). +Timeout will not trigger while HTTP/1.1 connection is idle between two consecutive requests. +If not specified, there is no per-route idle timeout, though a connection manager-wide +stream_idle_timeout default of 5m still applies.

+
+idleConnection +
+ +string + +
+(Optional) +

Timeout for how long connection from the proxy to the upstream service is kept when there are no active requests. +If not supplied, Envoy’s default value of 1h applies.

+
+

UpstreamValidation +

+

+(Appears on: +RemoteJWKS, +Service, +ExtensionServiceSpec) +

+

+

UpstreamValidation defines how to verify the backend service’s certificate

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caSecret +
+ +string + +
+

Name or namespaced name of the Kubernetes secret used to validate the certificate presented by the backend. +The secret must contain key named ca.crt. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. +Max length should be the actual max possible length of a namespaced name (63 + 253 + 1 = 317)

+
+subjectName +
+ +string + +
+

Key which is expected to be present in the ‘subjectAltName’ of the presented certificate. +Deprecated: migrate to using the plural field subjectNames.

+
+subjectNames +
+ +[]string + +
+(Optional) +

List of keys, of which at least one is expected to be present in the ‘subjectAltName of the +presented certificate.

+
+

VirtualHost +

+

+(Appears on: +HTTPProxySpec) +

+

+

VirtualHost appears at most once. If it is present, the object is considered +to be a “root”.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+fqdn +
+ +string + +
+

The fully qualified domain name of the root of the ingress tree +all leaves of the DAG rooted at this object relate to the fqdn.

+
+tls +
+ + +TLS + + +
+(Optional) +

If present the fields describes TLS properties of the virtual +host. The SNI names that will be matched on are described in fqdn, +the tls.secretName secret must contain a certificate that itself +contains a name that matches the FQDN.

+
+authorization +
+ + +AuthorizationServer + + +
+(Optional) +

This field configures an extension service to perform +authorization for this virtual host. Authorization can +only be configured on virtual hosts that have TLS enabled. +If the TLS configuration requires client certificate +validation, the client certificate is always included in the +authentication check request.

+
+corsPolicy +
+ + +CORSPolicy + + +
+(Optional) +

Specifies the cross-origin policy to apply to the VirtualHost.

+
+rateLimitPolicy +
+ + +RateLimitPolicy + + +
+(Optional) +

The policy for rate limiting on the virtual host.

+
+jwtProviders +
+ + +[]JWTProvider + + +
+(Optional) +

Providers to use for verifying JSON Web Tokens (JWTs) on the virtual host.

+
+ipAllowPolicy +
+ + +[]IPFilterPolicy + + +
+

IPAllowFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be allowed. All other requests will be denied. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here may be overridden in a Route.

+
+ipDenyPolicy +
+ + +[]IPFilterPolicy + + +
+

IPDenyFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be denied. All other requests will be allowed. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here may be overridden in a Route.

+
+
+

projectcontour.io/v1alpha1

+

+

Package v1alpha1 contains API Schema definitions for the projectcontour.io v1alpha1 API group

+

+Resource Types: + +

ContourConfiguration +

+

+

ContourConfiguration is the schema for a Contour instance.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1alpha1 + +
+kind
+string +
ContourConfiguration
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +ContourConfigurationSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+xdsServer +
+ + +XDSServerConfig + + +
+(Optional) +

XDSServer contains parameters for the xDS server.

+
+ingress +
+ + +IngressConfig + + +
+(Optional) +

Ingress contains parameters for ingress options.

+
+debug +
+ + +DebugConfig + + +
+(Optional) +

Debug contains parameters to enable debug logging +and debug interfaces inside Contour.

+
+health +
+ + +HealthConfig + + +
+(Optional) +

Health defines the endpoints Contour uses to serve health checks.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+envoy +
+ + +EnvoyConfig + + +
+(Optional) +

Envoy contains parameters for Envoy as well +as how to optionally configure a managed Envoy fleet.

+
+gateway +
+ + +GatewayConfig + + +
+(Optional) +

Gateway contains parameters for the gateway-api Gateway that Contour +is configured to serve traffic.

+
+httpproxy +
+ + +HTTPProxyConfig + + +
+(Optional) +

HTTPProxy defines parameters on HTTPProxy.

+
+enableExternalNameService +
+ +bool + +
+(Optional) +

EnableExternalNameService allows processing of ExternalNameServices

+

Contour’s default is false for security reasons.

+
+globalExtAuth +
+ + +AuthorizationServer + + +
+(Optional) +

GlobalExternalAuthorization allows envoys external authorization filter +to be enabled for all virtual hosts.

+
+rateLimitService +
+ + +RateLimitServiceConfig + + +
+(Optional) +

RateLimitService optionally holds properties of the Rate Limit Service +to be used for global rate limiting.

+
+policy +
+ + +PolicyConfig + + +
+(Optional) +

Policy specifies default policy applied if not overridden by the user

+
+metrics +
+ + +MetricsConfig + + +
+(Optional) +

Metrics defines the endpoint Contour uses to serve metrics.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+tracing +
+ + +TracingConfig + + +
+

Tracing defines properties for exporting trace data to OpenTelemetry.

+
+featureFlags +
+ + +FeatureFlags + + +
+

FeatureFlags defines toggle to enable new contour features. +Available toggles are: +useEndpointSlices - Configures contour to fetch endpoint data +from k8s endpoint slices. defaults to true, +If false then reads endpoint data from the k8s endpoints.

+
+
+status +
+ + +ContourConfigurationStatus + + +
+(Optional) +
+

ContourDeployment +

+

+

ContourDeployment is the schema for a Contour Deployment.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1alpha1 + +
+kind
+string +
ContourDeployment
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +ContourDeploymentSpec + + +
+
+
+ + + + + + + + + + + + + + + + + +
+contour +
+ + +ContourSettings + + +
+(Optional) +

Contour specifies deployment-time settings for the Contour +part of the installation, i.e. the xDS server/control plane +and associated resources, including things like replica count +for the Deployment, and node placement constraints for the pods.

+
+envoy +
+ + +EnvoySettings + + +
+(Optional) +

Envoy specifies deployment-time settings for the Envoy +part of the installation, i.e. the xDS client/data plane +and associated resources, including things like the workload +type to use (DaemonSet or Deployment), node placement constraints +for the pods, and various options for the Envoy service.

+
+runtimeSettings +
+ + +ContourConfigurationSpec + + +
+(Optional) +

RuntimeSettings is a ContourConfiguration spec to be used when +provisioning a Contour instance that will influence aspects of +the Contour instance’s runtime behavior.

+
+resourceLabels +
+ +map[string]string + +
+(Optional) +

ResourceLabels is a set of labels to add to the provisioned Contour resources.

+

Deprecated: use Gateway.Spec.Infrastructure.Labels instead. This field will be +removed in a future release.

+
+
+status +
+ + +ContourDeploymentStatus + + +
+
+

ExtensionService +

+

+

ExtensionService is the schema for the Contour extension services API. +An ExtensionService resource binds a network service to the Contour +API so that Contour API features can be implemented by collaborating +components.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1alpha1 + +
+kind
+string +
ExtensionService
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +ExtensionServiceSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+services +
+ + +[]ExtensionServiceTarget + + +
+

Services specifies the set of Kubernetes Service resources that +receive GRPC extension API requests. +If no weights are specified for any of the entries in +this array, traffic will be spread evenly across all the +services. +Otherwise, traffic is balanced proportionally to the +Weight field in each entry.

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the backend service’s certificate

+
+protocol +
+ +string + +
+(Optional) +

Protocol may be used to specify (or override) the protocol used to reach this Service. +Values may be h2 or h2c. If omitted, protocol-selection falls back on Service annotations.

+
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The policy for load balancing GRPC service requests. Note that the +Cookie and RequestHash load balancing strategies cannot be used +here.

+
+timeoutPolicy +
+ + +TimeoutPolicy + + +
+(Optional) +

The timeout policy for requests to the services.

+
+protocolVersion +
+ + +ExtensionProtocolVersion + + +
+(Optional) +

This field sets the version of the GRPC protocol that Envoy uses to +send requests to the extension service. Since Contour always uses the +v3 Envoy API, this is currently fixed at “v3”. However, other +protocol options will be available in future.

+
+
+status +
+ + +ExtensionServiceStatus + + +
+
+

AccessLogFormatString +(string alias)

+

+

+

AccessLogJSONFields +([]string alias)

+

+(Appears on: +EnvoyLogging) +

+

+

+

AccessLogLevel +(string alias)

+

+(Appears on: +EnvoyLogging) +

+

+

+ + + + + + + + + + + + + + + + +
ValueDescription

"critical"

Log only requests that result in an server error (i.e. 500+) response code.

+

"disabled"

Disable the access log.

+

"error"

Log only requests that result in a non-success (i.e. 300+) response code

+

"info"

Log all requests. This is the default.

+
+

AccessLogType +(string alias)

+

+(Appears on: +EnvoyLogging) +

+

+

AccessLogType is the name of a supported access logging mechanism.

+

+ + + + + + + + + + + + + + +
ValueDescription

"envoy"

DefaultAccessLogType is the default access log format.

+

"envoy"

Set the Envoy access logging to Envoy’s standard format. +Can be customized using accessLogFormatString.

+

"json"

Set the Envoy access logging to a JSON format. +Can be customized using jsonFields.

+
+

ClusterDNSFamilyType +(string alias)

+

+(Appears on: +ClusterParameters) +

+

+

ClusterDNSFamilyType is the Ip family to use for resolving DNS +names in an Envoy cluster config.

+

+ + + + + + + + + + + + + + + + +
ValueDescription

"all"

DNS lookups will attempt both v4 and v6 queries.

+

"auto"

DNS lookups will do a v6 lookup first, followed by a v4 if that fails.

+

"v4"

DNS lookups will only attempt v4 queries.

+

"v6"

DNS lookups will only attempt v6 queries.

+
+

ClusterParameters +

+

+(Appears on: +EnvoyConfig) +

+

+

ClusterParameters holds various configurable cluster values.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+dnsLookupFamily +
+ + +ClusterDNSFamilyType + + +
+(Optional) +

DNSLookupFamily defines how external names are looked up +When configured as V4, the DNS resolver will only perform a lookup +for addresses in the IPv4 family. If V6 is configured, the DNS resolver +will only perform a lookup for addresses in the IPv6 family. +If AUTO is configured, the DNS resolver will first perform a lookup +for addresses in the IPv6 family and fallback to a lookup for addresses +in the IPv4 family. If ALL is specified, the DNS resolver will perform a lookup for +both IPv4 and IPv6 families, and return all resolved addresses. +When this is used, Happy Eyeballs will be enabled for upstream connections. +Refer to Happy Eyeballs Support for more information. +Note: This only applies to externalName clusters.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto.html#envoy-v3-api-enum-config-cluster-v3-cluster-dnslookupfamily +for more information.

+

Values: auto (default), v4, v6, all.

+

Other values will produce an error.

+
+maxRequestsPerConnection +
+ +uint32 + +
+(Optional) +

Defines the maximum requests for upstream connections. If not specified, there is no limit. +see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-msg-config-core-v3-httpprotocoloptions +for more information.

+
+per-connection-buffer-limit-bytes +
+ +uint32 + +
+(Optional) +

Defines the soft limit on size of the cluster’s new connection read and write buffers in bytes. +If unspecified, an implementation defined default is applied (1MiB). +see 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 +for more information.

+
+circuitBreakers +
+ + +GlobalCircuitBreakerDefaults + + +
+(Optional) +

GlobalCircuitBreakerDefaults specifies default circuit breaker budget across all services. +If defined, this will be used as the default for all services.

+
+upstreamTLS +
+ + +EnvoyTLS + + +
+(Optional) +

UpstreamTLS contains the TLS policy parameters for upstream connections

+
+

ContourConfigurationSpec +

+

+(Appears on: +ContourConfiguration, +ContourDeploymentSpec) +

+

+

ContourConfigurationSpec represents a configuration of a Contour controller. +It contains most of all the options that can be customized, the +other remaining options being command line flags.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+xdsServer +
+ + +XDSServerConfig + + +
+(Optional) +

XDSServer contains parameters for the xDS server.

+
+ingress +
+ + +IngressConfig + + +
+(Optional) +

Ingress contains parameters for ingress options.

+
+debug +
+ + +DebugConfig + + +
+(Optional) +

Debug contains parameters to enable debug logging +and debug interfaces inside Contour.

+
+health +
+ + +HealthConfig + + +
+(Optional) +

Health defines the endpoints Contour uses to serve health checks.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+envoy +
+ + +EnvoyConfig + + +
+(Optional) +

Envoy contains parameters for Envoy as well +as how to optionally configure a managed Envoy fleet.

+
+gateway +
+ + +GatewayConfig + + +
+(Optional) +

Gateway contains parameters for the gateway-api Gateway that Contour +is configured to serve traffic.

+
+httpproxy +
+ + +HTTPProxyConfig + + +
+(Optional) +

HTTPProxy defines parameters on HTTPProxy.

+
+enableExternalNameService +
+ +bool + +
+(Optional) +

EnableExternalNameService allows processing of ExternalNameServices

+

Contour’s default is false for security reasons.

+
+globalExtAuth +
+ + +AuthorizationServer + + +
+(Optional) +

GlobalExternalAuthorization allows envoys external authorization filter +to be enabled for all virtual hosts.

+
+rateLimitService +
+ + +RateLimitServiceConfig + + +
+(Optional) +

RateLimitService optionally holds properties of the Rate Limit Service +to be used for global rate limiting.

+
+policy +
+ + +PolicyConfig + + +
+(Optional) +

Policy specifies default policy applied if not overridden by the user

+
+metrics +
+ + +MetricsConfig + + +
+(Optional) +

Metrics defines the endpoint Contour uses to serve metrics.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+tracing +
+ + +TracingConfig + + +
+

Tracing defines properties for exporting trace data to OpenTelemetry.

+
+featureFlags +
+ + +FeatureFlags + + +
+

FeatureFlags defines toggle to enable new contour features. +Available toggles are: +useEndpointSlices - Configures contour to fetch endpoint data +from k8s endpoint slices. defaults to true, +If false then reads endpoint data from the k8s endpoints.

+
+

ContourConfigurationStatus +

+

+(Appears on: +ContourConfiguration) +

+

+

ContourConfigurationStatus defines the observed state of a ContourConfiguration resource.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains the current status of the Contour resource.

+

Contour will update a single condition, Valid, that is in normal-true polarity.

+

Contour will not modify any other Conditions set in this block, +in case some other controller wants to add a Condition.

+
+

ContourDeploymentSpec +

+

+(Appears on: +ContourDeployment) +

+

+

ContourDeploymentSpec specifies options for how a Contour +instance should be provisioned.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+contour +
+ + +ContourSettings + + +
+(Optional) +

Contour specifies deployment-time settings for the Contour +part of the installation, i.e. the xDS server/control plane +and associated resources, including things like replica count +for the Deployment, and node placement constraints for the pods.

+
+envoy +
+ + +EnvoySettings + + +
+(Optional) +

Envoy specifies deployment-time settings for the Envoy +part of the installation, i.e. the xDS client/data plane +and associated resources, including things like the workload +type to use (DaemonSet or Deployment), node placement constraints +for the pods, and various options for the Envoy service.

+
+runtimeSettings +
+ + +ContourConfigurationSpec + + +
+(Optional) +

RuntimeSettings is a ContourConfiguration spec to be used when +provisioning a Contour instance that will influence aspects of +the Contour instance’s runtime behavior.

+
+resourceLabels +
+ +map[string]string + +
+(Optional) +

ResourceLabels is a set of labels to add to the provisioned Contour resources.

+

Deprecated: use Gateway.Spec.Infrastructure.Labels instead. This field will be +removed in a future release.

+
+

ContourDeploymentStatus +

+

+(Appears on: +ContourDeployment) +

+

+

ContourDeploymentStatus defines the observed state of a ContourDeployment resource.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]Kubernetes meta/v1.Condition + + +
+(Optional) +

Conditions describe the current conditions of the ContourDeployment resource.

+
+

ContourSettings +

+

+(Appears on: +ContourDeploymentSpec) +

+

+

ContourSettings contains settings for the Contour part of the installation, +i.e. the xDS server/control plane and associated resources.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+replicas +
+ +int32 + +
+(Optional) +

Deprecated: Use DeploymentSettings.Replicas instead.

+

Replicas is the desired number of Contour replicas. If if unset, +defaults to 2.

+

if both DeploymentSettings.Replicas and this one is set, use DeploymentSettings.Replicas.

+
+nodePlacement +
+ + +NodePlacement + + +
+(Optional) +

NodePlacement describes node scheduling configuration of Contour pods.

+
+kubernetesLogLevel +
+ +byte + +
+(Optional) +

KubernetesLogLevel Enable Kubernetes client debug logging with log level. If unset, +defaults to 0.

+
+logLevel +
+ + +LogLevel + + +
+(Optional) +

LogLevel sets the log level for Contour +Allowed values are “info”, “debug”.

+
+resources +
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Compute Resources required by contour container. +Cannot be updated. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

+
+deployment +
+ + +DeploymentSettings + + +
+(Optional) +

Deployment describes the settings for running contour as a Deployment.

+
+podAnnotations +
+ +map[string]string + +
+(Optional) +

PodAnnotations defines annotations to add to the Contour pods. +the annotations for Prometheus will be appended or overwritten with predefined value.

+
+watchNamespaces +
+ + +[]Namespace + + +
+(Optional) +

WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance +to only watch this subset of namespaces.

+
+disabledFeatures +
+ + +[]Feature + + +
+(Optional) +

DisabledFeatures defines an array of resources that will be ignored by +contour reconciler.

+
+

CustomTag +

+

+

CustomTag defines custom tags with unique tag name +to create tags for the active span.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+tagName +
+ +string + +
+

TagName is the unique name of the custom tag.

+
+literal +
+ +string + +
+(Optional) +

Literal is a static custom tag value. +Precisely one of Literal, RequestHeaderName must be set.

+
+requestHeaderName +
+ +string + +
+(Optional) +

RequestHeaderName indicates which request header +the label value is obtained from. +Precisely one of Literal, RequestHeaderName must be set.

+
+

DaemonSetSettings +

+

+(Appears on: +EnvoySettings) +

+

+

DaemonSetSettings contains settings for DaemonSet resources.

+

+ + + + + + + + + + + + + +
FieldDescription
+updateStrategy +
+ + +Kubernetes apps/v1.DaemonSetUpdateStrategy + + +
+(Optional) +

Strategy describes the deployment strategy to use to replace existing DaemonSet pods with new pods.

+
+

DebugConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

DebugConfig contains Contour specific troubleshooting options.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines the Contour debug address interface.

+

Contour’s default is “127.0.0.1”.

+
+port +
+ +int + +
+(Optional) +

Defines the Contour debug address port.

+

Contour’s default is 6060.

+
+

DeploymentSettings +

+

+(Appears on: +ContourSettings, +EnvoySettings) +

+

+

DeploymentSettings contains settings for Deployment resources.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+replicas +
+ +int32 + +
+

Replicas is the desired number of replicas.

+
+strategy +
+ + +Kubernetes apps/v1.DeploymentStrategy + + +
+(Optional) +

Strategy describes the deployment strategy to use to replace existing pods with new pods.

+
+

EnvoyConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

EnvoyConfig defines how Envoy is to be Configured from Contour.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+listener +
+ + +EnvoyListenerConfig + + +
+(Optional) +

Listener hold various configurable Envoy listener values.

+
+service +
+ + +NamespacedName + + +
+(Optional) +

Service holds Envoy service parameters for setting Ingress status.

+

Contour’s default is { namespace: “projectcontour”, name: “envoy” }.

+
+http +
+ + +EnvoyListener + + +
+(Optional) +

Defines the HTTP Listener for Envoy.

+

Contour’s default is { address: “0.0.0.0”, port: 8080, accessLog: “/dev/stdout” }.

+
+https +
+ + +EnvoyListener + + +
+(Optional) +

Defines the HTTPS Listener for Envoy.

+

Contour’s default is { address: “0.0.0.0”, port: 8443, accessLog: “/dev/stdout” }.

+
+health +
+ + +HealthConfig + + +
+(Optional) +

Health defines the endpoint Envoy uses to serve health checks.

+

Contour’s default is { address: “0.0.0.0”, port: 8002 }.

+
+metrics +
+ + +MetricsConfig + + +
+(Optional) +

Metrics defines the endpoint Envoy uses to serve metrics.

+

Contour’s default is { address: “0.0.0.0”, port: 8002 }.

+
+clientCertificate +
+ + +NamespacedName + + +
+(Optional) +

ClientCertificate defines the namespace/name of the Kubernetes +secret containing the client certificate and private key +to be used when establishing TLS connection to upstream +cluster.

+
+logging +
+ + +EnvoyLogging + + +
+(Optional) +

Logging defines how Envoy’s logs can be configured.

+
+defaultHTTPVersions +
+ + +[]HTTPVersionType + + +
+(Optional) +

DefaultHTTPVersions defines the default set of HTTPS +versions the proxy should accept. HTTP versions are +strings of the form “HTTP/xx”. Supported versions are +“HTTP/1.1” and “HTTP/2”.

+

Values: HTTP/1.1, HTTP/2 (default: both).

+

Other values will produce an error.

+
+timeouts +
+ + +TimeoutParameters + + +
+(Optional) +

Timeouts holds various configurable timeouts that can +be set in the config file.

+
+cluster +
+ + +ClusterParameters + + +
+(Optional) +

Cluster holds various configurable Envoy cluster values that can +be set in the config file.

+
+network +
+ + +NetworkParameters + + +
+(Optional) +

Network holds various configurable Envoy network values.

+
+

EnvoyListener +

+

+(Appears on: +EnvoyConfig) +

+

+

EnvoyListener defines parameters for an Envoy Listener.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines an Envoy Listener Address.

+
+port +
+ +int + +
+(Optional) +

Defines an Envoy listener Port.

+
+accessLog +
+ +string + +
+(Optional) +

AccessLog defines where Envoy logs are outputted for this listener.

+
+

EnvoyListenerConfig +

+

+(Appears on: +EnvoyConfig) +

+

+

EnvoyListenerConfig hold various configurable Envoy listener values.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+useProxyProtocol +
+ +bool + +
+(Optional) +

Use PROXY protocol for all listeners.

+

Contour’s default is false.

+
+disableAllowChunkedLength +
+ +bool + +
+(Optional) +

DisableAllowChunkedLength disables the RFC-compliant Envoy behavior to +strip the “Content-Length” header if “Transfer-Encoding: chunked” is +also set. This is an emergency off-switch to revert back to Envoy’s +default behavior in case of failures. Please file an issue if failures +are encountered. +See: https://github.com/projectcontour/contour/issues/3221

+

Contour’s default is false.

+
+disableMergeSlashes +
+ +bool + +
+(Optional) +

DisableMergeSlashes disables Envoy’s non-standard merge_slashes path transformation option +which strips duplicate slashes from request URL paths.

+

Contour’s default is false.

+
+serverHeaderTransformation +
+ + +ServerHeaderTransformationType + + +
+(Optional) +

Defines the action to be applied to the Server header on the response path. +When configured as overwrite, overwrites any Server header with “envoy”. +When configured as append_if_absent, if a Server header is present, pass it through, otherwise set it to “envoy”. +When configured as pass_through, pass through the value of the Server header, and do not append a header if none is present.

+

Values: overwrite (default), append_if_absent, pass_through

+

Other values will produce an error. +Contour’s default is overwrite.

+
+connectionBalancer +
+ +string + +
+(Optional) +

ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer +See https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/listener.proto#envoy-api-msg-listener-connectionbalanceconfig +for more information.

+

Values: (empty string): use the default ConnectionBalancer, exact: use the Exact ConnectionBalancer.

+

Other values will produce an error.

+
+maxRequestsPerConnection +
+ +uint32 + +
+(Optional) +

Defines the maximum requests for downstream connections. If not specified, there is no limit. +see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-msg-config-core-v3-httpprotocoloptions +for more information.

+
+per-connection-buffer-limit-bytes +
+ +uint32 + +
+(Optional) +

Defines the soft limit on size of the listener’s new connection read and write buffers in bytes. +If unspecified, an implementation defined default is applied (1MiB). +see 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 +for more information.

+
+tls +
+ + +EnvoyTLS + + +
+(Optional) +

TLS holds various configurable Envoy TLS listener values.

+
+socketOptions +
+ + +SocketOptions + + +
+(Optional) +

SocketOptions defines configurable socket options for the listeners. +Single set of options are applied to all listeners.

+
+maxRequestsPerIOCycle +
+ +uint32 + +
+(Optional) +

Defines the limit on number of HTTP requests that Envoy will process from a single +connection in a single I/O cycle. Requests over this limit are processed in subsequent +I/O cycles. Can be used as a mitigation for CVE-2023-44487 when abusive traffic is +detected. Configures the http.max_requests_per_io_cycle Envoy runtime setting. The default +value when this is not set is no limit.

+
+httpMaxConcurrentStreams +
+ +uint32 + +
+(Optional) +

Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS Envoy will advertise in the +SETTINGS frame in HTTP/2 connections and the limit for concurrent streams allowed +for a peer on a single HTTP/2 connection. It is recommended to not set this lower +than 100 but this field can be used to bound resource usage by HTTP/2 connections +and mitigate attacks like CVE-2023-44487. The default value when this is not set is +unlimited.

+
+maxConnectionsPerListener +
+ +uint32 + +
+(Optional) +

Defines the limit on number of active connections to a listener. The limit is applied +per listener. The default value when this is not set is unlimited.

+
+

EnvoyLogging +

+

+(Appears on: +EnvoyConfig) +

+

+

EnvoyLogging defines how Envoy’s logs can be configured.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+accessLogFormat +
+ + +AccessLogType + + +
+(Optional) +

AccessLogFormat sets the global access log format.

+

Values: envoy (default), json.

+

Other values will produce an error.

+
+accessLogFormatString +
+ +string + +
+(Optional) +

AccessLogFormatString sets the access log format when format is set to envoy. +When empty, Envoy’s default format is used.

+
+accessLogJSONFields +
+ + +AccessLogJSONFields + + +
+(Optional) +

AccessLogJSONFields sets the fields that JSON logging will +output when AccessLogFormat is json.

+
+accessLogLevel +
+ + +AccessLogLevel + + +
+(Optional) +

AccessLogLevel sets the verbosity level of the access log.

+

Values: info (default, all requests are logged), error (all non-success requests, i.e. 300+ response code, are logged), critical (all 5xx requests are logged) and disabled.

+

Other values will produce an error.

+
+

EnvoySettings +

+

+(Appears on: +ContourDeploymentSpec) +

+

+

EnvoySettings contains settings for the Envoy part of the installation, +i.e. the xDS client/data plane and associated resources.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+workloadType +
+ + +WorkloadType + + +
+(Optional) +

WorkloadType is the type of workload to install Envoy +as. Choices are DaemonSet and Deployment. If unset, defaults +to DaemonSet.

+
+replicas +
+ +int32 + +
+(Optional) +

Deprecated: Use DeploymentSettings.Replicas instead.

+

Replicas is the desired number of Envoy replicas. If WorkloadType +is not “Deployment”, this field is ignored. Otherwise, if unset, +defaults to 2.

+

if both DeploymentSettings.Replicas and this one is set, use DeploymentSettings.Replicas.

+
+networkPublishing +
+ + +NetworkPublishing + + +
+

NetworkPublishing defines how to expose Envoy to a network.

+
+nodePlacement +
+ + +NodePlacement + + +
+(Optional) +

NodePlacement describes node scheduling configuration of Envoy pods.

+
+extraVolumes +
+ + +[]Kubernetes core/v1.Volume + + +
+(Optional) +

ExtraVolumes holds the extra volumes to add.

+
+extraVolumeMounts +
+ + +[]Kubernetes core/v1.VolumeMount + + +
+(Optional) +

ExtraVolumeMounts holds the extra volume mounts to add (normally used with extraVolumes).

+
+podAnnotations +
+ +map[string]string + +
+(Optional) +

PodAnnotations defines annotations to add to the Envoy pods. +the annotations for Prometheus will be appended or overwritten with predefined value.

+
+resources +
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Compute Resources required by envoy container. +Cannot be updated. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

+
+logLevel +
+ + +LogLevel + + +
+(Optional) +

LogLevel sets the log level for Envoy. +Allowed values are “trace”, “debug”, “info”, “warn”, “error”, “critical”, “off”.

+
+daemonSet +
+ + +DaemonSetSettings + + +
+(Optional) +

DaemonSet describes the settings for running envoy as a DaemonSet. +if WorkloadType is Deployment,it’s must be nil

+
+deployment +
+ + +DeploymentSettings + + +
+(Optional) +

Deployment describes the settings for running envoy as a Deployment. +if WorkloadType is DaemonSet,it’s must be nil

+
+baseID +
+ +int32 + +
+(Optional) +

The base ID to use when allocating shared memory regions. +if Envoy needs to be run multiple times on the same machine, each running Envoy will need a unique base ID +so that the shared memory regions do not conflict. +defaults to 0.

+
+overloadMaxHeapSize +
+ +uint64 + +
+(Optional) +

OverloadMaxHeapSize defines the maximum heap memory of the envoy controlled by the overload manager. +When the value is greater than 0, the overload manager is enabled, +and when envoy reaches 95% of the maximum heap size, it performs a shrink heap operation, +When it reaches 98% of the maximum heap size, Envoy Will stop accepting requests. +More info: https://projectcontour.io/docs/main/config/overload-manager/

+
+

EnvoyTLS +

+

+(Appears on: +ClusterParameters, +EnvoyListenerConfig) +

+

+

EnvoyTLS describes tls parameters for Envoy listneners.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+minimumProtocolVersion +
+ +string + +
+(Optional) +

MinimumProtocolVersion is the minimum TLS version this vhost should +negotiate.

+

Values: 1.2 (default), 1.3.

+

Other values will produce an error.

+
+maximumProtocolVersion +
+ +string + +
+(Optional) +

MaximumProtocolVersion is the maximum TLS version this vhost should +negotiate.

+

Values: 1.2, 1.3(default).

+

Other values will produce an error.

+
+cipherSuites +
+ +[]string + +
+(Optional) +

CipherSuites defines the TLS ciphers to be supported by Envoy TLS +listeners when negotiating TLS 1.2. Ciphers are validated against the +set that Envoy supports by default. This parameter should only be used +by advanced users. Note that these will be ignored when TLS 1.3 is in +use.

+

This field is optional; when it is undefined, a Contour-managed ciphersuite list +will be used, which may be updated to keep it secure.

+

Contour’s default 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”

+

Ciphers provided are validated against the following list: +- “[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]” +- “[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]” +- “ECDHE-ECDSA-AES128-GCM-SHA256” +- “ECDHE-RSA-AES128-GCM-SHA256” +- “ECDHE-ECDSA-AES128-SHA” +- “ECDHE-RSA-AES128-SHA” +- “AES128-GCM-SHA256” +- “AES128-SHA” +- “ECDHE-ECDSA-AES256-GCM-SHA384” +- “ECDHE-RSA-AES256-GCM-SHA384” +- “ECDHE-ECDSA-AES256-SHA” +- “ECDHE-RSA-AES256-SHA” +- “AES256-GCM-SHA384” +- “AES256-SHA”

+

Contour recommends leaving this undefined unless you are sure you must.

+

See: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlsparameters +Note: This list is a superset of what is valid for stock Envoy builds and those using BoringSSL FIPS.

+
+

ExtensionProtocolVersion +(string alias)

+

+(Appears on: +ExtensionServiceSpec) +

+

+

ExtensionProtocolVersion is the version of the GRPC protocol used +to access extension services. The only version currently supported +is “v3”.

+

+ + + + + + + + + + + + +
ValueDescription

"v2"

SupportProtocolVersion2 requests the “v2” support protocol version.

+

Deprecated: this protocol version is no longer supported and the +constant is retained for backwards compatibility only.

+

"v3"

SupportProtocolVersion3 requests the “v3” support protocol version.

+
+

ExtensionServiceSpec +

+

+(Appears on: +ExtensionService) +

+

+

ExtensionServiceSpec defines the desired state of an ExtensionService resource.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+services +
+ + +[]ExtensionServiceTarget + + +
+

Services specifies the set of Kubernetes Service resources that +receive GRPC extension API requests. +If no weights are specified for any of the entries in +this array, traffic will be spread evenly across all the +services. +Otherwise, traffic is balanced proportionally to the +Weight field in each entry.

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the backend service’s certificate

+
+protocol +
+ +string + +
+(Optional) +

Protocol may be used to specify (or override) the protocol used to reach this Service. +Values may be h2 or h2c. If omitted, protocol-selection falls back on Service annotations.

+
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The policy for load balancing GRPC service requests. Note that the +Cookie and RequestHash load balancing strategies cannot be used +here.

+
+timeoutPolicy +
+ + +TimeoutPolicy + + +
+(Optional) +

The timeout policy for requests to the services.

+
+protocolVersion +
+ + +ExtensionProtocolVersion + + +
+(Optional) +

This field sets the version of the GRPC protocol that Envoy uses to +send requests to the extension service. Since Contour always uses the +v3 Envoy API, this is currently fixed at “v3”. However, other +protocol options will be available in future.

+
+

ExtensionServiceStatus +

+

+(Appears on: +ExtensionService) +

+

+

ExtensionServiceStatus defines the observed state of an +ExtensionService resource.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains the current status of the ExtensionService resource.

+

Contour will update a single condition, Valid, that is in normal-true polarity.

+

Contour will not modify any other Conditions set in this block, +in case some other controller wants to add a Condition.

+
+

ExtensionServiceTarget +

+

+(Appears on: +ExtensionServiceSpec) +

+

+

ExtensionServiceTarget defines an Kubernetes Service to target with +extension service traffic.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of Kubernetes service that will accept service +traffic.

+
+port +
+ +int + +
+

Port (defined as Integer) to proxy traffic to since a service can have multiple defined.

+
+weight +
+ +uint32 + +
+(Optional) +

Weight defines proportion of traffic to balance to the Kubernetes Service.

+
+

FeatureFlags +([]string alias)

+

+(Appears on: +ContourConfigurationSpec) +

+

+

FeatureFlags defines the set of feature flags +to toggle new contour features.

+

+

GatewayConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

GatewayConfig holds the config for Gateway API controllers.

+

+ + + + + + + + + + + + + +
FieldDescription
+gatewayRef +
+ + +NamespacedName + + +
+

GatewayRef defines the specific Gateway that this Contour +instance corresponds to.

+
+

GlobalCircuitBreakerDefaults +

+

+(Appears on: +ClusterParameters) +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+maxConnections +
+ +uint32 + +
+(Optional) +

The maximum number of connections that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

+
+maxPendingRequests +
+ +uint32 + +
+(Optional) +

The maximum number of pending requests that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

+
+maxRequests +
+ +uint32 + +
+(Optional) +

The maximum parallel requests a single Envoy instance allows to the Kubernetes Service; defaults to 1024

+
+maxRetries +
+ +uint32 + +
+(Optional) +

The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3.

+
+

HTTPProxyConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

HTTPProxyConfig defines parameters on HTTPProxy.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+disablePermitInsecure +
+ +bool + +
+(Optional) +

DisablePermitInsecure disables the use of the +permitInsecure field in HTTPProxy.

+

Contour’s default is false.

+
+rootNamespaces +
+ +[]string + +
+(Optional) +

Restrict Contour to searching these namespaces for root ingress routes.

+
+fallbackCertificate +
+ + +NamespacedName + + +
+(Optional) +

FallbackCertificate defines the namespace/name of the Kubernetes secret to +use as fallback when a non-SNI request is received.

+
+

HTTPVersionType +(string alias)

+

+(Appears on: +EnvoyConfig) +

+

+

HTTPVersionType is the name of a supported HTTP version.

+

+ + + + + + + + + + + + +
ValueDescription

"HTTP/1.1"

HTTPVersion1 is the name of the HTTP/1.1 version.

+

"HTTP/2"

HTTPVersion2 is the name of the HTTP/2 version.

+
+

HeadersPolicy +

+

+(Appears on: +PolicyConfig) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+set +
+ +map[string]string + +
+(Optional) +
+remove +
+ +[]string + +
+(Optional) +
+

HealthConfig +

+

+(Appears on: +ContourConfigurationSpec, +EnvoyConfig) +

+

+

HealthConfig defines the endpoints to enable health checks.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines the health address interface.

+
+port +
+ +int + +
+(Optional) +

Defines the health port.

+
+

IngressConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

IngressConfig defines ingress specific config items.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+classNames +
+ +[]string + +
+(Optional) +

Ingress Class Names Contour should use.

+
+statusAddress +
+ +string + +
+(Optional) +

Address to set in Ingress object status.

+
+

LogLevel +(string alias)

+

+(Appears on: +ContourSettings, +EnvoySettings) +

+

+

LogLevel is the logging levels available.

+

+ + + + + + + + + + + + + + + + + + + + + + +
ValueDescription

"critical"

CriticalLog sets the log level for Envoy to critical.

+

"debug"

DebugLog sets the log level for Contour/Envoy to debug.

+

"error"

ErrorLog sets the log level for Envoy to error.

+

"info"

InfoLog sets the log level for Contour/Envoy to info.

+

"off"

OffLog disable logging for Envoy.

+

"trace"

TraceLog sets the log level for Envoy to trace.

+

"warn"

WarnLog sets the log level for Envoy to warn.

+
+

MetricsConfig +

+

+(Appears on: +ContourConfigurationSpec, +EnvoyConfig) +

+

+

MetricsConfig defines the metrics endpoint.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines the metrics address interface.

+
+port +
+ +int + +
+(Optional) +

Defines the metrics port.

+
+tls +
+ + +MetricsTLS + + +
+(Optional) +

TLS holds TLS file config details. +Metrics and health endpoints cannot have same port number when metrics is served over HTTPS.

+
+

MetricsTLS +

+

+(Appears on: +MetricsConfig) +

+

+

TLS holds TLS file config details.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caFile +
+ +string + +
+(Optional) +

CA filename.

+
+certFile +
+ +string + +
+(Optional) +

Client certificate filename.

+
+keyFile +
+ +string + +
+(Optional) +

Client key filename.

+
+

NamespacedName +

+

+(Appears on: +EnvoyConfig, +GatewayConfig, +HTTPProxyConfig, +RateLimitServiceConfig, +TracingConfig) +

+

+

NamespacedName defines the namespace/name of the Kubernetes resource referred from the config file. +Used for Contour config YAML file parsing, otherwise we could use K8s types.NamespacedName.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+
+namespace +
+ +string + +
+
+

NetworkParameters +

+

+(Appears on: +EnvoyConfig) +

+

+

NetworkParameters hold various configurable network values.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+numTrustedHops +
+ +uint32 + +
+(Optional) +

XffNumTrustedHops defines the number of additional ingress proxy hops from the +right side of the x-forwarded-for HTTP header to trust when determining the origin +client’s IP address.

+

See https://www.envoyproxy.io/docs/envoy/v1.17.0/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto?highlight=xff_num_trusted_hops +for more information.

+

Contour’s default is 0.

+
+adminPort +
+ +int + +
+(Optional) +

Configure the port used to access the Envoy Admin interface. +If configured to port “0” then the admin interface is disabled.

+

Contour’s default is 9001.

+
+

NetworkPublishing +

+

+(Appears on: +EnvoySettings) +

+

+

NetworkPublishing defines the schema for publishing to a network.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+type +
+ + +NetworkPublishingType + + +
+(Optional) +

NetworkPublishingType is the type of publishing strategy to use. Valid values are:

+
    +
  • LoadBalancerService
  • +
+

In this configuration, network endpoints for Envoy use container networking. +A Kubernetes LoadBalancer Service is created to publish Envoy network +endpoints.

+

See: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer

+
    +
  • NodePortService
  • +
+

Publishes Envoy network endpoints using a Kubernetes NodePort Service.

+

In this configuration, Envoy network endpoints use container networking. A Kubernetes +NodePort Service is created to publish the network endpoints.

+

See: https://kubernetes.io/docs/concepts/services-networking/service/#nodeport

+

NOTE: +When provisioning an Envoy NodePortService, use Gateway Listeners’ port numbers to populate +the Service’s node port values, there’s no way to auto-allocate them.

+

See: https://github.com/projectcontour/contour/issues/4499

+
    +
  • ClusterIPService
  • +
+

Publishes Envoy network endpoints using a Kubernetes ClusterIP Service.

+

In this configuration, Envoy network endpoints use container networking. A Kubernetes +ClusterIP Service is created to publish the network endpoints.

+

See: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

+

If unset, defaults to LoadBalancerService.

+
+externalTrafficPolicy +
+ + +Kubernetes core/v1.ServiceExternalTrafficPolicy + + +
+(Optional) +

ExternalTrafficPolicy describes how nodes distribute service traffic they +receive on one of the Service’s “externally-facing” addresses (NodePorts, ExternalIPs, +and LoadBalancer IPs).

+

If unset, defaults to “Local”.

+
+ipFamilyPolicy +
+ + +Kubernetes core/v1.IPFamilyPolicy + + +
+(Optional) +

IPFamilyPolicy represents the dual-stack-ness requested or required by +this Service. If there is no value provided, then this field will be set +to SingleStack. Services can be “SingleStack” (a single IP family), +“PreferDualStack” (two IP families on dual-stack configured clusters or +a single IP family on single-stack clusters), or “RequireDualStack” +(two IP families on dual-stack configured clusters, otherwise fail).

+
+serviceAnnotations +
+ +map[string]string + +
+(Optional) +

ServiceAnnotations is the annotations to add to +the provisioned Envoy service.

+
+

NetworkPublishingType +(string alias)

+

+(Appears on: +NetworkPublishing) +

+

+

NetworkPublishingType is a way to publish network endpoints.

+

+ + + + + + + + + + + + + + +
ValueDescription

"ClusterIPService"

ClusterIPServicePublishingType publishes a network endpoint using a Kubernetes +ClusterIP Service.

+

"LoadBalancerService"

LoadBalancerServicePublishingType publishes a network endpoint using a Kubernetes +LoadBalancer Service.

+

"NodePortService"

NodePortServicePublishingType publishes a network endpoint using a Kubernetes +NodePort Service.

+
+

NodePlacement +

+

+(Appears on: +ContourSettings, +EnvoySettings) +

+

+

NodePlacement describes node scheduling configuration for pods. +If nodeSelector and tolerations are specified, the scheduler will use both to +determine where to place the pod(s).

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+nodeSelector +
+ +map[string]string + +
+(Optional) +

NodeSelector is the simplest recommended form of node selection constraint +and specifies a map of key-value pairs. For the pod to be eligible +to run on a node, the node must have each of the indicated key-value pairs +as labels (it can have additional labels as well).

+

If unset, the pod(s) will be scheduled to any available node.

+
+tolerations +
+ + +[]Kubernetes core/v1.Toleration + + +
+(Optional) +

Tolerations work with taints to ensure that pods are not scheduled +onto inappropriate nodes. One or more taints are applied to a node; this +marks that the node should not accept any pods that do not tolerate the +taints.

+

The default is an empty list.

+

See https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +for additional details.

+
+

PolicyConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

PolicyConfig holds default policy used if not explicitly set by the user

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+requestHeaders +
+ + +HeadersPolicy + + +
+(Optional) +

RequestHeadersPolicy defines the request headers set/removed on all routes

+
+responseHeaders +
+ + +HeadersPolicy + + +
+(Optional) +

ResponseHeadersPolicy defines the response headers set/removed on all routes

+
+applyToIngress +
+ +bool + +
+(Optional) +

ApplyToIngress determines if the Policies will apply to ingress objects

+

Contour’s default is false.

+
+

RateLimitServiceConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

RateLimitServiceConfig defines properties of a global Rate Limit Service.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+extensionService +
+ + +NamespacedName + + +
+

ExtensionService identifies the extension service defining the RLS.

+
+domain +
+ +string + +
+(Optional) +

Domain is passed to the Rate Limit Service.

+
+failOpen +
+ +bool + +
+(Optional) +

FailOpen defines whether to allow requests to proceed when the +Rate Limit Service fails to respond with a valid rate limit +decision within the timeout defined on the extension service.

+
+enableXRateLimitHeaders +
+ +bool + +
+(Optional) +

EnableXRateLimitHeaders defines whether to include the X-RateLimit +headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset +(as defined by the IETF Internet-Draft linked below), on responses +to clients when the Rate Limit Service is consulted for a request.

+

ref. https://tools.ietf.org/id/draft-polli-ratelimit-headers-03.html

+
+enableResourceExhaustedCode +
+ +bool + +
+(Optional) +

EnableResourceExhaustedCode enables translating error code 429 to +grpc code RESOURCE_EXHAUSTED. When disabled it’s translated to UNAVAILABLE

+
+defaultGlobalRateLimitPolicy +
+ + +GlobalRateLimitPolicy + + +
+(Optional) +

DefaultGlobalRateLimitPolicy allows setting a default global rate limit policy for every HTTPProxy. +HTTPProxy can overwrite this configuration.

+
+

ServerHeaderTransformationType +(string alias)

+

+(Appears on: +EnvoyListenerConfig) +

+

+

ServerHeaderTransformation defines the action to be applied to the Server header on the response path

+

+ + + + + + + + + + + + + + +
ValueDescription

"append_if_absent"

If no Server header is present, set it to “envoy”. +If a Server header is present, pass it through.

+

"overwrite"

Overwrite any Server header with “envoy”. +This is the default value.

+

"pass_through"

Pass through the value of the Server header, and do not append a header +if none is present.

+
+

SocketOptions +

+

+(Appears on: +EnvoyListenerConfig) +

+

+

SocketOptions defines configurable socket options for Envoy listeners.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+tos +
+ +int32 + +
+(Optional) +

Defines the value for IPv4 TOS field (including 6 bit DSCP field) for IP packets originating from Envoy listeners. +Single value is applied to all listeners. +If listeners are bound to IPv6-only addresses, setting this option will cause an error.

+
+trafficClass +
+ +int32 + +
+(Optional) +

Defines the value for IPv6 Traffic Class field (including 6 bit DSCP field) for IP packets originating from the Envoy listeners. +Single value is applied to all listeners. +If listeners are bound to IPv4-only addresses, setting this option will cause an error.

+
+

TLS +

+

+(Appears on: +XDSServerConfig) +

+

+

TLS holds TLS file config details.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caFile +
+ +string + +
+(Optional) +

CA filename.

+
+certFile +
+ +string + +
+(Optional) +

Client certificate filename.

+
+keyFile +
+ +string + +
+(Optional) +

Client key filename.

+
+insecure +
+ +bool + +
+(Optional) +

Allow serving the xDS gRPC API without TLS.

+
+

TimeoutParameters +

+

+(Appears on: +EnvoyConfig) +

+

+

TimeoutParameters holds various configurable proxy timeout values.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+requestTimeout +
+ +string + +
+(Optional) +

RequestTimeout sets the client request timeout globally for Contour. Note that +this is a timeout for the entire request, not an idle timeout. Omit or set to +“infinity” to disable the timeout entirely.

+

See 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-request-timeout +for more information.

+
+connectionIdleTimeout +
+ +string + +
+(Optional) +

ConnectionIdleTimeout defines how long the proxy should wait while there are +no active requests (for HTTP/1.1) or streams (for HTTP/2) before terminating +an HTTP connection. Set to “infinity” to disable the timeout entirely.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout +for more information.

+
+streamIdleTimeout +
+ +string + +
+(Optional) +

StreamIdleTimeout defines how long the proxy should wait while there is no +request activity (for HTTP/1.1) or stream activity (for HTTP/2) before +terminating the HTTP request or stream. Set to “infinity” to disable the +timeout entirely.

+

See 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-stream-idle-timeout +for more information.

+
+maxConnectionDuration +
+ +string + +
+(Optional) +

MaxConnectionDuration defines the maximum period of time after an HTTP connection +has been established from the client to the proxy before it is closed by the proxy, +regardless of whether there has been activity or not. Omit or set to “infinity” for +no max duration.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-max-connection-duration +for more information.

+
+delayedCloseTimeout +
+ +string + +
+(Optional) +

DelayedCloseTimeout defines how long envoy will wait, once connection +close processing has been initiated, for the downstream peer to close +the connection before Envoy closes the socket associated with the connection.

+

Setting this timeout to ‘infinity’ will disable it, equivalent to setting it to ‘0’ +in Envoy. Leaving it unset will result in the Envoy default value being used.

+

See 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-delayed-close-timeout +for more information.

+
+connectionShutdownGracePeriod +
+ +string + +
+(Optional) +

ConnectionShutdownGracePeriod defines how long the proxy will wait between sending an +initial GOAWAY frame and a second, final GOAWAY frame when terminating an HTTP/2 connection. +During this grace period, the proxy will continue to respond to new streams. After the final +GOAWAY frame has been sent, the proxy will refuse new streams.

+

See 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-drain-timeout +for more information.

+
+connectTimeout +
+ +string + +
+(Optional) +

ConnectTimeout defines how long the proxy should wait when establishing connection to upstream service. +If not set, a default value of 2 seconds will be used.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-connect-timeout +for more information.

+
+

TracingConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

TracingConfig defines properties for exporting trace data to OpenTelemetry.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+includePodDetail +
+ +bool + +
+(Optional) +

IncludePodDetail defines a flag. +If it is true, contour will add the pod name and namespace to the span of the trace. +the default is true. +Note: The Envoy pods MUST have the HOSTNAME and CONTOUR_NAMESPACE environment variables set for this to work properly.

+
+serviceName +
+ +string + +
+

ServiceName defines the name for the service. +contour’s default is contour.

+
+overallSampling +
+ +string + +
+(Optional) +

OverallSampling defines the sampling rate of trace data. +contour’s default is 100.

+
+maxPathTagLength +
+ +uint32 + +
+(Optional) +

MaxPathTagLength defines maximum length of the request path +to extract and include in the HttpUrl tag. +contour’s default is 256.

+
+customTags +
+ + +[]*github.com/projectcontour/contour/apis/projectcontour/v1alpha1.CustomTag + + +
+(Optional) +

CustomTags defines a list of custom tags with unique tag name.

+
+extensionService +
+ + +NamespacedName + + +
+

ExtensionService identifies the extension service defining the otel-collector.

+
+

WorkloadType +(string alias)

+

+(Appears on: +EnvoySettings) +

+

+

WorkloadType is the type of Kubernetes workload to use for a component.

+

+

XDSServerConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

XDSServerConfig holds the config for the Contour xDS server.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+type +
+ + +XDSServerType + + +
+(Optional) +

Defines the XDSServer to use for contour serve.

+

Values: envoy (default), contour (deprecated).

+

Other values will produce an error.

+
+address +
+ +string + +
+(Optional) +

Defines the xDS gRPC API address which Contour will serve.

+

Contour’s default is “0.0.0.0”.

+
+port +
+ +int + +
+(Optional) +

Defines the xDS gRPC API port which Contour will serve.

+

Contour’s default is 8001.

+
+tls +
+ + +TLS + + +
+(Optional) +

TLS holds TLS file config details.

+

Contour’s default is { caFile: “/certs/ca.crt”, certFile: “/certs/tls.cert”, keyFile: “/certs/tls.key”, insecure: false }.

+
+

XDSServerType +(string alias)

+

+(Appears on: +XDSServerConfig) +

+

+

XDSServerType is the type of xDS server implementation.

+

+ + + + + + + + + + + + +
ValueDescription

"contour"

Use Contour’s xDS server (deprecated).

+

"envoy"

Use the upstream go-control-plane-based xDS server.

+
+
+

+Generated with gen-crd-api-reference-docs. +

diff --git a/site/content/docs/1.29/config/api.md b/site/content/docs/1.29/config/api.md new file mode 100644 index 00000000000..99809537d11 --- /dev/null +++ b/site/content/docs/1.29/config/api.md @@ -0,0 +1,3 @@ +# Contour API Reference + +{{% include-html api-reference.html %}} diff --git a/site/content/docs/1.29/config/client-authorization.md b/site/content/docs/1.29/config/client-authorization.md new file mode 100644 index 00000000000..4db2b932eff --- /dev/null +++ b/site/content/docs/1.29/config/client-authorization.md @@ -0,0 +1,123 @@ +# Client Authorization + +Contour supports integrating external servers to authorize client requests. + +Envoy implements external authorization in the [ext_authz][1] filter. +This filter intercepts client requests and holds them while it sends a check +request to an external server. +The filter uses the check result to either allow the request to proceed, or to +deny or redirect the request. + +The diagram below shows the sequence of requests involved in the successful +authorization of a HTTP request: + +

+client authorization sequence diagram +

+ +The [external authorization][7] guides demonstrates how to deploy HTTP basic +authentication using Contour and [contour-authserver](https://github.com/projectcontour/contour-authserver). + +## Extension Services + +The starting point for external authorization in Contour is the +[ExtensionService][2] API. +This API creates a cluster which Envoy can use to send requests to an external server. +In principle, the Envoy cluster can be used for any purpose, but in this +document we are concerned only with how to use it as an authorization service. + +An authorization service is a gRPC service that implements the Envoy [CheckRequest][3] protocol. +Note that Contour requires the extension to implement the "v3" version of the protocol. +Contour is compatible with any authorization server that implements this protocol. + +The primary field of interest in the `ExtensionService` CRD is the +`.spec.services` field. +This field lists the Kubernetes Services that will receive the check requests. +The `.spec.services[].name` field contains the name of the Service, which must +exist in the same namespace as the `ExtensionService` object. +The `ExtensionService` object must exist in the same namespace as the +Services they target to ensure that both objects are under the same +administrative control. + +### Load Balancing for Extension Services + +An `ExtensionService` can be configured to send traffic to multiple Kubernetes Services. +In this case, requests are divided proportionally across the Services according +to the weight in the `.spec.services[].weight` field. +The service weight can be used to flexibly shift traffic between Services for +reasons like implementing blue-green deployments. +The `.spec.loadBalancerPolicy` field configures how Envoy will load balance +requests to the endpoints within each Service. + +### TLS Validation for Extension Services + +Since authorizing a client request may involve passing sensitive credentials +from a HTTP request to the authorization service, the connection to the +authorization server should be as secure as possible. +Contour defaults the `.spec.protocol` field to "h2", which configures +Envoy to use HTTP/2 over TLS for the authorization service connection. + +The [.spec.validation][4] field configures how Envoy should verify the TLS +identity of the authorization server. +This is a critical protection against accidentally sending credentials to an +imposter service and should be enabled for all production deployments. +The `.spec.validation` field should specify the expected server name +from the authorization server's TLS certificate, and the trusted CA bundle +that can be used to validate the TLS chain of trust. + +## Authorizing Virtual Hosts + +The [.spec.virtualhost.authorization][5] field in the Contour `HTTPProxy` +API connects a virtual host to an authorization server that is bound by an +`ExtensionService` object. +Each virtual host can use a different `ExtensionService`, but only one +`ExtensionService` can be used by a single virtual host. +Authorization servers can only be attached to `HTTPProxy` objects that have TLS +termination enabled. + +### Migrating from Application Authorization + +When applications perform their own authorization, migrating to centralized +authorization may need some planning. +The `.spec.virtualhost.authorization.failOpen` field controls how client +requests should be handled when the authorization server fails. +During a migration process, this can be set to `true`, so that if the +authorization server becomes unavailable, clients can gracefully fall back to +the existing application authorization mechanism. + +### Scoping Authorization Policy Settings + +It is common for services to contain some HTTP request paths that require +authorization and some that do not. +The HTTPProxy [authorization policy][6] allows authorization to be +disabled for both an entire virtual host and for specific routes. + +The initial authorization policy is set on the HTTPProxy virtual host +in the `.spec.virtualhost.authorization.authPolicy` field. +This configures whether authorization is enabled, and the default authorization policy context. +If authorization is disabled on the virtual host, it is also disabled by +default on all the routes for that virtual host that do not specify an authorization policy. +However, a route can configure its own authorization policy (in the +`.spec.routes[].authPolicy` field) that can configure whether authorization +is enabled, irrespective of the virtual host setting. + +The authorization policy context is a way to configure a set of key/value +pairs that will be sent to the authorization server with each request check +request. +The keys and values that should be specified here depend on which authorization +server has been configured. +This facility is intended for configuring authorization-specific information, such as +the basic authentication realm, or OIDC parameters. + +The initial context map can be set on the virtual host. +This sets the context keys that will be sent on every check request. +A route can overwrite the value for a context key by setting it in the +context field of authorization policy for the route. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter +[2]: api/#projectcontour.io/v1alpha1.ExtensionService +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto +[4]: api/#projectcontour.io/v1.UpstreamValidation +[5]: api/#projectcontour.io/v1.AuthorizationServer +[6]: api/#projectcontour.io/v1.AuthorizationPolicy +[7]: guides/external-authorization.md diff --git a/site/content/docs/1.29/config/cookie-rewriting.md b/site/content/docs/1.29/config/cookie-rewriting.md new file mode 100644 index 00000000000..480fc34125c --- /dev/null +++ b/site/content/docs/1.29/config/cookie-rewriting.md @@ -0,0 +1,109 @@ +# Cookie Rewriting + +Contour now enables users to customize attributes on HTTP `Set-Cookie` response headers. +Application specific cookies and cookies generated by Contour's ["cookie" load balancing strategy](https://projectcontour.io/docs/v1.19.0/config/request-routing/#session-affinity) can be rewritten either per HTTPProxy `Route` or `Service`. +Users can choose to rewrite the `Path`, `Domain`, `Secure`, and `SameSite` attributes of the `Set-Cookie` header currently. +These attributes may be things an application may not be able to accurately set, without prior knowledge of how the application is deployed. +For example, if Contour is in use to rewrite the path or hostname of a request before it reaches an application backend, the application may not be able to accurately set the `Path` and `Domain` attributes in a `Set-Cookie` response header. +This feature can be used to apply security settings to ensure browsers treat generated cookies appropriately. +The `SameSite` and `Secure` attributes are currently not set by Envoy when it generates the `X-Contour-Session-Affinity`, but with this feature, users can customize this cookie further. + +## Per-Route Cookie Rewriting + +In order to implement separate cookie rewriting policies per-route, we can configure an HTTPProxy as below: + +```yaml +# cookie-rewrite-route.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cookie-rewrite-route +spec: + virtualhost: + fqdn: cookie-rewrite-route.com + routes: + - conditions: + - prefix: /admin + services: + - name: admin-app + port: 80 + cookieRewritePolicies: + - name: X-Admin-Session + pathRewrite: + value: /admin + - conditions: + - prefix: /payments + services: + - name: payment-app + port: 80 + cookieRewritePolicies: + - name: X-User-Session + pathRewrite: + value: /payments + sameSite: Lax + - name: X-User-Data + sameSite: Lax +``` + +This HTTPProxy allows us to rewrite the `Path` attribute of the `X-Admin-Session` cookie on the `/admin` route. +In addition on the `/payments` route we rewrite the `Path` and `SameSite` attributes of the `X-User-Session` cookie and the `SameSite` attribute of the additional `X-User-Data` cookie. +If the backing services `payment-app` and `admin-app` return the specified cookies in `Set-Cookie` response headers, they will be rewritten with the values specified above. + +## Per-Service Cookie Rewriting + +Similar to the above, if we have more than one `Service` configured per `Route` but want to customize cookies separately between them we can: + +```yaml +# cookie-rewrite-service.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cookie-rewrite-service +spec: + virtualhost: + fqdn: cookie-rewrite-service.com + routes: + - conditions: + - prefix: / + services: + - name: backend-1 + port: 80 + cookieRewritePolicies: + - name: X-User-Data-1 + domainRewrite: + value: cookie-rewrite-service.com + - name: backend-2 + port: 80 + cookieRewritePolicies: + - name: X-User-Data-2 + domainRewrite: + value: cookie-rewrite-service.com +``` + +## Rewriting Contour Session Affinity Cookie + +As mentioned above, users can use Contour's cookie load balancing strategy to enable session affinity. +Envoy generates a pretty bare-bones cookie but Contour's cookie rewriting feature can be used to customize this cookie to add security attributes: + +```yaml +# cookie-rewrite-session-affinity.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cookie-rewrite-session-affinity +spec: + virtualhost: + fqdn: cookie-rewrite-session-affinity.com + routes: + - conditions: + - prefix: / + services: + - name: backend + port: 80 + loadBalancerPolicy: + strategy: Cookie + cookieRewritePolicies: + - name: X-Contour-Session-Affinity + sameSite: Strict + secure: true +``` diff --git a/site/content/docs/1.29/config/cors.md b/site/content/docs/1.29/config/cors.md new file mode 100644 index 00000000000..8f468aeaec7 --- /dev/null +++ b/site/content/docs/1.29/config/cors.md @@ -0,0 +1,82 @@ +# CORS + +A CORS (Cross-origin resource sharing) policy can be set for a HTTPProxy in order to allow cross-domain requests for trusted sources. +If a policy is set, it will be applied to all the routes of the virtual host. + +Contour allows configuring the headers involved in responses to cross-domain requests. +These include the `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers`, `Access-Control-Expose-Headers`, `Access-Control-Max-Age`, `Access-Control-Allow-Private-Network` and `Access-Control-Allow-Credentials` headers in responses. + +In this example, cross-domain requests will be allowed for any domain (note the `*` value), with the methods `GET`, `POST`, or `OPTIONS`. +Headers `Authorization` and `Cache-Control` will be passed to the upstream server and headers `Content-Length` and `Content-Range` will be made available to the cross-origin request client. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cors-example +spec: + virtualhost: + fqdn: www.example.com + corsPolicy: + allowCredentials: true + allowPrivateNetwork: true + allowOrigin: + - "*" # allows any origin + allowMethods: + - GET + - POST + - OPTIONS + allowHeaders: + - authorization + - cache-control + exposeHeaders: + - Content-Length + - Content-Range + maxAge: "10m" # preflight requests can be cached for 10 minutes. + routes: + - conditions: + - prefix: / + services: + - name: cors-example + port: 80 +``` + +The `allowOrigin` list may also be configured with exact origin matches or regex patterns. +In the following example, cross-domain requests must originate from the domain `https://client.example.com` or domains that match the regex `http[s]?:\/\/some-site-[a-z0-9]+\.example\.com` (e.g. request with `Origin` header `https://some-site-abc456.example.com`) + +*Note:* Patterns for matching `Origin` headers must be valid regex, simple "globbing" patterns (e.g. `*.foo.com`) will not be accepted or may produce incorrect matches. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cors-example +spec: + virtualhost: + fqdn: www.example.com + corsPolicy: + allowCredentials: true + allowOrigin: + - https://client.example.com + - http[s]?:\/\/some-site-[a-z0-9]+\.example\.com + allowMethods: + - GET + - POST + - OPTIONS + allowHeaders: + - authorization + - cache-control + exposeHeaders: + - Content-Length + - Content-Range + maxAge: "10m" + routes: + - conditions: + - prefix: / + services: + - name: cors-example + port: 80 +``` + +`MaxAge` durations are expressed in the Go [duration format](https://godoc.org/time#ParseDuration). +Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Only positive values are allowed and 0 disables the cache requiring a preflight `OPTIONS` check for all cross-origin requests. diff --git a/site/content/docs/1.29/config/external-service-routing.md b/site/content/docs/1.29/config/external-service-routing.md new file mode 100644 index 00000000000..7da431dd06b --- /dev/null +++ b/site/content/docs/1.29/config/external-service-routing.md @@ -0,0 +1,47 @@ +# External Service Routing + +HTTPProxy supports routing traffic to `ExternalName` service types, but this is disabled by default, as it can lead +to inadvertent exposure of the Envoy Admin UI, allowing remote shutdown and restart of Envoy. +Please see [this security advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for all the details. +It can also be used to expose services in namespaces a user does not have access to, using an ExternalName of `service.namespace.svc.cluster.local`. +Please see [this Kubernetes security advisory](https://github.com/kubernetes/kubernetes/issues/103675) for more details. + +We do *not* recommend enabling ExternalName Services without a strong use case, and understanding of the security implications. + +However, To enable ExternalName processing, you must set the `enableExternalNameService` configuration file setting to `true`. +This will allow the following configuration to be valid. + +## ExternalName Support + +Contour looks at the `spec.externalName` field of the service and configures the route to use that DNS name instead of utilizing EDS. + +Note that hostnames of `localhost` or some other synonyms will be rejected (because of the aforementioned security issues). + +There's nothing specific in the HTTPProxy object that needs to be configured other than referencing a service of type `ExternalName`. +HTTPProxy supports the `requestHeadersPolicy` field to rewrite the `Host` header after first handling a request and before proxying to an upstream service. +This field can be used to ensure that the forwarded HTTP request contains the hostname that the external resource is expecting. + +_**Note:** The ports are required to be specified._ + +```yaml +# httpproxy-externalname.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + run: externaldns + name: externaldns + namespace: default +spec: + externalName: foo-basic.bar.com + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 80 + type: ExternalName +``` + +To proxy to another resource outside the cluster (e.g. A hosted object store bucket for example), configure that external resource in a service type `externalName`. +Then define a `requestHeadersPolicy` which replaces the `Host` header with the value of the external name service defined previously. +Finally, if the upstream service is served over TLS, set the `protocol` field on the service to `tls` or annotate the external name service with: `projectcontour.io/upstream-protocol.tls: 443,https`, assuming your service had a port 443 and name `https`. diff --git a/site/content/docs/1.29/config/fundamentals.md b/site/content/docs/1.29/config/fundamentals.md new file mode 100644 index 00000000000..0bdac65f77f --- /dev/null +++ b/site/content/docs/1.29/config/fundamentals.md @@ -0,0 +1,197 @@ +# HTTPProxy Fundamentals + +The [Ingress][1] object was added to Kubernetes in version 1.1 to describe properties of a cluster-wide reverse HTTP proxy. +Since that time, the Ingress API has remained relatively unchanged, and the need to express implementation-specific capabilities has inspired an [explosion of annotations][2]. + +The goal of the HTTPProxy Custom Resource Definition (CRD) is to expand upon the functionality of the Ingress API to allow for a richer user experience as well addressing the limitations of the latter's use in multi tenant environments. + +## Key HTTPProxy Benefits + +- Safely supports multi-team Kubernetes clusters, with the ability to limit which Namespaces may configure virtual hosts and TLS credentials. +- Enables including of routing configuration for a path or domain from another HTTPProxy, possibly in another Namespace. +- Accepts multiple services within a single route and load balances traffic across them. +- Natively allows defining service weighting and load balancing strategy without annotations. +- Validation of HTTPProxy objects at creation time and status reporting for post-creation validity. + +## Ingress to HTTPProxy + +A minimal Ingress object might look like: + +```yaml +# ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: basic +spec: + rules: + - host: foo-basic.bar.com + http: + paths: + - backend: + service: + name: s1 + port: + number: 80 + pathType: Prefix +``` + +This Ingress object, named `basic`, will route incoming HTTP traffic with a `Host:` header for `foo-basic.bar.com` to a Service named `s1` on port `80`. +Implementing similar behavior using an HTTPProxy looks like this: + +```yaml +# httpproxy.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: basic +spec: + virtualhost: + fqdn: foo-basic.bar.com + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +``` + +**Lines 1-5**: As with all other Kubernetes objects, an HTTPProxy needs apiVersion, kind, and metadata fields. + +**Lines 7-8**: The presence of the `virtualhost` field indicates that this is a root HTTPProxy that is the top level entry point for this domain. + + +## Interacting with HTTPProxies + +As with all Kubernetes objects, you can use `kubectl` to create, list, describe, edit, and delete HTTPProxy CRDs. + +Creating an HTTPProxy: + +```bash +$ kubectl create -f basic.httpproxy.yaml +httpproxy "basic" created +``` + +Listing HTTPProxies: + +```bash +$ kubectl get httpproxy +NAME AGE +basic 24s +``` + +Describing HTTPProxy: + +```bash +$ kubectl describe httpproxy basic +Name: basic +Namespace: default +Labels: +API Version: projectcontour.io/v1 +Kind: HTTPProxy +Metadata: + Cluster Name: + Creation Timestamp: 2019-07-05T19:26:54Z + Resource Version: 19373717 + Self Link: /apis/projectcontour.io/v1/namespaces/default/httpproxy/basic + UID: 6036a9d7-8089-11e8-ab00-f80f4182762e +Spec: + Routes: + Conditions: + Prefix: / + Services: + Name: s1 + Port: 80 + Virtualhost: + Fqdn: foo-basic.bar.com +Events: +``` + +Deleting HTTPProxies: + +```bash +$ kubectl delete httpproxy basic +httpproxy "basic" deleted +``` + +## Status Reporting + +There are many misconfigurations that could cause an HTTPProxy or delegation to be invalid. +Contour will make its best effort to process even partially valid configuration and allow traffic to be served for the valid parts. +To aid users in resolving any issues, Contour updates a `status` field in all HTTPProxy objects. + +If an HTTPProxy object is valid, it will have a status property that looks like this: + +```yaml +status: + currentStatus: valid + description: valid HTTPProxy +``` + +If the HTTPProxy is invalid, the `currentStatus` field will be `invalid` and the `description` field will provide a description of the issue. + +As an example, if an HTTPProxy object has specified a negative value for weighting, the HTTPProxy status will be: + +```yaml +status: + currentStatus: invalid + description: "route '/foo': service 'home': weight must be greater than or equal to zero" +``` + +Some examples of invalid configurations that Contour provides statuses for: + +- Negative weight provided in the route definition. +- Invalid port number provided for service. +- Prefix in parent does not match route in delegated route. +- Root HTTPProxy created in a namespace other than the allowed root namespaces. +- A given Route of an HTTPProxy both delegates to another HTTPProxy and has a list of services. +- Orphaned route. +- Delegation chain produces a cycle. +- Root HTTPProxy does not specify fqdn. +- Multiple prefixes cannot be specified on the same set of route conditions. +- Multiple header conditions of type "exact match" with the same header key. +- Contradictory header conditions on a route, e.g. a "contains" and "notcontains" condition for the same header and value. + +Invalid configuration is ignored and will be not used in the ingress routing configuration. +Envoy will respond with an error when HTTP request is received on route with invalid configuration on following cases: + +* `502 Bad Gateway` response is sent when HTTPProxy has an include that refers to an HTTPProxy that does not exist. +* `503 Service Unavailable` response is sent when HTTPProxy refers to a service that does not exist. + +### Example + +Following example has two routes: the first one is valid, the second one refers to a service that does not exist. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-routes-with-a-missing-service +spec: + virtualhost: + fqdn: www.example.com + routes: + - conditions: + - prefix: / + services: + - name: valid-service + port: 80 + - conditions: + - prefix: /subpage + services: + - name: service-that-does-not-exist + port: 80 +``` + +The `HTTPProxy` will have condition `Valid=false` with detailed error message: `Spec.Routes unresolved service reference: service "default/service-that-does-not-exist" not found`. +Requests received for `http://www.example.com/` will be forwarded to `valid-service` but requests received for `http://www.example.com/subpage` will result in error `503 Service Unavailable` response from Envoy. + +## HTTPProxy API Specification + +The full HTTPProxy specification is described in detail in the [API documentation][4]. +There are a number of working examples of HTTPProxy objects in the [`examples/example-workload`][3] directory of the Contour Github repository. + + [1]: https://kubernetes.io/docs/concepts/services-networking/ingress/ + [2]: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md + [3]: {{< param github_url>}}/tree/{{< param branch >}}/examples/example-workload/httpproxy + [4]: api.md diff --git a/site/content/docs/1.29/config/gateway-api.md b/site/content/docs/1.29/config/gateway-api.md new file mode 100644 index 00000000000..605103dc7e3 --- /dev/null +++ b/site/content/docs/1.29/config/gateway-api.md @@ -0,0 +1,217 @@ +# Gateway API + +## Introduction + +[Gateway API][1] is an open source project managed by the SIG Network community. +It is a collection of resources that model service networking in Kubernetes. +These resources - GatewayClass, Gateway, HTTPRoute, TCPRoute, Service, etc - aim to evolve Kubernetes service networking through expressive, extensible, and role-oriented interfaces that are implemented by many vendors and have broad industry support. + +Contour implements Gateway API in addition to supporting HTTPProxy and Ingress. +In particular, Contour aims to support all [core and extended features][2] in Gateway API. + +Gateway API has a comprehensive [website and docs][1], so this document focuses primarily on unique aspects of Contour's Gateway API implementation, rather than attempting to reproduce all of the content available on the Gateway API website. +The reader is suggested to familiarize themselves with the basics of Gateway API before continuing with this doc. + +In Contour's Gateway API implementation, a Gateway corresponds 1:1 with a single deployment of Contour + Envoy. +In other words, each Gateway has its own control plane (Contour) and data plane (Envoy). + +The remainder of this document delves into more detail regarding configuration options when using Contour with Gateway API. +If you are looking for a way to get started with Gateway API and Contour, see the [Gateway API guide][12], a step-by-step tutorial on getting Contour installed with Gateway API and using it to route traffic to a service. + +## Enabling Gateway API in Contour + +There are two ways to deploy Contour with Gateway API support: **static** provisioning and **dynamic** provisioning. + +In **static** provisioning, the platform operator defines a `Gateway` resource, and then manually deploys a Contour instance corresponding to that `Gateway` resource. +It is up to the platform operator to ensure that all configuration matches between the `Gateway` and the Contour/Envoy resources. +Contour will then process that `Gateway` and its routes. + +In **dynamic** provisioning, the platform operator first deploys Contour's Gateway provisioner. Then, the platform operator defines a `Gateway` resource, and the provisioner automatically deploys a Contour instance that corresponds to the `Gateway's` configuration and will process that `Gateway` and its routes. + +Static provisioning makes sense for users who: +- prefer the traditional model of deploying Contour +- have only a single Gateway +- want to use just the standard listener ports (80/443) +- have highly customized YAML for deploying Contour. + +Dynamic provisioning makes sense for users who: +- have many Gateways +- want to use additional listener ports +- prefer a simple declarative API for provisioning Contour instances +- want a fully conformant Gateway API implementation + +### Static Provisioning + +To statically provision Contour with Gateway API enabled: + +1. Install the [Gateway API experimental channel][3]. +1. Create a GatewayClass, with a controller name of `projectcontour.io/gateway-controller`. +1. Create a Gateway using the above GatewayClass. +1. In the Contour config file, add a reference to the above Gateway via `gateway.gatewayRef` (see https://projectcontour.io/docs/1.25/configuration/#gateway-configuration) +1. Install Contour using the above config file. + +Contour provides an example manifest for this at https://projectcontour.io/quickstart/contour-gateway.yaml. + +### Dynamic Provisioning + +To dynamically provision Contour with Gateway API enabled: + +1. Install the [Contour Gateway Provisioner][9], which includes the Gateway API experimental channel. +1. Create a GatewayClass, with a controller name of `projectcontour.io/gateway-controller`. +1. Create a Gateway using the above GatewayClass. + +The Contour Gateway Provisioner will deploy an instance of Contour in the Gateway's namespace implementing the Gateway spec. + +**Note:** Gateway names must be 63 characters or shorter, to avoid issues when generating dependent resources. See [projectcontour/contour#5970][13] and [kubernetes-sigs/gateway-api#2592][14] for more information. + +## Gateway Listeners + +Each unique Gateway Listener port requires the Envoy service to expose that port, and to map it to an underlying port in the Envoy daemonset/deployment that Envoy is configured to listen on. +For example, the following Gateway Listener configuration (abridged) requires service ports of 80 and 443, mapped to underlying container ports 8080 and 8443: + +```yaml +listeners: +- name: http + protocol: HTTP + port: 80 +- name: https + protocol: HTTPS + port: 443 +``` + +In dynamic provisioning, the Contour Gateway Provisioner will continuously ensure that the Envoy service and daemonset/deployment are kept in sync with the Gateway Listener configuration. +In static provisioning, it is up to the platform operator to keep the Envoy resources in sync with the Gateway Listeners. + +To get from the Gateway Listener port to the port that Envoy will be configured to listen on, i.e. the container port: +- add 8000 to the Listener port number +- if the result is greater than 65535, subtract 65535 +- if the result is less than or equal to 1023, add 1023. + +Note that, in rare corner cases, it's possible to have port conflicts. +Check the Gateway status to ensure that Listeners have been properly provisioned. + +## Routing + +Gateway API defines multiple route types. +Each route type is appropriate for a different type of traffic being proxied to a backend service. +Contour implements `HTTPRoute`, `TLSRoute`, `GRPCRoute` and `TCPRoute`. +The details of each of these route types are covered in extensive detail on the Gateway API website; the [route resources overview][11] is a good place to start learning about them. + +### Routing with HTTPProxy or Ingress + +When Gateway API is enabled in Contour, it's still possible to use HTTPProxy or Ingress to define routes, with some limitations. +This is useful for users who: +- are in the process of migrating to Gateway API +- want to use the Contour Gateway Provisioner for dynamic provisioning, but need the advanced features of HTTPProxy + +To use HTTPProxy or Ingress with Gateway API, define a Gateway with the following Listeners: + +```yaml +listeners: +- name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +- name: https + protocol: projectcontour.io/https + port: 443 + allowedRoutes: + namespaces: + from: All +``` + +Note that for the second Listener, a Contour-specific protocol is used, and no TLS details are specified. +Instead, TLS details continue to be configured on the HTTPProxy or Ingress resource. + +This is an area of active development and further work will be done in upcoming releases to better support migrations and mixed modes of operation. + +## Contour Gateway Provisioner + +### Customizing a GatewayClass + +Gateway API [supports attaching parameters to a GatewayClass][5], which can customize the Gateways that are provisioned for that GatewayClass. + +Contour defines a CRD called `ContourDeployment`, which can be used as `GatewayClass` parameters. + +A simple example of a parameterized Contour GatewayClass that provisions Envoy as a Deployment instead of the default DaemonSet looks like: + +```yaml +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: contour-with-envoy-deployment +spec: + controllerName: projectcontour.io/gateway-controller + parametersRef: + kind: ContourDeployment + group: projectcontour.io + name: contour-with-envoy-deployment-params + namespace: projectcontour +--- +kind: ContourDeployment +apiVersion: projectcontour.io/v1alpha1 +metadata: + namespace: projectcontour + name: contour-with-envoy-deployment-params +spec: + envoy: + workloadType: Deployment +``` + +All Gateways provisioned using the `contour-with-envoy-deployment` GatewayClass would get an Envoy Deployment. + +See [the API documentation][6] for all `ContourDeployment` options. + +It's important to note that, per the [GatewayClass spec][10]: + +> It is recommended that [GatewayClass] 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 propagated down to existing Gateways. +> This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. +> If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. + +Contour follows the recommended behavior, meaning changes to a GatewayClass and its parameters are not propagated down to existing Gateways. + +### Upgrades + +When the Contour Gateway Provisioner is upgraded to a new version, it will upgrade all Gateways it controls (both the control plane and the data plane). + +## Disabling Experimental Resources + +Some users may want to use Contour with the [Gateway API standard channel][4] instead of the experimental channel, to avoid installing alpha resources into their clusters. +To do this, Contour must be told to disable informers for the experimental resources. +In the Contour (control plane) deployment, use the `--disable-feature` flag for `contour serve` to disable informers for the experimental resources: + +```yaml +containers: +- name: contour + image: ghcr.io/projectcontour/contour: + command: ["contour"] + args: + - serve + - --incluster + - --xds-address=0.0.0.0 + - --xds-port=8001 + - --contour-cafile=/certs/ca.crt + - --contour-cert-file=/certs/tls.crt + - --contour-key-file=/certs/tls.key + - --config-path=/config/contour.yaml + - --disable-feature=tlsroutes + - --disable-feature=grpcroutes +``` + +[1]: https://gateway-api.sigs.k8s.io/ +[2]: https://gateway-api.sigs.k8s.io/concepts/conformance/#2-support-levels +[3]: https://gateway-api.sigs.k8s.io/guides/#install-experimental-channel +[4]: https://gateway-api.sigs.k8s.io/guides/#install-standard-channel +[5]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/#gatewayclass-parameters +[6]: https://projectcontour.io/docs/main/config/api/#projectcontour.io/v1alpha1.ContourDeployment +[7]: https://projectcontour.io/docs/main/config/api/#projectcontour.io/v1alpha1.GatewayConfig +[8]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/#gatewayclass-controller-selection +[9]: https://projectcontour.io/quickstart/contour-gateway-provisioner.yaml +[10]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.GatewayClass +[11]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#route-resources +[12]: /docs/{{< param version >}}/guides/gateway-api +[13]: https://github.com/projectcontour/contour/issues/5970 +[14]: https://github.com/kubernetes-sigs/gateway-api/issues/2592 \ No newline at end of file diff --git a/site/content/docs/1.29/config/health-checks.md b/site/content/docs/1.29/config/health-checks.md new file mode 100644 index 00000000000..6dd1aac619d --- /dev/null +++ b/site/content/docs/1.29/config/health-checks.md @@ -0,0 +1,160 @@ +# Upstream Health Checks + +## HTTP Proxy Health Checking + +Active health checking can be configured on a per route basis. +Contour supports HTTP health checking and can be configured with various settings to tune the behavior. + +During HTTP health checking Envoy will send an HTTP request to the upstream Endpoints. +It expects a 200 response by default if the host is healthy (see `expectedStatuses` below for configuring the "healthy" status codes). +The upstream host can return 503 if it wants to immediately notify Envoy to no longer forward traffic to it. +It is important to note that these are health checks which Envoy implements and are separate from any other system such as those that exist in Kubernetes. + +```yaml +# httpproxy-health-checks.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + routes: + - conditions: + - prefix: / + healthCheckPolicy: + path: /healthy + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + services: + - name: s1-health + port: 80 + - name: s2-health + port: 80 +``` + +Health check configuration parameters: + +- `path`: HTTP endpoint used to perform health checks on upstream service (e.g. `/healthz`). It expects a 200 response if the host is healthy. The upstream host can return 503 if it wants to immediately notify downstream hosts to no longer forward traffic to it. +- `host`: The value of the host header in the HTTP health check request. If left empty (default value), the name "contour-envoy-healthcheck" will be used. +- `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set. +- `timeoutSeconds`: The time to wait (seconds) for a health check response. If the timeout is reached the health check attempt will be considered a failure. Defaults to 2 seconds if not set. +- `unhealthyThresholdCount`: The number of unhealthy health checks required before a host is marked unhealthy. Note that for http health checking if a host responds with 503 this threshold is ignored and the host is considered unhealthy immediately. Defaults to 3 if not defined. +- `healthyThresholdCount`: The number of healthy health checks required before a host is marked healthy. Note that during startup, only a single successful health check is required to mark a host healthy. +- `expectedStatuses`: An optional list of HTTP status ranges that are considered healthy. Ranges follow half-open semantics, meaning the start is inclusive and the end is exclusive. Statuses must be between 100 (inclusive) and 600 (exclusive). + +### Non-default expected statuses + +By default, only responses with a 200 status code will be considered healthy. +The set of response codes considered healthy can be customized by specifying ranges in `expectedStatuses`. +Ranges follow half-open semantics, meaning the start is inclusive and the end is exclusive. +Statuses must be between 100 (inclusive) and 600 (exclusive). +For example: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + routes: + - conditions: + - prefix: / + healthCheckPolicy: + path: /healthy + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + # Status codes 200 and 250-299 will be considered healthy. + expectedStatuses: + - start: 200 + end: 201 + - start: 250 + end: 300 + services: + - name: s1-health + port: 80 + - name: s2-health + port: 80 +``` + +Note that if `expectedStatuses` is specified, `200` must be explicitly included in one of the specified ranges if it is desired as a healthy status code. + +## TCP Proxy Health Checking + +Contour also supports TCP health checking and can be configured with various settings to tune the behavior. + +During TCP health checking Envoy will send a connect-only health check to the upstream Endpoints. +It is important to note that these are health checks which Envoy implements and are separate from any +other system such as those that exist in Kubernetes. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: tcp-health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + tcpproxy: + healthCheckPolicy: + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + services: + - name: s1-health + port: 80 + - name: s2-health + port: 80 +``` + +TCP Health check policy configuration parameters: + +- `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set. +- `timeoutSeconds`: The time to wait (seconds) for a health check response. If the timeout is reached the health check attempt will be considered a failure. Defaults to 2 seconds if not set. +- `unhealthyThresholdCount`: The number of unhealthy health checks required before a host is marked unhealthy. Note that for http health checking if a host responds with 503 this threshold is ignored and the host is considered unhealthy immediately. Defaults to 3 if not defined. +- `healthyThresholdCount`: The number of healthy health checks required before a host is marked healthy. Note that during startup, only a single successful health check is required to mark a host healthy. + +## Specify the service health check port + +contour supports configuring an optional health check port for services. + +By default, the service's health check port is the same as the service's routing port. +If the service's health check port and routing port are different, you can configure the health check port separately. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + routes: + - conditions: + - prefix: / + healthCheckPolicy: + path: /healthy + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + services: + - name: s1-health + port: 80 + healthPort: 8998 + - name: s2-health + port: 80 +``` + +In this example, envoy will send a health check request to port `8998` of the `s1-health` service and port `80` of the `s2-health` service respectively . If the host is healthy, envoy will forward traffic to the `s1-health` service on port `80` and to the `s2-health` service on port `80`. diff --git a/site/content/docs/1.29/config/inclusion-delegation.md b/site/content/docs/1.29/config/inclusion-delegation.md new file mode 100644 index 00000000000..b9364ff1fcd --- /dev/null +++ b/site/content/docs/1.29/config/inclusion-delegation.md @@ -0,0 +1,139 @@ +# HTTPProxy Inclusion + +HTTPProxy permits the splitting of a system's configuration into separate HTTPProxy instances using **inclusion**. + +Inclusion, as the name implies, allows for one HTTPProxy object to be included in another, optionally with some conditions inherited from the parent. +Contour reads the inclusion tree and merges the included routes into one big object internally before rendering Envoy config. +Importantly, the included HTTPProxy objects do not have to be in the same namespace. + +Each tree of HTTPProxy starts with a root, the top level object of the configuration for a particular virtual host. +Each root HTTPProxy defines a `virtualhost` key, which describes properties such as the fully qualified name of the virtual host, TLS configuration, etc. + +HTTPProxies included from the root must not contain a virtualhost key. +Root objects cannot include other roots either transitively or directly. +This permits the owner of an HTTPProxy root to allow the inclusion of a portion of the route space inside a virtual host, and to allow that route space to be further subdivided with inclusions. +Because the path is not necessarily used as the only key, the route space can be multi-dimensional. + +## Conditions and Inclusion + +Like Routes, Inclusion may specify a set of [conditions][1]. +These conditions are added to any conditions on the routes included. +This process is recursive. + +Conditions are sets of individual condition statements, for example `prefix: /blog` is the condition that the matching request's path must start with `/blog`. +When conditions are combined through inclusion Contour merges the conditions inherited via inclusion with any conditions specified on the route. +This may result in duplicates, for example two `prefix:` conditions, mix of both `prefix:` and `exact` or `prefix` and `regex` conditions, or two header match conditions with the same name and value. +To resolve this Contour applies the following logic. + +- `prefix:` conditions are concatenated together in the order they were applied from the root object. For example the conditions, `prefix: /api`, `prefix: /v1` becomes a single `prefix: /api/v1` conditions. Note: Multiple prefixes cannot be supplied on a single set of Route conditions. +- `exact:` conditions are also concatenated just like `prefix:` conditions, but `exact:` conditions are not allowed in include match conditions. If the child httpproxy has `exact:` condition then after concatenation, it becomes a single `exact:` condition. For example, `prefix: /static` and `exact: /main.js` become a single `exact: /static/main.js` condition. +- `regex:` conditions are also concatenated just like `prefix:` conditions, but `regex:` conditions are not allowed in include match conditions. If the child httpproxy has `regex:` condition then after concatenation, it becomes a single `regex:` condition. For example, `prefix: /static` and `regex: /.*/main.js` become a single `regex: /static/.*/main.js` condition. +- Proxies with repeated identical `header:` conditions of type "exact match" (the same header keys exactly) are marked as "Invalid" since they create an un-routable configuration. + +## Configuring Inclusion + +Inclusion is a top-level field in the HTTPProxy [spec][2] element. +It requires one field, `name`, and has two optional fields: + +- `namespace`. This will assume the included HTTPProxy is in the same namespace if it's not specified. +- a `conditions` block. + +## Inclusion Within the Same Namespace + +HTTPProxies can include other HTTPProxy objects in the namespace by specifying the name of the object and its namespace in the top-level `includes` block. +Note that `includes` is a list, and so it must use the YAML list construct. + +In this example, the HTTPProxy `include-root` has included the configuration for paths matching `/service2` from the HTTPProxy named `service2` in the same namespace as `include-root` (the `default` namespace). +It's important to note that `service2` HTTPProxy has not defined a `virtualhost` property as it is NOT a root HTTPProxy. + +```yaml +# httpproxy-inclusion-samenamespace.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: include-root + namespace: default +spec: + virtualhost: + fqdn: root.bar.com + includes: + # Includes the /service2 path from service2 in the same namespace + - name: service2 + namespace: default + conditions: + - prefix: /service2 + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: service2 + namespace: default +spec: + routes: + - services: # matches /service2 + - name: s2 + port: 80 + - conditions: + - prefix: /blog # matches /service2/blog + services: + - name: blog + port: 80 +``` + +## Inclusion Across Namespaces + +Inclusion can also happen across Namespaces by specifying a `namespace` in the `inclusion`. +This is a particularly powerful paradigm for enabling multi-team Ingress management. + +If the `--watch-namespaces` configuration flag is used, it must define all namespaces that will be referenced by the inclusion. + +In this example, the root HTTPProxy has included configuration for paths matching `/blog` to the `blog` HTTPProxy object in the `marketing` namespace. + +```yaml +# httpproxy-inclusion-across-namespaces.yaml +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: namespace-include-root + namespace: default +spec: + virtualhost: + fqdn: ns-root.bar.com + includes: + # delegate the subpath, `/blog` to the HTTPProxy object in the marketing namespace with the name `blog` + - name: blog + namespace: marketing + conditions: + - prefix: /blog + routes: + - services: + - name: s1 + port: 80 + +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: blog + namespace: marketing +spec: + routes: + - services: + - name: s2 + port: 80 +``` + +## Orphaned HTTPProxy children + +It is possible for HTTPProxy objects to exist that have not been delegated to by another HTTPProxy. +These objects are considered "orphaned" and will be ignored by Contour in determining ingress configuration. + +[1]: request-routing#conditions +[2]: api/#projectcontour.io/v1.HTTPProxySpec diff --git a/site/content/docs/1.29/config/ingress.md b/site/content/docs/1.29/config/ingress.md new file mode 100644 index 00000000000..22e65bb0255 --- /dev/null +++ b/site/content/docs/1.29/config/ingress.md @@ -0,0 +1,94 @@ +# k8s Ingress Resource Support in Contour + + + + + +This document describes Contour's implementation of specific Ingress resource fields and features. +As the Ingress specification has evolved between v1beta1 and v1, any differences between versions are highlighted to ensure clarity for Contour users. + +**Note: As of Contour version 1.16.0, Contour is not compatible with Kubernetes versions that predate Ingress v1. This means Contour 1.16.0 and above require Kubernetes 1.19 and above. The Ingress v1beta1 resource is still available in Kubernetes 1.19 (but will be removed in 1.22) and the API server will convert such resources to Ingress v1 for Contour to subscribe to.** + +## Kubernetes Versions + +Contour is [validated against Kubernetes release versions N through N-2][1] (with N being the latest release). +For Kubernetes version 1.19+, the API server translates any Ingress v1beta1 resources to Ingress v1 and Contour watches Ingress v1 resources. + +## IngressClass and IngressClass Name + +In order to support differentiating between Ingress controllers or multiple instances of a single Ingress controller, users can create an [IngressClass resource][2] and specify an IngressClass name on a Ingress to reference it. +The IngressClass resource can be used to provide configuration to an Ingress controller watching resources it governs. +Contour supports watching an IngressClass resource specified with the `--ingress-class-name` flag to the `contour serve` command. +Contour does not require an IngressClass resource with the name passed in the aforementioned flag to exist, the name can just be used as an identifier for filtering which Ingress resources Contour reconciles into actual route configuration. + +Ingresses may specify an IngressClass name via the original annotation method or via the `ingressClassName` spec field. +As the `ingressClassName` field has been introduced on Ingress v1beta1, there should be no differences in IngressClass name filtering between the two available versions of the resource. +Contour uses its configured IngressClass name to filter Ingresses. +If the `--ingress-class-name` flag is provided, Contour will only accept Ingress resources that exactly match the specified IngressClass name via annotation or spec field, with the value in the annotation taking precedence. (The `--ingress-class-name` value can be a comma-separated list of class names to match against.) +If the flag is not passed to `contour serve` Contour will accept any Ingress resource that specifies the IngressClass name `contour` in annotation or spec fields or does not specify one at all. + +## Default Backend + +Contour supports the `defaultBackend` Ingress v1 spec field and equivalent `backend` v1beta1 version of the field. +See upstream [documentation][3] on this field. +Any requests that do not match an Ingress rule will be forwarded to this backend. +As TLS secrets on Ingresses are scoped to specific hosts, this default backend cannot serve TLS as it could match an unbounded set of hosts and configuring a matching set of TLS secrets would not be possible. +As is the case on Ingress rules, Contour only supports configuring a Service as a backend and does not support any other Kubernetes resource. + +## Ingress Rules + +See upstream [documentation][4] on Ingress rules. + +As with default backends, Contour only supports configuring a Service as a backend and does not support any other Kubernetes resource. + +Contour supports [wildcard hostnames][5] as documented by the upstream API as well as precise hostnames. +Wildcard hostnames are limited to the whole first DNS label of the hostname, e.g. `*.foo.com` is valid but `*foo.com`, `foo*.com`, `foo.*.com` are not. +`*` is also not a valid hostname. +Precise hostnames in Ingress or HTTPProxy configuration take higher precedence over wildcards. +For example, given an Ingress rule with the hostname `*.foo.com` routing to `service-a` and another Ingress rule or HTTPProxy route containing a subdomain (say `bar.foo.com`) routing to `service-b`, requests to `bar.foo.com` will be routed to `service-b`. +The Ingress admission controller validation ensures valid hostnames are present when creating an Ingress resource. + +Contour supports all of the various [path matching][6] types described by the Ingress spec. +Prior to Contour 1.14.0, path match types were ignored and path matching was performed with a Contour specific implementation. +Paths specified with any regex meta-characters (any of `^+*[]%`) were implemented as regex matches. +Any other paths were programmed in Envoy as "string prefix" matches. +This behavior is preserved in the `ImplementationSpecific` match type in Contour 1.14.0+ to ensure backwards compatibility. +`Exact` path matches will now result in matching requests to the given path exactly. +The `Prefix` patch match type will now result in matching requests with a "segment prefix" rather than a "string prefix" according to the spec (e.g. the prefix `/foo/bar` will match requests with paths `/foo/bar`, `/foo/bar/`, and `/foo/bar/baz`, but not `/foo/barbaz`). + +## TLS + +See upstream [documentation][7] on TLS configuration. + +A secret specified in an Ingress TLS element will only be applied to Ingress rules with `Host` configuration that exactly matches an element of the TLS `Hosts` field. +Any secrets that do not match an Ingress rule `Host` will be ignored. + +In Ingress v1beta1, the `secretName` field could contain a string with a full `namespace/name` identifier. +When used with Contour's [TLS certificate delegation][8], this allowed Ingresses to use a TLS certificate from a different namespace. +However, Ingress v1 does not allow the `secretName` field to contain a string with a full `namespace/name` identifier, because the field validation disallows the `/` character. +Instead, Ingress v1 resources can now use the `projectcontour.io/tls-cert-namespace` annotation, to define the namespace that contains the TLS certificate (if different than the Ingress's namespace). +This enables the TLS certificate delegation functionality to continue working for Ingress v1. +For more information and an example, see the [TLS certificate delegation documentation][8]. + +## Status + +In order to inform users of the address the Services their Ingress resources can be accessed at, Contour sets status on Ingress resources. +If `contour serve` is run with the `--ingress-status-address` flag, Contour will use the provided value to set the Ingress status address accordingly. +If not provided, Contour will use the address of the Envoy service using the passed in `--envoy-service-name` and `--envoy-service-namespace` flags. + +## Header Manipulation + +The Ingress resource does not allow adding or removing HTTP headers on requests or responses. +However, Contour does allow users to set a global HTTP header [policy configuration][9] which can be optionally applied to configuration generated from Ingress resources. +Contour enables this behavior with the `applyToIngress` boolean field (set to `true` to enable). + +[0]: https://github.com/kubernetes-sigs/ingress-controller-conformance +[1]: /resources/compatibility-matrix/ +[2]: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class +[3]: https://kubernetes.io/docs/concepts/services-networking/ingress/#default-backend +[4]: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules +[5]: https://kubernetes.io/docs/concepts/services-networking/ingress/#hostname-wildcards +[6]: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types +[7]: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls +[8]: /docs/{{< param version >}}/config/tls-delegation/ +[9]: /docs/{{< param version >}}/configuration/#policy-configuration diff --git a/site/content/docs/1.29/config/ip-filtering.md b/site/content/docs/1.29/config/ip-filtering.md new file mode 100644 index 00000000000..161d39bc228 --- /dev/null +++ b/site/content/docs/1.29/config/ip-filtering.md @@ -0,0 +1,80 @@ +# IP Filtering + +Contour supports filtering requests based on the incoming ip address using Envoy's [RBAC Filter][1]. + +Requests can be either allowed or denied based on a CIDR range specified on the virtual host and/or individual routes. + +If the request's IP address is allowed, the request will be proxied to the appropriate upstream. +If the request's IP address is denied, an HTTP 403 (Forbidden) will be returned to the client. + +## Specifying Rules + +Rules are specified with the `ipAllowPolicy` and `ipDenyPolicy` fields on `virtualhost` and `route`: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: basic +spec: + virtualhost: + fqdn: foo-basic.bar.com + ipAllowPolicy: + # traffic is allowed if it came from localhost (i.e. co-located reverse proxy) + - cidr: 127.0.0.1/32 + source: Peer + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + # route-level ip filters override the virtualhost-level filters + ipAllowPolicy: + # traffic is allowed if it came from localhost (i.e. co-located reverse proxy) + - cidr: 127.0.0.1/32 + source: Peer + # and the request originated from an IP in this range + - cidr: 99.99.0.0/16 + source: Remote +``` + +### Specifying CIDR Ranges + +CIDR ranges may be ipv4 or ipv6. Bare IP addresses are interpreted as the CIDR range containing that one ip address only. + +Examples: +- `1.1.1.1/24` +- `127.0.0.1` +- `2001:db8::68/24` +- `2001:db8::68` + +### Allow vs Deny + +Filters are specified as either allow or deny: + +- `ipAllowPolicy` only allows requests that match the ip filters. +- `ipDenyPolicy` denies all requests unless they match the ip filters. + +Allow and deny policies cannot both be specified at the same time for a virtual host or route. + +### IP Source + +The `source` field controls how the ip address is selected from the request for filtering. + +- `source: Peer` filter rules will filter using Envoy's [direct_remote_ip][2], which is always the physical peer. +- `source: Remote` filter rules will filter using Envoy's [remote_ip][3], which may be inferred from the X-Forwarded-For header or proxy protocol. + +If using `source: Remote` with `X-Forwarded-For`, it may be necessary to configure Contour's `numTrustedHops` in [Network Parameters][4]. + +### Virtual Host and Route Filter Precedence + +IP filters on the virtual host apply to all routes included in the virtual host, unless the route specifies its own rules. + +Rules specified on a route override any rules defined on the virtual host, they are not additive. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rbac_filter.html +[2]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/rbac/v3/rbac.proto#envoy-v3-api-field-config-rbac-v3-principal-direct-remote-ip +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/rbac/v3/rbac.proto#envoy-v3-api-field-config-rbac-v3-principal-remote-ip +[4]: api/#projectcontour.io/v1.NetworkParameters + diff --git a/site/content/docs/1.29/config/jwt-verification.md b/site/content/docs/1.29/config/jwt-verification.md new file mode 100644 index 00000000000..3f884ad2aef --- /dev/null +++ b/site/content/docs/1.29/config/jwt-verification.md @@ -0,0 +1,182 @@ +# JWT Verification + +Contour supports verifying JSON Web Tokens (JWTs) on incoming requests, using Envoy's [jwt_authn HTTP filter][1]. +Specifically, the following properties can be checked: +- issuer field +- audiences field +- signature, using a configured JSON Web Key Store (JWKS) +- time restrictions (e.g. expiration, not before time) + +If verification succeeds, the request will be proxied to the appropriate upstream. +If verification fails, an HTTP 401 (Unauthorized) will be returned to the client. + +JWT verification is only supported on TLS-terminating virtual hosts. + +## Configuring providers and rules + +A JWT provider is configured for an HTTPProxy's virtual host, and defines how to verify JWTs: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + issuer: example.com + audiences: + - audience-1 + - audience-2 + remoteJWKS: + uri: https://example.com/jwks.json + timeout: 1s + cacheDuration: 5m + forwardJWT: true + routes: + ... +``` + +The provider above requires JWTs to have an issuer of example.com, an audience of either audience-1 or audience-2, and a signature that can be verified using the configured JWKS. +It also forwards the JWT to the backend via the `Authorization` header after successful verification. + +To apply a JWT provider as a requirement to a given route, specify a `jwtVerificationPolicy` for the route: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + ... + routes: + - conditions: + - prefix: / + jwtVerificationPolicy: + require: provider-1 + services: + - name: s1 + port: 80 + - conditions: + - prefix: /css + services: + - name: s1 + port: 80 +``` + +In the above example, the default route requires requests to carry JWTs that can be verified using provider-1. +The second route _excludes_ requests to paths starting with `/css` from JWT verification, because it does not have a JWT verification policy. + +### Configuring TLS validation for the JWKS server + +By default, the JWKS server's TLS certificate will not be validated, but validation can be requested by setting the `spec.virtualhost.jwtProviders[].remoteJWKS.validation` field. +This field has mandatory `caSecret` and `subjectName` fields, which specify the trusted root certificates with which to validate the server certificate and the expected server name. +The `caSecret` can be a namespaced name of the form `/`. +If the CA secret's namespace is not the same namespace as the `HTTPProxy` resource, [TLS Certificate Delegation][5] must be used to allow the owner of the CA certificate secret to delegate, for the purposes of referencing the CA certificate in a different namespace, permission to Contour to read the Secret object from another namespace. + +**Note:** If `spec.virtualhost.jwtProviders[].remoteJWKS.validation` is present, `spec.virtualhost.jwtProviders[].remoteJWKS.uri` must have a scheme of `https`. + +## Setting a default provider + +The previous section showed how to explicitly require JWT providers for specific routes. +An alternate approach is to define a JWT provider as the default by specifying `default: true` for it, in which case it is automatically applied to all routes unless they disable JWT verification. +The example from the previous section could alternately be configured as follows: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + default: true + ... + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - conditions: + - prefix: /css + jwtVerificationPolicy: + disabled: true + services: + - name: s1 + port: 80 +``` + +In this case, the default route automatically has provider-1 applied, while the `/css` route explicitly disables JWT verification. + +One scenario where setting a default provider can be particularly useful is when using [HTTPProxy inclusion][2]. +Setting a default provider in the root HTTPProxy allows all routes in the child HTTPProxies to automatically have JWT verification applied. +For example: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification-root + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + default: true + ... + includes: + - name: jwt-verification-child + namespace: default + conditions: + - prefix: /blog +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification-child + namespace: default +spec: + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +``` + +In this case, all routes in the child HTTPProxy will automatically have JWT verification applied, without the owner of this HTTPProxy needing to configure it explicitly. + +## API documentation + +For more information on the HTTPProxy API for JWT verification, see: + +- [JWTProvider][3] +- [JWTVerificationPolicy][4] + + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter +[2]: /docs/{{< param version >}}/config/inclusion-delegation/ +[3]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.JWTProvider +[4]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.JWTVerificationPolicy +[5]: tls-delegation.md diff --git a/site/content/docs/1.29/config/overload-manager.md b/site/content/docs/1.29/config/overload-manager.md new file mode 100644 index 00000000000..33c96532eba --- /dev/null +++ b/site/content/docs/1.29/config/overload-manager.md @@ -0,0 +1,30 @@ +# Overload Manager + +Envoy uses heap memory when processing requests. +When the system runs out of memory or memory resource limit for the container is reached, Envoy process is terminated abruptly. +To avoid this, Envoy [overload manager][1] can be enabled. +Overload manager controls how much memory Envoy will allocate at maximum and what actions it takes when the limit is reached. + +Overload manager is disabled by default. +It can be enabled at deployment time by using `--overload-max-heap=[MAX_BYTES]` command line flag in [`contour bootstrap`][2] command. +The bootstrap command is executed in [init container of Envoy pod][3] to generate initial configuration for Envoy. +To enable overload manager, modify the deployment manifest and add for example `--overload-max-heap=2147483648` to set maximum heap size to 2 GiB. +The appropriate number of bytes can be different from system to system. + +After the feature is enabled, following two overload actions are configured to Envoy: + +* Shrink heap action is executed when 95% of the maximum heap size is reached. +* Envoy will stop accepting requests when 98% of the maximum heap size is reached. + +When requests are denied due to high memory pressure, `503 Service Unavailable` will be returned with a response body containing text `envoy overloaded`. +Shrink heap action will try to free unused heap memory, eventually allowing requests to be processed again. + +**NOTE:** +The side effect of overload is that Envoy will deny also requests `/ready` and `/stats` endpoints. +This is due to the way how Contour secures Envoy's admin API and exposes only selected admin API endpoints by proxying itself. +When readiness probe fails, the overloaded Envoy will be removed from the list of service endpoints. +If the maximum heap size is set too low, Envoy may be unable to free enough memory and never become ready again. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager +[2]: ../configuration#bootstrap-flags +[3]: https://github.com/projectcontour/contour/blob/cbec8eca9e8b639318588c5aa7ec0b5b751938c5/examples/render/contour.yaml#L5204-L5216 diff --git a/site/content/docs/1.29/config/rate-limiting.md b/site/content/docs/1.29/config/rate-limiting.md new file mode 100644 index 00000000000..7a69c22c079 --- /dev/null +++ b/site/content/docs/1.29/config/rate-limiting.md @@ -0,0 +1,366 @@ +# Rate Limiting + +- [Overview](#overview) +- [Local Rate Limiting](#local-rate-limiting) +- [Global Rate Limiting](#global-rate-limiting) + +## Overview + +Rate limiting is a means of protecting backend services against unwanted traffic. +This can be useful for a variety of different scenarios: + +- Protecting against denial-of-service (DoS) attacks by malicious actors +- Protecting against DoS incidents due to bugs in client applications/services +- Enforcing usage quotas for different classes of clients, e.g. free vs. paid tiers +- Controlling resource consumption/cost + +Envoy supports two forms of HTTP rate limiting: **local** and **global**. + +In local rate limiting, rate limits are enforced by each Envoy instance, without any communication with other Envoys or any external service. + +In global rate limiting, an external rate limit service (RLS) is queried by each Envoy via gRPC for rate limit decisions. + +Contour supports both forms of Envoy's rate limiting. + +## Local Rate Limiting + +The `HTTPProxy` API supports defining local rate limit policies that can be applied to either individual routes or entire virtual hosts. +Local rate limit policies define a maximum number of requests per unit of time that an Envoy should proxy to the upstream service. +Requests beyond the defined limit will receive a `429 (Too Many Requests)` response by default. +Local rate limit policies program Envoy's [HTTP local rate limit filter][1]. + +It's important to note that local rate limit policies apply *per Envoy pod*. +For example, a local rate limit policy of 100 requests per second for a given route will result in *each Envoy pod* allowing up to 100 requests per second for that route. + +### Defining a local rate limit + +Local rate limit policies can be defined for either routes or virtual hosts. A local rate limit policy requires a `requests` and a `units` field, defining the *number of requests per unit of time* that are allowed. `Requests` must be a positive integer, and `units` can be `second`, `minute`, or `hour`. Optionally, a `burst` parameter can also be provided, defining the number of requests above the baseline rate that are allowed in a short period of time. This would allow occasional larger bursts of traffic not to be rate limited. + +Local rate limiting for the virtual host: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-vhost +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + local: + requests: 100 + unit: hour + burst: 20 + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +Local rate limiting for the route: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-route +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + local: + requests: 20 + unit: minute + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +### Customizing the response + +#### Response code + +By default, Envoy returns a `429 (Too Many Requests)` when a request is rate limited. +A non-default response code can optionally be configured as part of the local rate limit policy, in the `responseStatusCode` field. +The value must be in the 400-599 range. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: custom-ratelimit-response +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + local: + requests: 20 + unit: minute + responseStatusCode: 503 # Service Unavailable +``` + +#### Headers + +Headers can optionally be added to rate limited responses, by configuring the `responseHeadersToAdd` field. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: custom-ratelimit-response +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + local: + requests: 20 + unit: minute + responseHeadersToAdd: + - name: x-contour-ratelimited + value: "true" +``` + +## Global Rate Limiting + +The `HTTPProxy` API also supports defining global rate limit policies on routes and virtual hosts. + +In order to use global rate limiting, you must first select and deploy an external rate limit service (RLS). +There is an [Envoy rate limit service implementation][2], but any service that implements the [RateLimitService gRPC interface][3] is supported. + +### Configuring an external RLS with Contour + +Once you have deployed your RLS, you must configure it with Contour. + +Define an extension service for it (substituting values as appropriate): +```yaml +apiVersion: projectcontour.io/v1alpha1 +kind: ExtensionService +metadata: + namespace: projectcontour + name: ratelimit +spec: + protocol: h2 + services: + - name: ratelimit + port: 8081 +``` + +Now add a reference to it in the Contour config file: +```yaml +rateLimitService: + # The namespace/name of the extension service. + extensionService: projectcontour/ratelimit + # The domain value to pass to the RLS for all rate limit + # requests. Acts as a container for a set of rate limit + # definitions within the RLS. + domain: contour + # Whether to allow requests to proceed when the rate limit + # service fails to respond with a valid rate limit decision + # within the timeout defined on the extension service. + failOpen: true +``` + +### Defining a global rate limit policy + +Global rate limit policies can be defined for either routes or virtual hosts. Unlike local rate limit policies, global rate limit policies do not directly define a rate limit. Instead, they define a set of request descriptors that will be generated and sent to the external RLS for each request. The external RLS then makes the rate limit decision based on the descriptors and returns a response to Envoy. + +A global rate limit policy for the virtual host: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-vhost +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + global: + descriptors: + # the first descriptor has a single key-value pair: + # [ remote_address= ]. + - entries: + - remoteAddress: {} + # the second descriptor has two key-value pairs: + # [ remote_address=, vhost=local.projectcontour.io ]. + - entries: + - remoteAddress: {} + - genericKey: + key: vhost + value: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +A global rate limit policy for the route: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-route +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + global: + descriptors: + # the first descriptor has a single key-value pair: + # [ remote_address= ]. + - entries: + - remoteAddress: {} + # the second descriptor has two key-value pairs: + # [ remote_address=, prefix=/s1 ]. + - entries: + - remoteAddress: {} + - genericKey: + key: prefix + value: /s1 + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +#### Descriptors & descriptor entries + +A descriptor is a list of key-value pairs, i.e. entries, that are generated for a request. The entries can be generated based on different criteria. If any entry in a descriptor cannot generate a key-value pair for a given request, then the entire descriptor is not generated (see the [Envoy documentation][8] for more information). When a global rate limit policy defines multiple descriptors, then *all* descriptors that can be generated will be generated and sent to the rate limit service for consideration. + +Below are the supported types of descriptor entries. + +##### GenericKey + +A `GenericKey` descriptor entry defines a static key-value pair. For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - genericKey: + key: virtual-host-name + value: foo.bar.com +``` + +Produces a descriptor entry of `virtual-host-name=foo.bar.com`. + +The `key` field is optional and defaults to a value of `generic_key` if not specified. + +See the [Envoy documentation][4] for more information and examples. + +##### RemoteAddress + +A `RemoteAddress` descriptor entry has a key of `remote_address` and a value of the client IP address (using the trusted address from `x-forwarded-for`). For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - remoteAddress: {} +``` + +Produces a descriptor entry of `remote_address=`. + +See the [Envoy documentation][5] for more information and examples. + +##### RequestHeader + +A `RequestHeader` descriptor entry has a static key and a value equal to the value of a specified header on the client request. If the header is not present, the descriptor entry is not generated. For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - requestHeader: + headerName: My-Header + descriptorKey: my-header-value +``` + +Produces a descriptor entry of `my-header-value=`, for a client request that has the `My-Header` header. + +See the [Envoy documentation][6] for more information and examples. + +##### RequestHeaderValueMatch + +A `RequestHeaderValueMatch` descriptor entry has a key of `header_match` and a static value. The entry is only generated if the client request's headers match a specified set of criteria. For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - requestHeaderValueMatch: + headers: + - name: My-Header + notpresent: true + - name: My-Other-Header + contains: contour + expectMatch: true + value: foo +``` + +Produces a descriptor entry of `header_match=foo`, for a client request that does not have the `My-Header` header, and does have the `My-Other-Header` header, with a value containing the substring "contour". + +Contour supports `present`, `notpresent`, `contains`, `notcontains`, `exact`, and `notexact` header match operators. + +The `expectMatch` field defaults to true if not specified. If true, the client request's headers must positively match the specified criteria in order for the descriptor entry to be generated. If false, the client request's header must *not* match the specified criteria in order for the descriptor entry to be generated. + +See the [Envoy documentation][7] for more information and examples. + + + +[1]: https://www.envoyproxy.io/docs/envoy/v1.17.0/configuration/http/http_filters/local_rate_limit_filter#config-http-filters-local-rate-limit +[2]: https://github.com/envoyproxy/ratelimit +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto +[4]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-ratelimit-action-generickey +[5]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-action-remoteaddress +[6]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-action-requestheaders +[7]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-action-headervaluematch +[8]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter#composing-actions diff --git a/site/content/docs/1.29/config/request-rewriting.md b/site/content/docs/1.29/config/request-rewriting.md new file mode 100644 index 00000000000..88fa3cc2508 --- /dev/null +++ b/site/content/docs/1.29/config/request-rewriting.md @@ -0,0 +1,337 @@ +# Request Rewriting + +## Path Rewriting + +HTTPProxy supports rewriting the HTTP request URL path prior to delivering the request to the backend service. +Rewriting is performed after a routing decision has been made, and never changes the request destination. + +The `pathRewritePolicy` field specifies how the path prefix should be rewritten. +The `replacePrefix` rewrite policy specifies a replacement string for a HTTP request path prefix match. +When this field is present, the path prefix that the request matched is replaced by the text specified in the `replacement` field. +If the HTTP request path is longer than the matched prefix, the remainder of the path is unchanged. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: rewrite-example + namespace: default +spec: + virtualhost: + fqdn: rewrite.bar.com + routes: + - services: + - name: s1 + port: 80 + pathRewritePolicy: + replacePrefix: + - replacement: /new/prefix +``` + +The `replacePrefix` field accepts an array of possible replacements. +When more than one `replacePrefix` array element is present, the `prefix` field can be used to disambiguate which replacement to apply. + +If no `prefix` field is present, the replacement is applied to all prefix matches made against the route. +If a `prefix` field is present, the replacement is applied only to routes that have an exactly matching prefix condition. +Specifying more than one `replacePrefix` entry is mainly useful when a HTTPProxy document is included into multiple parent documents. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: rewrite-example + namespace: default +spec: + virtualhost: + fqdn: rewrite.bar.com + routes: + - services: + - name: s1 + port: 80 + conditions: + - prefix: /v1/api + pathRewritePolicy: + replacePrefix: + - prefix: /v1/api + replacement: /app/api/v1 + - prefix: / + replacement: /app +``` + +## Header Rewriting + +HTTPProxy supports rewriting HTTP request and response headers. +The `Set` operation sets a HTTP header value, creating it if it doesn't already exist or overwriting it if it does. +The `Remove` operation removes a HTTP header. +The `requestHeadersPolicy` field is used to rewrite headers on a HTTP request, and the `responseHeadersPolicy` is used to rewrite headers on a HTTP response. +These fields can be specified on a route or on a specific service, depending on the rewrite granularity you need. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: header-rewrite-example +spec: + virtualhost: + fqdn: header.bar.com + routes: + - services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: Host + value: external.dev + remove: + - Some-Header + - Some-Other-Header +``` + +Manipulating headers is also supported per-Service or per-Route. Headers can be set or +removed from the request or response as follows: + +per-Service: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: header-manipulation + namespace: default +spec: + virtualhost: + fqdn: headers.bar.com + routes: + - services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: X-Foo + value: bar + remove: + - X-Baz + responseHeadersPolicy: + set: + - name: X-Service-Name + value: s1 + remove: + - X-Internal-Secret +``` + +per-Route: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: header-manipulation + namespace: default +spec: + virtualhost: + fqdn: headers.bar.com + routes: + - services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: X-Foo + value: bar + remove: + - X-Baz + responseHeadersPolicy: + set: + - name: X-Service-Name + value: s1 + remove: + - X-Internal-Secret +``` + +In these examples we are setting the header `X-Foo` with value `baz` on requests +and stripping `X-Baz`. We are then setting `X-Service-Name` on the response with +value `s1`, and removing `X-Internal-Secret`. + +### Dynamic Header Values + +It is sometimes useful to set a header value using a dynamic value such as the +hostname where the Envoy Pod is running (`%HOSTNAME%`) or the subject of the +TLS client certificate (`%DOWNSTREAM_PEER_SUBJECT%`) or based on another header +(`%REQ(header)%`). + +Examples: +``` + requestHeadersPolicy: + set: + - name: X-Envoy-Hostname + value: "%HOSTNAME%" + - name: X-Host-Protocol + value: "%REQ(Host)% - %PROTOCOL%" + responseHeadersPolicy: + set: + - name: X-Envoy-Response-Flags + value: "%RESPONSE_FLAGS%" +``` + +Contour supports most of the custom request/response header variables offered +by Envoy - see the Envoy +documentation for details of what each of these resolve to: + +* `%DOWNSTREAM_REMOTE_ADDRESS%` +* `%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%` +* `%DOWNSTREAM_LOCAL_ADDRESS%` +* `%DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT%` +* `%DOWNSTREAM_LOCAL_PORT%` +* `%DOWNSTREAM_LOCAL_URI_SAN%` +* `%DOWNSTREAM_PEER_URI_SAN%` +* `%DOWNSTREAM_LOCAL_SUBJECT%` +* `%DOWNSTREAM_PEER_SUBJECT%` +* `%DOWNSTREAM_PEER_ISSUER%` +* `%DOWNSTREAM_TLS_SESSION_ID%` +* `%DOWNSTREAM_TLS_CIPHER%` +* `%DOWNSTREAM_TLS_VERSION%` +* `%DOWNSTREAM_PEER_FINGERPRINT_256%` +* `%DOWNSTREAM_PEER_FINGERPRINT_1%` +* `%DOWNSTREAM_PEER_SERIAL%` +* `%DOWNSTREAM_PEER_CERT%` +* `%DOWNSTREAM_PEER_CERT_V_START%` +* `%DOWNSTREAM_PEER_CERT_V_END%` +* `%HOSTNAME%` +* `%REQ(header-name)%` +* `%PROTOCOL%` +* `%RESPONSE_FLAGS%` +* `%RESPONSE_CODE_DETAILS%` +* `%UPSTREAM_REMOTE_ADDRESS%` + +Note that Envoy passes variables that can't be expanded through unchanged or +skips them entirely - for example: +* `%UPSTREAM_REMOTE_ADDRESS%` as a request header remains as + `%UPSTREAM_REMOTE_ADDRESS%` because as noted in the Envoy docs: "The upstream + remote address cannot be added to request headers as the upstream host has not + been selected when custom request headers are generated." +* `%DOWNSTREAM_TLS_VERSION%` is skipped if TLS is not in use +* Envoy ignores REQ headers that refer to an non-existent header - for example + `%REQ(Host)%` works as expected but `%REQ(Missing-Header)%` is skipped + +Contour already sets the `X-Request-Start` request header to +`t=%START_TIME(%s.%3f)%` which is the Unix epoch time when the request +started. + +To enable setting header values based on the destination service Contour also supports: + +* `%CONTOUR_NAMESPACE%` +* `%CONTOUR_SERVICE_NAME%` +* `%CONTOUR_SERVICE_PORT%` + +For example, with the following HTTPProxy object that has a per-Service requestHeadersPolicy using these variables: +``` +# httpproxy.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: basic + namespace: myns +spec: + virtualhost: + fqdn: foo-basic.bar.com + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: l5d-dst-override + value: "%CONTOUR_SERVICE_NAME%.%CONTOUR_NAMESPACE%.svc.cluster.local:%CONTOUR_SERVICE_PORT%" +``` +the values would be: +* `CONTOUR_NAMESPACE: "myns"` +* `CONTOUR_SERVICE_NAME: "s1"` +* `CONTOUR_SERVICE_PORT: "80"` + +and the `l5-dst-override` header would be set to `s1.myns.svc.cluster.local:80`. + +For per-Route requestHeadersPolicy only `%CONTOUR_NAMESPACE%` is set and using +`%CONTOUR_SERVICE_NAME%` and `%CONTOUR_SERVICE_PORT%` will end up as the +literal values `%%CONTOUR_SERVICE_NAME%%` and `%%CONTOUR_SERVICE_PORT%%`, +respectively. + +### Manipulating the Host header + +Contour allows users to manipulate the host header in two ways, using the `requestHeadersPolicy`. + +#### Static rewrite + +You can set the host to a static value. This can be done on the route and service level. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: static-host-header-rewrite-route +spec: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - requestHeaderPolicy: + set: + - name: host + value: foo.com +``` + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: static-host-header-rewrite-service +spec: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - requestHeaderPolicy: + set: + - name: host + value: "foo.com" +``` + +#### Dynamic rewrite + +You can also set the host header dynamically with the content of an existing header. +The format has to be `"%REQ()%"`. If the header is empty, it is ignored. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: dynamic-host-header-rewrite-route +spec: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - requestHeaderPolicy: + set: + - name: host + value: "%REQ(x-rewrite-header)%" +``` + +Note: Only one of static or dynamic host rewrite can be specified. + +Note: Dynamic rewrite is only available at the route level and not possible on the service level. + +Note: Pay attention to the potential security implications of using this option, the provided header must come from a trusted source. + +Note: The header rewrite is only done while forwarding and has no bearing on the routing decision. diff --git a/site/content/docs/1.29/config/request-routing.md b/site/content/docs/1.29/config/request-routing.md new file mode 100644 index 00000000000..19ef5386e86 --- /dev/null +++ b/site/content/docs/1.29/config/request-routing.md @@ -0,0 +1,535 @@ +# Request Routing + +A HTTPProxy object must have at least one route or include defined. +In this example, any requests to `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` will be routed to the Service `s2` using the prefix conditions. Requests to `multi-path.bar.com/feed` will be routed to Service `s2` using exact match condition. +All other requests to the host `multi-path.bar.com` will be routed to the Service `s1`. + +```yaml +# httpproxy-multiple-paths.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-paths + namespace: default +spec: + virtualhost: + fqdn: multi-path.bar.com + routes: + - conditions: + - prefix: / # matches everything else + services: + - name: s1 + port: 80 + - conditions: + - prefix: /blog # matches `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` + services: + - name: s2 + port: 80 + - conditions: + - exact: /feed # matches `multi-path.bar.com/feed` only + services: + - name: s2 + port: 80 +``` + +In the following example, we match on headers and query parameters and send to different services, with a default route if those do not match. + +```yaml +# httpproxy-multiple-headers.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-paths + namespace: default +spec: + virtualhost: + fqdn: multi-path.bar.com + routes: + - conditions: + - header: + name: x-os + contains: ios + services: + - name: s1 + port: 80 + - conditions: + - header: + name: x-os + contains: android + services: + - name: s2 + port: 80 + - conditions: + - queryParameter: + name: os + exact: other + ignoreCase: true + services: + - name: s3 + port: 80 + - services: + - name: s4 + port: 80 +``` + +## Conditions + +Each Route entry in a HTTPProxy **may** contain one or more conditions. +These conditions are combined with an AND operator on the route passed to Envoy. +Conditions can be either a `prefix`, `exact`, `regex`, `header` or a `queryParameter` condition. At most one of `prefix`, `exact` or `regex` can be used in one condition block. + +#### Prefix conditions + +Paths defined are matched using prefix conditions. +Up to one prefix condition may be present in any condition block. + +Prefix conditions **must** start with a `/` if they are present. + +#### Exact conditions + +Paths defined are matched using exact conditions. +Up to one exact condition may be present in any condition block. Any condition block can +either have a regex condition, exact condition or prefix condition, but not multiple together. Exact conditions are +only allowed in route match conditions and not in include match conditions. + +Exact conditions **must** start with a `/` if they are present. + +#### Regex conditions + +Paths defined are matched using regex expressions. +Up to one regex condition may be present in any condition block. Any condition block can +either have a regex condition, exact condition or prefix condition, but not multiple together. Regex conditions are +only allowed in route match conditions and not in include match conditions. + +Regex conditions **must** start with a `/` if they are present. + +#### Header conditions + +For `header` conditions there is the following structure: + +1. one required field, `name` +2. six operator fields: `present`, `notpresent`, `contains`, `notcontains`, `exact`, and `notexact` +3. two optional modifiers: `ignoreCase` and `treatMissingAsEmpty` + +Operators: +- `present` is a boolean and checks that the header is present. The value will not be checked. + +- `notpresent` similarly checks that the header is *not* present. + +- `contains` is a string, and checks that the header contains the string. `notcontains` similarly checks that the header does *not* contain the string. + +- `exact` is a string, and checks that the header exactly matches the whole string. `notexact` checks that the header does *not* exactly match the whole string. + +- `regex` is a string representing a regular expression, and checks that the header value matches against the given regular expression. + +Modifiers: +- `ignoreCase`: IgnoreCase specifies that string matching should be case insensitive. It has no effect on the `Regex` parameter. +- `treatMissingAsEmpty`: specifies if the header match rule specified header does not exist, this header value will be treated as empty. Defaults to false. Unlike the underlying Envoy implementation this is **only** supported for negative matches (e.g. NotContains, NotExact). + +#### Query parameter conditions + +Similar to the `header` conditions, `queryParameter` conditions also require the +`name` field to be specified, which represents the name of the query parameter +e.g. `search` when the query string looks like `/?search=term` and `term` +representing the value. + +There are six operator fields: `exact`, `prefix`, `suffix`, `regex`, `contains` +and `present` and a modifier `ignoreCase` which can be used together with all of +the operator fields except `regex` and `present`. + +- `exact` is a string, and checks that the query parameter value exactly matches + the whole string. + +- `prefix` is a string, and checks that the query parameter value is prefixed by + the given value. + +- `suffix` is a string, and checks that the query parameter value is suffixed by + the given value. + +- `regex` is a string representing a regular expression, and checks that the + query parameter value matches against the given regular expression. + +- `contains` is a string, and checks that the query parameter value contains + the given string. + +- `present` is a boolean, and checks that the query parameter is present. The + value will not be checked. + +- `ignoreCase` is a boolean, and if set to `true` it will enable case + insensitive matching for any of the string operator matching methods. + +## Request Redirection + +HTTP redirects can be implemented in HTTPProxy using `requestRedirectPolicy` on a route. +In the following basic example, requests to `example.com` are redirected to `www.example.com`. +We configure a root HTTPProxy for `example.com` that contains redirect configuration. +We also configure a root HTTPProxy for `www.example.com` that represents the destination of the redirect. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example-com +spec: + virtualhost: + fqdn: example.com + routes: + - conditions: + - prefix: / + requestRedirectPolicy: + hostname: www.example.com +``` + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: www-example-com +spec: + virtualhost: + fqdn: www.example.com + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +``` + +In addition to specifying the hostname to set in the `location` header, the scheme, port, and returned status code of the redirect response can be configured. +Configuration of the path or a path prefix replacement to modify the path of the returned `location` can be included as well. +See [the API specification][3] for more detail. + +## Multiple Upstreams + +One of the key HTTPProxy features is the ability to support multiple services for a given path: + +```yaml +# httpproxy-multiple-upstreams.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-upstreams + namespace: default +spec: + virtualhost: + fqdn: multi.bar.com + routes: + - services: + - name: s1 + port: 80 + - name: s2 + port: 80 +``` + +In this example, requests for `multi.bar.com/` will be load balanced across two Kubernetes Services, `s1`, and `s2`. +This is helpful when you need to split traffic for a given URL across two different versions of an application. + +### Upstream Weighting + +Building on multiple upstreams is the ability to define relative weights for upstream Services. +This is commonly used for canary testing of new versions of an application when you want to send a small fraction of traffic to a specific Service. + +```yaml +# httpproxy-weight-shifting.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: weight-shifting + namespace: default +spec: + virtualhost: + fqdn: weights.bar.com + routes: + - services: + - name: s1 + port: 80 + weight: 10 + - name: s2 + port: 80 + weight: 90 +``` + +In this example, we are sending 10% of the traffic to Service `s1`, while Service `s2` receives the remaining 90% of traffic. + +HTTPProxy weighting follows some specific rules: + +- If no weights are specified for a given route, it's assumed even distribution across the Services. +- Weights are relative and do not need to add up to 100. If all weights for a route are specified, then the "total" weight is the sum of those specified. As an example, if weights are 20, 30, 20 for three upstreams, the total weight would be 70. In this example, a weight of 30 would receive approximately 42.9% of traffic (30/70 = .4285). +- If some weights are specified but others are not, then it's assumed that upstreams without weights have an implicit weight of zero, and thus will not receive traffic. + +### Traffic mirroring + +Per route, a service can be nominated as a mirror. +The mirror service will receive a copy of the read traffic sent to any non mirror service. +The mirror traffic is considered _read only_, any response by the mirror will be discarded. + +This service can be useful for recording traffic for later replay or for smoke testing new deployments. + +`weight` can be optionally set (in the space of integers 1-100) to mirror the corresponding percent of traffic (ie. `weight: 5` mirrors 5% of traffic). Omitting the `weight` field results in 100% traffic mirroring. There is unexpected behavior if `weight` is explicitly set to 0, 100% traffic will be mirrored. This occurs because we cannot distinguish undefined variables from explicitly setting them to default values, and omission of a `weight` must mirror full traffic. +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: traffic-mirror + namespace: default +spec: + virtualhost: + fqdn: www.example.com + routes: + - conditions: + - prefix: / + services: + - name: www + port: 80 + - name: www-mirror + port: 80 + mirror: true +``` + +## Response Timeouts + +Each Route can be configured to have a timeout policy and a retry policy as shown: + +```yaml +# httpproxy-response-timeout.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: response-timeout + namespace: default +spec: + virtualhost: + fqdn: timeout.bar.com + routes: + - timeoutPolicy: + response: 1s + idle: 10s + idleConnection: 60s + retryPolicy: + count: 3 + perTryTimeout: 150ms + services: + - name: s1 + port: 80 +``` + +In this example, requests to `timeout.bar.com/` will have a response timeout policy of 1s. +This refers to the time that spans between the point at which complete client request has been processed by the proxy, and when the response from the server has been completely processed. + +- `timeoutPolicy.response` Timeout for receiving a response from the server after processing a request from client. +If not supplied, Envoy's default value of 15s applies. +More information can be found in [Envoy's documentation][4]. +- `timeoutPolicy.idle` Timeout for how long the proxy should wait while there is no activity during single request/response (for HTTP/1.1) or stream (for HTTP/2). +Timeout will not trigger while HTTP/1.1 connection is idle between two consecutive requests. +If not specified, there is no per-route idle timeout, though a connection manager-wide stream idle timeout default of 5m still applies. +More information can be found in [Envoy's documentation][6]. +- `timeoutPolicy.idleConnection` Timeout for how long connection from the proxy to the upstream service is kept when there are no active requests. +If not supplied, Envoy’s default value of 1h applies. +More information can be found in [Envoy's documentation][8]. + +TimeoutPolicy durations are expressed in the Go [Duration format][5]. +Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". +The string "infinity" is also a valid input and specifies no timeout. +A value of "0s" will be treated as if the field were not set, i.e. by using Envoy's default behavior. +Example input values: "300ms", "5s", "1m". + +- `retryPolicy`: A retry will be attempted if the server returns an error code in the 5xx range, or if the server takes more than `retryPolicy.perTryTimeout` to process a request. + +- `retryPolicy.count` specifies the maximum number of retries allowed. This parameter is optional and defaults to 1. Set to -1 to disable. If set to 0, the Envoy default of 1 is used. + +- `retryPolicy.perTryTimeout` specifies the timeout per retry. If this field is greater than the request timeout, it is ignored. This parameter is optional. + If left unspecified, `timeoutPolicy.request` will be used. + +## Load Balancing Strategy + +Each route can have a load balancing strategy applied to determine which of its Endpoints is selected for the request. +The following list are the options available to choose from: + +- `RoundRobin`: Each healthy upstream Endpoint is selected in round-robin order (Default strategy if none selected). +- `WeightedLeastRequest`: The least request load balancer uses different algorithms depending on whether hosts have the same or different weights in an attempt to route traffic based upon the number of active requests or the load at the time of selection. +- `Random`: The random strategy selects a random healthy Endpoints. +- `RequestHash`: The request hashing strategy allows for load balancing based on request attributes. An upstream Endpoint is selected based on the hash of an element of a request. For example, requests that contain a consistent value in an HTTP request header will be routed to the same upstream Endpoint. Currently, only hashing of HTTP request headers, query parameters and the source IP of a request is supported. +- `Cookie`: The cookie load balancing strategy is similar to the request hash strategy and is a convenience feature to implement session affinity, as described below. + +More information on the load balancing strategy can be found in [Envoy's documentation][7]. + +The following example defines the strategy for the route `/` as `WeightedLeastRequest`. + +```yaml +# httpproxy-lb-strategy.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-strategy + namespace: default +spec: + virtualhost: + fqdn: strategy.bar.com + routes: + - conditions: + - prefix: / + services: + - name: s1-strategy + port: 80 + - name: s2-strategy + port: 80 + loadBalancerPolicy: + strategy: WeightedLeastRequest +``` + +The below example demonstrates how request hash load balancing policies can be configured: + +Request hash headers +```yaml +# httpproxy-lb-request-hash.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-request-hash + namespace: default +spec: + virtualhost: + fqdn: request-hash.bar.com + routes: + - conditions: + - prefix: / + services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: RequestHash + requestHashPolicies: + - headerHashOptions: + headerName: X-Some-Header + terminal: true + - headerHashOptions: + headerName: User-Agent + - hashSourceIP: true +``` +In this example, if a client request contains the `X-Some-Header` header, the value of the header will be hashed and used to route to an upstream Endpoint. This could be used to implement a similar workflow to cookie-based session affinity by passing a consistent value for this header. If it is present, because it is set as a `terminal` hash option, Envoy will not continue on to process to `User-Agent` header or source IP to calculate a hash. If `X-Some-Header` is not present, Envoy will use the `User-Agent` header value to make a routing decision along with the source IP of the client making the request. These policies can be used alone or as shown for an advanced routing decision. + + +Request hash source ip +```yaml +# httpproxy-lb-request-hash-ip.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-request-hash + namespace: default +spec: + virtualhost: + fqdn: request-hash.bar.com + routes: + - conditions: + - prefix: / + services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: RequestHash + requestHashPolicies: + - hashSourceIP: true +``` + +Request hash query parameters +```yaml +# httpproxy-lb-request-hash.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-request-hash + namespace: default +spec: + virtualhost: + fqdn: request-hash.bar.com + routes: + - conditions: + - prefix: / + services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: RequestHash + requestHashPolicies: + - queryParameterHashOptions: + prameterName: param1 + terminal: true + - queryParameterHashOptions: + parameterName: param2 +``` + +## Session Affinity + +Session affinity, also known as _sticky sessions_, is a load balancing strategy whereby a sequence of requests from a single client are consistently routed to the same application backend. +Contour supports session affinity on a per-route basis with `loadBalancerPolicy` `strategy: Cookie`. + +```yaml +# httpproxy-sticky-sessions.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: httpbin + namespace: default +spec: + virtualhost: + fqdn: httpbin.davecheney.com + routes: + - services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: Cookie +``` + +Session affinity is based on the premise that the backend servers are robust, do not change ordering, or grow and shrink according to load. +None of these properties are guaranteed by a Kubernetes cluster and will be visible to applications that rely heavily on session affinity. + +Any perturbation in the set of pods backing a service risks redistributing backends around the hash ring. + +## Internal Redirects + +HTTPProxy supports handling 3xx redirects internally, that is capturing a configurable 3xx redirect response, synthesizing a new request, sending it to the upstream specified by the new route match, and returning the redirected response as the response to the original request. + +Internal redirects can be enabled in HTTPProxy by defining an `internalRedirectPolicy` on a route. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: myservice + namespace: prod +spec: + virtualhost: + fqdn: foo.com + routes: + - conditions: + - prefix: /download + services: + - name: foo + port: 8080 + internalRedirectPolicy: + maxInternalRedirects: 5 + redirectResponseCodes: [ 302 ] + allowCrossSchemeRedirect: SafeOnly + denyRepeatedRouteRedirect: true +``` + +In this example, a sample redirect flow might look like this: + +1. Client sends a `GET` request for http://foo.com/download. +2. Upstream `foo` returns a `302` response with `location: http://foo.com/myfile`. +3. Envoy lookups a route for http://foo.com/myfile and sends a new `GET` request to the corresponding upstream with the additional request header `x-envoy-original-url: http://foo.com/download`. +4. Envoy proxies the response data for http://foo.com/myfile to the client as the response to the original request. + +See [the API specification][9] and [Envoy's documentation][10] for more detail. + +[3]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.HTTPRequestRedirectPolicy +[4]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-timeout +[5]: https://godoc.org/time#ParseDuration +[6]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-idle-timeout +[7]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/overview +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout +[9] /docs/{{< param version >}}/config/api/#projectcontour.io/v1.HTTPInternalRedirectPolicy +[10] https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/http_connection_management.html#internal-redirects diff --git a/site/content/docs/1.29/config/slow-start.md b/site/content/docs/1.29/config/slow-start.md new file mode 100644 index 00000000000..b44cc18fdc3 --- /dev/null +++ b/site/content/docs/1.29/config/slow-start.md @@ -0,0 +1,39 @@ +# Slow Start Mode + +Slow start mode is a configuration setting that is used to gradually increase the amount of traffic targeted to a newly added upstream endpoint. +By default, the amount of traffic will increase linearly for the duration of time window set by `window` field, starting from 10% of the target load balancing weight and increasing to 100% gradually. +The easing function for the traffic increase can be adjusted by setting optional field `aggression`. +A value above 1.0 results in a more aggressive increase initially, slowing down when nearing the end of the time window. +Value below 1.0 results in slow initial increase, picking up speed when nearing the end of the time window. +Optional field `minWeightPercent` can be set to change the minimum percent of target weight. +It is used to avoid too small new weight, which may cause endpoint to receive no traffic in beginning of the slow start window. + +Slow start mode can be useful for example with JVM based applications, that might otherwise get overwhelmed during JIT warm-up period. +Such applications may respond to requests slowly or return errors immediately after pod start or after container restarts. +User impact of this behavior can be mitigated by using slow start configuration to gradually increase traffic to recently started service endpoints. + +The following example configures slow start mode for a service: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: slow-start +spec: + virtualhost: + fqdn: www.example.com + routes: + - services: + - name: java-app + port: 80 + slowStartPolicy: + window: 3s + aggression: "1.0" + minWeightPercent: 10 +``` + +Slow start mode works only with `RoundRobin` and `WeightedLeastRequest` [load balancing strategies][2]. +For more details see [Envoy documentation][1]. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/slow_start +[2]: api/#projectcontour.io/v1.LoadBalancerPolicy diff --git a/site/content/docs/1.29/config/tls-delegation.md b/site/content/docs/1.29/config/tls-delegation.md new file mode 100644 index 00000000000..155796fe7eb --- /dev/null +++ b/site/content/docs/1.29/config/tls-delegation.md @@ -0,0 +1,79 @@ +# TLS Certificate Delegation + +In order to support wildcard certificates, TLS certificates for a `*.somedomain.com`, which are stored in a namespace controlled by the cluster administrator, Contour supports a facility known as TLS Certificate Delegation. +This facility allows the owner of a TLS certificate to delegate, for the purposes of referencing the TLS certificate, permission to Contour to read the Secret object from another namespace. +Delegation works for both HTTPProxy and Ingress resources, however it needs an annotation to work with Ingress v1. + +If the `--watch-namespaces` configuration flag is used, it must define all namespaces that will be referenced by the delegation. + +The [`TLSCertificateDelegation`][1] resource defines a set of `delegations` in the `spec`. +Each delegation references a `secretName` from the namespace where the `TLSCertificateDelegation` is created as well as describing a set of `targetNamespaces` in which the certificate can be referenced. +If all namespaces should be able to reference the secret, then set `"*"` as the value of `targetNamespaces` (see example below). + +```yaml +apiVersion: projectcontour.io/v1 +kind: TLSCertificateDelegation +metadata: + name: example-com-wildcard + namespace: www-admin +spec: + delegations: + - secretName: example-com-wildcard + targetNamespaces: + - example-com + - secretName: another-com-wildcard + targetNamespaces: + - "*" +``` + +In this example, the permission for Contour to reference the Secret `example-com-wildcard` in the `www-admin` namespace has been delegated to HTTPProxy and Ingress objects in the `example-com` namespace. +Also, the permission for Contour to reference the Secret `another-com-wildcard` from all namespaces has been delegated to all HTTPProxy and Ingress objects in the cluster. + +To reference the secret from an HTTPProxy or Ingress v1beta1 you must use the slash syntax in the `secretName`: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: www + namespace: example-com +spec: + virtualhost: + fqdn: foo2.bar.com + tls: + secretName: www-admin/example-com-wildcard + routes: + - services: + - name: s1 + port: 80 +``` + +To reference the secret from an Ingress v1 you must use the `projectcontour.io/tls-cert-namespace` annotation: +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + projectcontour.io/tls-cert-namespace: www-admin + name: www + namespace: example-com +spec: + rules: + - host: foo2.bar.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: s1 + port: + number: 80 + tls: + - hosts: + - foo2.bar.com + secretName: example-com-wildcard +``` + + +[0]: https://github.com/projectcontour/contour/issues/3544 +[1]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.TLSCertificateDelegation diff --git a/site/content/docs/1.29/config/tls-termination.md b/site/content/docs/1.29/config/tls-termination.md new file mode 100644 index 00000000000..d1b26dc2f4e --- /dev/null +++ b/site/content/docs/1.29/config/tls-termination.md @@ -0,0 +1,353 @@ +# TLS Termination + +HTTPProxy follows a similar pattern to Ingress for configuring TLS credentials. + +You can secure a HTTPProxy by specifying a Secret that contains TLS private key and certificate information. +If multiple HTTPProxies utilize the same Secret, the certificate must include the necessary Subject Authority Name (SAN) for each fqdn. + +Contour (via Envoy) requires that clients send the Server Name Indication (SNI) TLS extension so that requests can be routed to the correct virtual host. +Virtual hosts are strongly bound to SNI names. +This means that the Host header in HTTP requests must match the SNI name that was sent at the start of the TLS session. + +Contour also follows a "secure first" approach. +When TLS is enabled for a virtual host, any request to the insecure port is redirected to the secure interface with a 301 redirect. +Specific routes can be configured to override this behavior and handle insecure requests by enabling the `spec.routes.permitInsecure` parameter on a Route. + +The TLS secret must: +- be a Secret of type `kubernetes.io/tls`. This means that it must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS, in PEM format. + +The TLS secret may also: +- add any chain CA certificates required for validation into the `tls.crt` PEM bundle. If this is the case, the serving certificate must be the first certificate in the bundle and the intermediate CA certificates must be appended in issuing order. + +```yaml +# ingress-tls.secret.yaml +apiVersion: v1 +data: + tls.crt: base64 encoded cert + tls.key: base64 encoded key +kind: Secret +metadata: + name: testsecret + namespace: default +type: kubernetes.io/tls +``` + +The HTTPProxy can be configured to use this secret using `tls.secretName` property: + +```yaml +# httpproxy-tls.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: tls-example + namespace: default +spec: + virtualhost: + fqdn: foo2.bar.com + tls: + secretName: testsecret + routes: + - services: + - name: s1 + port: 80 +``` + +If the `tls.secretName` property contains a slash, eg. `somenamespace/somesecret` then, subject to TLS Certificate Delegation, the TLS certificate will be read from `somesecret` in `somenamespace`. +See TLS Certificate Delegation below for more information. + +The TLS **Minimum Protocol Version** a virtual host should negotiate can be specified by setting the `spec.virtualhost.tls.minimumProtocolVersion`: + +- 1.3 +- 1.2 (Default) + +## Fallback Certificate + +Contour provides virtual host based routing, so that any TLS request is routed to the appropriate service based on both the server name requested by the TLS client and the HOST header in the HTTP request. + +Since the HOST Header is encrypted during TLS handshake, it can’t be used for virtual host based routing unless the client sends HTTPS requests specifying hostname using the TLS server name, or the request is first decrypted using a default TLS certificate. + +Some legacy TLS clients do not send the server name, so Envoy does not know how to select the right certificate. A fallback certificate is needed for these clients. + +_**Note:** +The minimum TLS protocol version for any fallback request is defined by the `minimum TLS protocol version` set in the Contour configuration file. +Enabling the fallback certificate is not compatible with TLS client authentication._ + +### Fallback Certificate Configuration + +First define the `namespace/name` in the [Contour configuration file][1] of a Kubernetes secret which will be used as the fallback certificate. +Any HTTPProxy which enables fallback certificate delegation must have the fallback certificate delegated to the namespace in which the HTTPProxy object resides. + +To do that, configure `TLSCertificateDelegation` to delegate the fallback certificate to specific or all namespaces (e.g. `*`) which should be allowed to enable the fallback certificate. +Finally, for each root HTTPProxy, set the `Spec.TLS.enableFallbackCertificate` parameter to allow that HTTPProxy to opt-in to the fallback certificate routing. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: fallback-tls-example + namespace: defaultub +spec: + virtualhost: + fqdn: fallback.bar.com + tls: + secretName: testsecret + enableFallbackCertificate: true + routes: + - services: + - name: s1 + port: 80 +--- +apiVersion: projectcontour.io/v1 +kind: TLSCertificateDelegation +metadata: + name: fallback-delegation + namespace: www-admin +spec: + delegations: + - secretName: fallback-secret-name + targetNamespaces: + - "*" +``` + +## Permitting Insecure Requests + +A HTTPProxy can be configured to permit insecure requests to specific Routes. +In this example, any request to `foo2.bar.com/blog` will not receive a 301 redirect to HTTPS, but the `/` route will: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: tls-example-insecure + namespace: default +spec: + virtualhost: + fqdn: foo2.bar.com + tls: + secretName: testsecret + routes: + - services: + - name: s1 + port: 80 + - conditions: + - prefix: /blog + permitInsecure: true + services: + - name: s2 + port: 80 +``` + +## Client Certificate Validation + +It is possible to protect the backend service from unauthorized external clients by requiring the client to present a valid TLS certificate. +Envoy will validate the client certificate by verifying that it is not expired and that a chain of trust can be established to the configured trusted root CA certificate. +Only those requests with a valid client certificate will be accepted and forwarded to the backend service. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + routes: + - services: + - name: s1 + port: 80 +``` + +The preceding example enables validation by setting the optional `clientValidation` attribute. +Its mandatory attribute `caSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have only a data key named `ca.crt`. +The data value of the key `ca.crt` must be a PEM-encoded certificate bundle and it must contain all the trusted CA certificates that are to be used for validating the client certificate. +If the Opaque Secret also contains one of either `tls.crt` or `tls.key` keys, it will be ignored. + +By default, client certificates are required but some applications might support different authentication schemes. In that case you can set the `optionalClientCertificate` field to `true`. A client certificate will be requested, but the connection is allowed to continue if the client does not provide one. If a client certificate is sent, it will be verified according to the other properties, which includes disabling validations if `skipClientCertValidation` is set. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-optional-client-auth +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + optionalClientCertificate: true + routes: + - services: + - name: s1 + port: 80 +``` + +When using external authorization, it may be desirable to use an external authorization server to validate client certificates on requests, rather than the Envoy proxy. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth-and-ext-authz +spec: + virtualhost: + fqdn: www.example.com + authorization: + # external authorization server configuration + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + skipClientCertValidation: true + routes: + - services: + - name: s1 + port: 80 +``` + +In the above example, setting the `skipClientCertValidation` field to `true` will configure Envoy to require client certificates on requests and pass them along to a configured authorization server. +Failed validation of client certificates by Envoy will be ignored and the `fail_verify_error` [Listener statistic][2] incremented. +If the `caSecret` field is omitted, Envoy will request but not require client certificates to be present on requests. + +Optionally, you can enable certificate revocation check by providing one or more Certificate Revocation Lists (CRLs). +Attribute `crlSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have a data key named `crl.pem`. +The data value of the key `crl.pem` must be one or more PEM-encoded CRLs concatenated together. +Large CRL lists are not supported since individual Secrets are limited to 1MiB in size. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth-and-crl-check +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + crlSecret: client-crl + routes: + - services: + - name: s1 + port: 80 +``` + +CRLs must be available from all relevant CAs, including intermediate CAs. +Otherwise clients will be denied access, since the revocation status cannot be checked for the full certificate chain. +This behavior can be controlled by `crlOnlyVerifyLeafCert` field. +If the option is set to `true`, only the certificate at the end of the certificate chain will be subject to validation by CRL. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth-and-crl-check-only-leaf +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + crlSecret: client-crl + crlOnlyVerifyLeafCert: true + routes: + - services: + - name: s1 + port: 80 +``` + +## Client Certificate Details Forwarding + +HTTPProxy supports passing certificate data through the `x-forwarded-client-cert` header to let applications use details from client certificates (e.g. Subject, SAN...). Since the certificate (or the certificate chain) could exceed the web server header size limit, you have the ability to select what specific part of the certificate to expose in the header through the `forwardClientCertificate` field. Read more about the supported values in the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert). + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + forwardClientCertificate: + subject: true + cert: true + chain: true + dns: true + uri: true + routes: + - services: + - name: s1 + port: 80 +``` + +## TLS Session Proxying + +HTTPProxy supports proxying of TLS encapsulated TCP sessions. + +_Note_: The TCP session must be encrypted with TLS. +This is necessary so that Envoy can use SNI to route the incoming request to the correct service. + +If `spec.virtualhost.tls.secretName` is present then that secret will be used to decrypt the TCP traffic at the edge. + +```yaml +# httpproxy-tls-termination.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example + namespace: default +spec: + virtualhost: + fqdn: tcp.example.com + tls: + secretName: secret + tcpproxy: + services: + - name: tcpservice + port: 8080 + - name: otherservice + port: 9999 + weight: 20 +``` + +The `spec.tcpproxy` key indicates that this _root_ HTTPProxy will forward the de-encrypted TCP traffic to the backend service. + +### TLS Session Passthrough + +If you wish to handle the TLS handshake at the backend service set `spec.virtualhost.tls.passthrough: true` indicates that once SNI demuxing is performed, the encrypted connection will be forwarded to the backend service. +The backend service is expected to have a key which matches the SNI header received at the edge, and be capable of completing the TLS handshake. This is called SSL/TLS Passthrough. + +```yaml +# httpproxy-tls-passthrough.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example + namespace: default +spec: + virtualhost: + fqdn: tcp.example.com + tls: + passthrough: true + tcpproxy: + services: + - name: tcpservice + port: 8080 + - name: otherservice + port: 9999 + weight: 20 +``` + +[1]: ../configuration#fallback-certificate +[2]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/stats#tls-statistics diff --git a/site/content/docs/1.29/config/tracing.md b/site/content/docs/1.29/config/tracing.md new file mode 100644 index 00000000000..5500c26d547 --- /dev/null +++ b/site/content/docs/1.29/config/tracing.md @@ -0,0 +1,117 @@ +# Tracing Support + +- [Overview](#overview) +- [Tracing-config](#tracing-config) + +## Overview + +Envoy has rich support for [distributed tracing][1],and supports exporting data to third-party providers (Zipkin, Jaeger, Datadog, etc.) + +[OpenTelemetry][2] is a CNCF project which is working to become a standard in the space. It was formed as a merger of the OpenTracing and OpenCensus projects. + +Contour supports configuring envoy to export data to OpenTelemetry, and allows users to customize some configurations. + +- Custom service name, the default is `contour`. +- Custom sampling rate, the default is `100`. +- Custom the maximum length of the request path, the default is `256`. +- Customize span tags from literal or request headers. +- Customize whether to include the pod's hostname and namespace. + +## Tracing-config + +In order to use this feature, you must first select and deploy an opentelemetry-collector to receive the tracing data exported by envoy. + +First we should deploy an opentelemetry-collector to receive the tracing data exported by envoy +```bash +# install operator +kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml +``` + +Install an otel collector instance, with verbose logging exporter enabled: +```shell +kubectl apply -f - </`. If the CA secret's namespace is not the same namespace as the `HTTPProxy` resource, [TLS Certificate Delegation][4] must be used to allow the owner of the CA certificate secret to delegate, for the purposes of referencing the CA certificate in a different namespace, permission to Contour to read the Secret object from another namespace. + +_**Note:** +If `spec.routes.services[].validation` is present, `spec.routes.services[].{name,port}` must point to a Service with a matching `projectcontour.io/upstream-protocol.tls` Service annotation._ + +In the example below, the upstream service is named `secure-backend` and uses port `8443`: + +```yaml +# httpproxy-example.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example +spec: + virtualhost: + fqdn: www.example.com + routes: + - services: + - name: secure-backend + port: 8443 + validation: + caSecret: my-certificate-authority + subjectName: backend.example.com +``` + +```yaml +# service-secure-backend.yaml +apiVersion: v1 +kind: Service +metadata: + name: secure-backend + annotations: + projectcontour.io/upstream-protocol.tls: "8443" +spec: + ports: + - name: https + port: 8443 + selector: + app: secure-backend + +``` + +If the `validation` spec is defined on a service, but the secret which it references does not exist, Contour will reject the update and set the status of the HTTPProxy object accordingly. +This helps prevent the case of proxying to an upstream where validation is requested, but not yet available. + +```yaml +Status: + Current Status: invalid + Description: route "/": service "tls-nginx": upstreamValidation requested but secret not found or misconfigured +``` + +## Upstream Validation + +When defining upstream services on a route, it's possible to configure the connection from Envoy to the backend endpoint to communicate over TLS. + +A CA certificate and a Subject Name must be provided, which are both used to verify the backend endpoint's identity. + +If specifying multiple Subject Names, `SubjectNames` and `SubjectName` must be configured such that `SubjectNames[0] == SubjectName`. + +The CA certificate bundle for the backend service should be supplied in a Kubernetes Secret. +The referenced Secret must be of type "Opaque" and have a data key named `ca.crt`. +This data value must be a PEM-encoded certificate bundle. + +In addition to the CA certificate and the subject name, the Kubernetes service must also be annotated with a Contour specific annotation: `projectcontour.io/upstream-protocol.tls: ` ([see annotations section][1]). + +_**Note:** This annotation is applied to the Service not the Ingress or HTTPProxy object._ + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: blog + namespace: marketing +spec: + routes: + - services: + - name: s2 + port: 80 + validation: + caSecret: foo-ca-cert + subjectName: foo.marketing + subjectNames: + - foo.marketing + - bar.marketing +``` + +## Envoy Client Certificate + +Contour can be configured with a `namespace/name` in the [Contour configuration file][3] of a Kubernetes secret which Envoy uses as a client certificate when upstream TLS is configured for the backend. +Envoy will send the certificate during TLS handshake when the backend applications request the client to present its certificate. +Backend applications can validate the certificate to ensure that the connection is coming from Envoy. + +[1]: annotations.md +[2]: api/#projectcontour.io/v1.Service +[3]: ../configuration#fallback-certificate +[4]: tls-delegation.md diff --git a/site/content/docs/1.29/config/virtual-hosts.md b/site/content/docs/1.29/config/virtual-hosts.md new file mode 100644 index 00000000000..b7a138dde6b --- /dev/null +++ b/site/content/docs/1.29/config/virtual-hosts.md @@ -0,0 +1,138 @@ +# Virtual Hosts + + +Similar to Ingress, HTTPProxy support name-based virtual hosting. +Name-based virtual hosts use multiple host names with the same IP address. + +``` +foo.bar.com --| |-> foo.bar.com s1:80 + | 178.91.123.132 | +bar.foo.com --| |-> bar.foo.com s2:80 +``` + +Unlike Ingress however, HTTPProxy only support a single root domain per HTTPProxy object. +As an example, this Ingress object: + +```yaml +# ingress-name.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: name-example +spec: + rules: + - host: foo1.bar.com + http: + paths: + - backend: + service: + name: s1 + port: + number: 80 + pathType: Prefix + - host: bar1.bar.com + http: + paths: + - backend: + service: + name: s2 + port: + number: 80 + pathType: Prefix +``` + +must be represented by two different HTTPProxy objects: + +```yaml +# httpproxy-name.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: name-example-foo + namespace: default +spec: + virtualhost: + fqdn: foo1.bar.com + routes: + - services: + - name: s1 + port: 80 +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: name-example-bar + namespace: default +spec: + virtualhost: + fqdn: bar1.bar.com + routes: + - services: + - name: s2 + port: 80 +``` + +A HTTPProxy object that contains a [`virtualhost`][2] field is known as a "root proxy". + +## Virtualhost aliases + +To present the same set of routes under multiple DNS entries (e.g. `www.example.com` and `example.com`), including a service with a `prefix` condition of `/` can be used. + +```yaml +# httpproxy-inclusion-multipleroots.yaml +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-root + namespace: default +spec: + virtualhost: + fqdn: bar.com + includes: + - name: main + namespace: default +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-root-www + namespace: default +spec: + virtualhost: + fqdn: www.bar.com + includes: + - name: main + namespace: default +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: main + namespace: default +spec: + routes: + - services: + - name: s2 + port: 80 +``` + +## Restricted root namespaces + +HTTPProxy inclusion allows Administrators to limit which users/namespaces may configure routes for a given domain, but it does not restrict where root HTTPProxies may be created. +Contour has an enforcing mode which accepts a list of namespaces where root HTTPProxy are valid. +Only users permitted to operate in those namespaces can therefore create HTTPProxy with the [`virtualhost`] field ([see API docs][2]). + +This restricted mode is enabled in Contour by specifying a command line flag, `--root-namespaces`, which will restrict Contour to only searching the defined namespaces for root HTTPProxy. This CLI flag accepts a comma separated list of namespaces where HTTPProxy are valid (e.g. `--root-namespaces=default,kube-system,my-admin-namespace`). + +HTTPProxy with a defined [virtualhost][2] field that are not in one of the allowed root namespaces will be flagged as `invalid` and will be ignored by Contour. + +Additionally, when defined, Contour will only watch for Kubernetes secrets in these namespaces ignoring changes in all other namespaces. +Proper RBAC rules should also be created to restrict what namespaces Contour has access matching the namespaces passed to the command line flag. +An example of this is included in the [examples directory][1] and shows how you might create a namespace called `root-httproxy`. + +_**Note:** The restricted root namespace feature is only supported for HTTPProxy CRDs. +`--root-namespaces` does not affect the operation of Ingress objects. In order to limit other resources, see the `--watch-namespaces` configuration flag._ + +[1]: {{< param github_url>}}/tree/{{< param branch >}}/examples/root-rbac +[2]: api/#projectcontour.io/v1.VirtualHost diff --git a/site/content/docs/1.29/config/websockets.md b/site/content/docs/1.29/config/websockets.md new file mode 100644 index 00000000000..136c0468378 --- /dev/null +++ b/site/content/docs/1.29/config/websockets.md @@ -0,0 +1,27 @@ +# Websockets + +WebSocket support can be enabled on specific routes using the `enableWebsockets` field: + +```yaml +# httpproxy-websockets.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: chat + namespace: default +spec: + virtualhost: + fqdn: chat.example.com + routes: + - services: + - name: chat-app + port: 80 + - conditions: + - prefix: /websocket + enableWebsockets: true # Setting this to true enables websocket for all paths that match /websocket + services: + - name: chat-app + port: 80 +``` + +If you are using Gateway API, websockets are enabled by default at the Listener level. diff --git a/site/content/docs/1.29/configuration.md b/site/content/docs/1.29/configuration.md new file mode 100644 index 00000000000..8e20de93fe5 --- /dev/null +++ b/site/content/docs/1.29/configuration.md @@ -0,0 +1,541 @@ +# Contour Configuration Reference + +- [Serve Flags](#serve-flags) +- [Configuration File](#configuration-file) +- [Environment Variables](#environment-variables) +- [Bootstrap Config File](#bootstrap-config-file) + +## Overview + +There are various ways to configure Contour, flags, the configuration file, as well as environment variables. +Contour has a precedence of configuration for contour serve, meaning anything configured in the config file is overridden by environment vars which are overridden by cli flags. + +## Serve Flags + +The `contour serve` command is the main command which is used to watch for Kubernetes resource and process them into Envoy configuration which is then streamed to any Envoy via its xDS gRPC connection. +There are a number of flags that can be passed to this command which further configures how Contour operates. +Many of these flags are mirrored in the [Contour Configuration File](#configuration-file). + +| Flag Name | Description | +| --------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| `--config-path` | Path to base configuration | +| `--contour-config-name` | Name of the ContourConfiguration resource to use | +| `--incluster` | Use in cluster configuration | +| `--kubeconfig=` | Path to kubeconfig (if not in running inside a cluster) | +| `--xds-address=` | xDS gRPC API address | +| `--xds-port=` | xDS gRPC API port | +| `--stats-address=` | Envoy /stats interface address | +| `--stats-port=` | Envoy /stats interface port | +| `--debug-http-address=
` | Address the debug http endpoint will bind to. | +| `--debug-http-port=` | Port the debug http endpoint will bind to | +| `--http-address=` | Address the metrics HTTP endpoint will bind to | +| `--http-port=` | Port the metrics HTTP endpoint will bind to. | +| `--health-address=` | Address the health HTTP endpoint will bind to | +| `--health-port=` | Port the health HTTP endpoint will bind to | +| `--contour-cafile=` | CA bundle file name for serving gRPC with TLS | +| `--contour-cert-file=` | Contour certificate file name for serving gRPC over TLS | +| `--contour-key-file=` | Contour key file name for serving gRPC over TLS | +| `--insecure` | Allow serving without TLS secured gRPC | +| `--root-namespaces=` | Restrict contour to searching these namespaces for root ingress routes | +| `--watch-namespaces=` | Restrict contour to searching these namespaces for all resources | +| `--ingress-class-name=` | Contour IngressClass name (comma-separated list allowed) | +| `--ingress-status-address=
` | Address to set in Ingress object status | +| `--envoy-http-access-log=` | Envoy HTTP access log | +| `--envoy-https-access-log=` | Envoy HTTPS access log | +| `--envoy-service-http-address=` | Kubernetes Service address for HTTP requests | +| `--envoy-service-https-address=` | Kubernetes Service address for HTTPS requests | +| `--envoy-service-http-port=` | Kubernetes Service port for HTTP requests | +| `--envoy-service-https-port=` | Kubernetes Service port for HTTPS requests | +| `--envoy-service-name=` | Name of the Envoy service to inspect for Ingress status details. | +| `--envoy-service-namespace=` | Envoy Service Namespace | +| `--use-proxy-protocol` | Use PROXY protocol for all listeners | +| `--accesslog-format=` | Format for Envoy access logs | +| `--disable-leader-election` | Disable leader election mechanism | +| `--disable-feature=` | Do not start an informer for the specified resources. Flag can be given multiple times. | +| `--leader-election-lease-duration` | The duration of the leadership lease. | +| `--leader-election-renew-deadline` | The duration leader will retry refreshing leadership before giving up. | +| `--leader-election-retry-period` | The interval which Contour will attempt to acquire leadership lease. | +| `--leader-election-resource-name` | The name of the resource (Lease) leader election will lease. | +| `--leader-election-resource-namespace` | The namespace of the resource (Lease) leader election will lease. | +| `-d, --debug` | Enable debug logging | +| `--kubernetes-debug=` | Enable Kubernetes client debug logging | +| `--log-format=` | Log output format for Contour. Either text (default) or json. | +| `--kubernetes-client-qps=` | QPS allowed for the Kubernetes client. | +| `--kubernetes-client-burst=` | Burst allowed for the Kubernetes client. | + +## Configuration File + +A configuration file can be passed to the `--config-path` argument of the `contour serve` command to specify additional configuration to Contour. +In most deployments, this file is passed to Contour via a ConfigMap which is mounted as a volume to the Contour pod. + +The Contour configuration file is optional. +In its absence, Contour will operate with reasonable defaults. +Where Contour settings can also be specified with command-line flags, the command-line value takes precedence over the configuration file. + +| Field Name | Type | Default | Description | +|---------------------------| ---------------------- |------------------------------------------------------------------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. | +| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` | +| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. | +| debug | boolean | `false` | Enables debug logging. | +| default-http-versions | string array | HTTP/1.1
HTTP/2 | This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. | +| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. +| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. +| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` +| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. | +| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. | +| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. | +| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. | +| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. | +| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. | +| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. | +| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. | +| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. | +| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). | +| tls | TLS | | The default [TLS configuration](#tls-configuration). | +| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). | +| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). | +| network | NetworkConfig | | The [network configuration](#network-configuration). | +| listener | ListenerConfig | | The [listener configuration](#listener-configuration). | +| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. | +| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). | +| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). | +| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. | +| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) | +| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are:
1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. | + +### TLS Configuration + +The TLS configuration block can be used to configure default values for how +Contour should provision TLS hosts. + +| Field Name | Type | Default | Description | +| ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| minimum-protocol-version | string | `1.2` | This field specifies the minimum TLS protocol version that is allowed. Valid options are `1.2` (default) and `1.3`. Any other value defaults to TLS 1.2. +| maximum-protocol-version | string | `1.3` | This field specifies the maximum TLS protocol version that is allowed. Valid options are `1.2` and `1.3`. Any other value defaults to TLS 1.3. | +| fallback-certificate | | | [Fallback certificate configuration](#fallback-certificate). | +| envoy-client-certificate | | | [Client certificate configuration for Envoy](#envoy-client-certificate). | +| cipher-suites | []string | See [config package documentation](https://pkg.go.dev/github.com/projectcontour/contour/pkg/config#pkg-variables) | This field specifies the TLS ciphers to be supported by TLS listeners when negotiating TLS 1.2. This parameter should only be used by advanced users. Note that this is ignored when TLS 1.3 is in use. The set of ciphers that are allowed is a superset of those supported by default in stock, non-FIPS Envoy builds and FIPS builds as specified [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlsparameters-cipher-suites). Custom ciphers not accepted by Envoy in a standard build are not supported. | + +### Upstream TLS Configuration + +The Upstream TLS configuration block can be used to configure default values for how Contour establishes TLS for upstream connections. + +| Field Name | Type | Default | Description | +| ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| minimum-protocol-version | string | `1.2` | This field specifies the minimum TLS protocol version that is allowed. Valid options are `1.2` (default) and `1.3`. Any other value defaults to TLS 1.2. | +| maximum-protocol-version | string | `1.3` | This field specifies the maximum TLS protocol version that is allowed. Valid options are `1.2` and `1.3`. Any other value defaults to TLS 1.3. | +| cipher-suites | []string | See [config package documentation](https://pkg.go.dev/github.com/projectcontour/contour/pkg/config#pkg-variables) | This field specifies the TLS ciphers to be supported by TLS listeners when negotiating TLS 1.2. This parameter should only be used by advanced users. Note that this is ignored when TLS 1.3 is in use. The set of ciphers that are allowed is a superset of those supported by default in stock, non-FIPS Envoy builds and FIPS builds as specified [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlsparameters-cipher-suites). Custom ciphers not accepted by Envoy in a standard build are not supported. | + +### Fallback Certificate + +| Field Name | Type | Default | Description | +| ---------- | ------ | ------- | ----------------------------------------------------------------------------------------------- | +| name | string | `""` | This field specifies the name of the Kubernetes secret to use as the fallback certificate. | +| namespace | string | `""` | This field specifies the namespace of the Kubernetes secret to use as the fallback certificate. | + + +### Envoy Client Certificate + +| Field Name | Type | Default | Description | +| ---------- | ------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| name | string | `""` | This field specifies the name of the Kubernetes secret to use as the client certificate and private key when establishing TLS connections to the backend service. | +| namespace | string | `""` | This field specifies the namespace of the Kubernetes secret to use as the client certificate and private key when establishing TLS connections to the backend service. | + + +### Timeout Configuration + +The timeout configuration block can be used to configure various timeouts for the proxies. All fields are optional; Contour/Envoy defaults apply if a field is not specified. + +| Field Name | Type | Default | Description | +| -------------------------------- | ------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| request-timeout | string | none* | This field specifies the default request timeout. Note that this is a timeout for the entire request, not an idle timeout. Must be a [valid Go duration string][4], or omitted or set to `infinity` to disable the timeout entirely. See [the Envoy documentation][12] for more information.

_Note: A value of `0s` previously disabled this timeout entirely. This is no longer the case. Use `infinity` or omit this field to disable the timeout._ | +| connection-idle-timeout | string | `60s` | This field defines how long the proxy should wait while there are no active requests (for HTTP/1.1) or streams (for HTTP/2) before terminating an HTTP connection. The timeout applies to downstream connections only. Must be a [valid Go duration string][4], or `infinity` to disable the timeout entirely. See [the Envoy documentation][8] for more information. | +| stream-idle-timeout | string | `5m`* | This field defines how long the proxy should wait while there is no activity during single request/response (for HTTP/1.1) or stream (for HTTP/2). Timeout will not trigger while HTTP/1.1 connection is idle between two consecutive requests. Must be a [valid Go duration string][4], or `infinity` to disable the timeout entirely. See [the Envoy documentation][9] for more information. | +| max-connection-duration | string | none* | This field defines the maximum period of time after an HTTP connection has been established from the client to the proxy before it is closed by the proxy, regardless of whether there has been activity or not. Must be a [valid Go duration string][4], or omitted or set to `infinity` for no max duration. See [the Envoy documentation][10] for more information. | +| delayed-close-timeout | string | `1s`* | *Note: this is an advanced setting that should not normally need to be tuned.*

This field defines how long envoy will wait, once connection close processing has been initiated, for the downstream peer to close the connection before Envoy closes the socket associated with the connection. Setting this timeout to 'infinity' will disable it. See [the Envoy documentation][13] for more information. | +| connection-shutdown-grace-period | string | `5s`* | This field defines how long the proxy will wait between sending an initial GOAWAY frame and a second, final GOAWAY frame when terminating an HTTP/2 connection. During this grace period, the proxy will continue to respond to new streams. After the final GOAWAY frame has been sent, the proxy will refuse new streams. Must be a [valid Go duration string][4]. See [the Envoy documentation][11] for more information. | +| connect-timeout | string | `2s` | This field defines how long the proxy will wait for the upstream connection to be established. + +_This is Envoy's default setting value and is not explicitly configured by Contour._ + +### Cluster Configuration + +The cluster configuration block can be used to configure various parameters for Envoy clusters. + +| Field Name | Type | Default | Description | +|-----------------------------------|--------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| dns-lookup-family | string | auto | This field specifies the dns-lookup-family to use for upstream requests to externalName type Kubernetes services from an HTTPProxy route. Values are: `auto`, `v4`, `v6`, `all` | +| max-requests-per-connection | int | none | This field specifies the maximum requests for upstream connections. If not specified, there is no limit | +| circuit-breakers | [CircuitBreakers](#circuit-breakers) | none | This field specifies the default value for [circuit-breaker-annotations](https://projectcontour.io/docs/main/config/annotations/) for services that don't specify them. | +| per-connection-buffer-limit-bytes | int | 1MiB* | This field specifies the soft limit on size of the cluster’s new connection read and write buffer. If not specified, Envoy defaults of 1MiB apply | +| upstream-tls | UpstreamTLS | | [Upstream TLS configuration](#upstream-tls) | + +_This is Envoy's default setting value and is not explicitly configured by Contour._ + + + + +### Network Configuration + +The network configuration block can be used to configure various parameters network connections. + +| Field Name | Type | Default | Description | +| ---------------- | ---- | ------- | ----------------------------------------------------------------------------------------------------------------------- | +| num-trusted-hops | int | 0 | Configures the number of additional ingress proxy hops from the right side of the x-forwarded-for HTTP header to trust. | +| admin-port | int | 9001 | Configures the Envoy Admin read-only listener on Envoy. Set to `0` to disable. | + +### Listener Configuration + +The listener configuration block can be used to configure various parameters for Envoy listener. + +| Field Name | Type | Default | Description | +|-----------------------------------|--------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| connection-balancer | string | `""` | This field specifies the listener connection balancer. If the value is `exact`, the listener will use the exact connection balancer to balance connections between threads in a single Envoy process. See [the Envoy documentation][14] for more information. | +| max-requests-per-connection | int | none | This field specifies the maximum requests for downstream connections. If not specified, there is no limit | +| per-connection-buffer-limit-bytes | int | 1MiB* | This field specifies the soft limit on size of the listener’s new connection read and write buffer. If not specified, Envoy defaults of 1MiB apply | +| socket-options | SocketOptions | | The [Socket Options](#socket-options) for Envoy listeners. | +| max-requests-per-io-cycle | int | none | Defines the limit on number of HTTP requests that Envoy will process from a single connection in a single I/O cycle. Requests over this limit are processed in subsequent I/O cycles. Can be used as a mitigation for CVE-2023-44487 when abusive traffic is detected. Configures the `http.max_requests_per_io_cycle` Envoy runtime setting. The default value when this is not set is no limit. | +| http2-max-concurrent-streams | int | none | Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS Envoy will advertise in the SETTINGS frame in HTTP/2 connections and the limit for concurrent streams allowed for a peer on a single HTTP/2 connection. It is recommended to not set this lower than 100 but this field can be used to bound resource usage by HTTP/2 connections and mitigate attacks like CVE-2023-44487. The default value when this is not set is unlimited. | + +_This is Envoy's default setting value and is not explicitly configured by Contour._ + +### Server Configuration + +The server configuration block can be used to configure various settings for the `contour serve` command. + +| Field Name | Type | Default | Description | +| --------------- | ------ | ------- | ----------------------------------------------------------------------------- | +| xds-server-type | string | envoy | This field specifies the xDS Server to use. Options are `envoy` or `contour` (deprecated). | + +### Gateway Configuration + +The gateway configuration block is used to configure which gateway-api Gateway Contour should configure: + +| Field Name | Type | Default | Description | +| -------------- | -------------- | ------- | ------------------------------------------------------------------------------ | +| gatewayRef | NamespacedName | | [Gateway namespace and name](#gateway-ref). | + +### Gateway Ref + +| Field Name | Type | Default | Description | +| ---------- | ------ | ------- | ----------------------------------------------------------------------------------------------- | +| name | string | `""` | This field specifies the name of the specific Gateway to reconcile. | +| namespace | string | `""` | This field specifies the namespace of the specific Gateway to reconcile. | + +### Policy Configuration + +The Policy configuration block can be used to configure default policy values +that are set if not overridden by the user. + +The `request-headers` field is used to rewrite headers on a HTTP request, and +the `response-headers` field is used to rewrite headers on a HTTP response. + +| Field Name | Type | Default | Description | +| ---------------- | ------------ | ------- | ------------------------------------------------------------------------------------------------- | +| request-headers | HeaderPolicy | none | The default request headers set or removed on all service routes if not overridden in the object | +| response-headers | HeaderPolicy | none | The default response headers set or removed on all service routes if not overridden in the object | +| applyToIngress | Boolean | false | Whether the global policy should apply to Ingress objects | + +#### HeaderPolicy + +The `set` field sets an HTTP header value, creating it if it doesn't already exist but not overwriting it if it does. +The `remove` field removes an HTTP header. + +| Field Name | Type | Default | Description | +| ---------- | ----------------- | ------- | ------------------------------------------------------------------------------- | +| set | map[string]string | none | Map of headers to set on all service routes if not overridden in the object | +| remove | []string | none | List of headers to remove on all service routes if not overridden in the object | + +Note: the values of entries in the `set` and `remove` fields can be overridden in HTTPProxy objects but it is not possible to remove these entries. + +### Rate Limit Service Configuration + +The rate limit service configuration block is used to configure an optional global rate limit service: + +| Field Name | Type | Default | Description | +|-----------------------------| ------ | ------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| extensionService | string | | This field identifies the extension service defining the rate limit service, formatted as /. | +| domain | string | contour | This field defines the rate limit domain value to pass to the rate limit service. Acts as a container for a set of rate limit definitions within the RLS. | +| failOpen | bool | false | This field defines whether to allow requests to proceed when the rate limit service fails to respond with a valid rate limit decision within the timeout defined on the extension service. | +| enableXRateLimitHeaders | bool | false | This field defines whether to include the X-RateLimit headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (as defined by the IETF Internet-Draft https://tools.ietf.org/id/draft-polli-ratelimit-headers-03.html), on responses to clients when the Rate Limit Service is consulted for a request. | +| enableResourceExhaustedCode | bool | false | This field defines whether to translate status code 429 to gRPC RESOURCE_EXHAUSTED instead of UNAVAILABLE. | + +### Metrics Configuration + +MetricsParameters holds configurable parameters for Contour and Envoy metrics. + +| Field Name | Type | Default | Description | +| ----------- | ----------------------- | ------- | -------------------------------------------------------------------- | +| contour | MetricsServerParameters | | [Metrics Server Parameters](#metrics-server-parameters) for Contour. | +| envoy | MetricsServerParameters | | [Metrics Server Parameters](#metrics-server-parameters) for Envoy. | + +### Metrics Server Parameters + +MetricsServerParameters holds configurable parameters for Contour and Envoy metrics. +Metrics are served over HTTPS if `server-certificate-path` and `server-key-path` are set. +Metrics and health endpoints cannot have the same port number when metrics are served over HTTPS. + +| Field Name | Type | Default | Description | +| ----------------------- | ------ | ---------------------------- | -----------------------------------------------------------------------------| +| address | string | 0.0.0.0 | Address that metrics server will bind to. | +| port | int | 8000 (Contour), 8002 (Envoy) | Port that metrics server will bind to. | +| server-certificate-path | string | none | Optional path to the server certificate file. | +| server-key-path | string | none | Optional path to the server private key file. | +| ca-certificate-path | string | none | Optional path to the CA certificate file used to verify client certificates. | + +### Socket Options + +| Field Name | Type | Default | Description | +| --------------- | ------ | ------- | ----------------------------------------------------------------------------- | +| tos | int | 0 | Defines the value for IPv4 TOS field (including 6 bit DSCP field) for IP packets originating from Envoy listeners. Single value is applied to all listeners. The value must be in the range 0-255, 0 means socket option is not set. If listeners are bound to IPv6-only addresses, setting this option will cause an error. | +| traffic-class | int | 0 | Defines the value for IPv6 Traffic Class field (including 6 bit DSCP field) for IP packets originating from the Envoy listeners. Single value is applied to all listeners. The value must be in the range 0-255, 0 means socket option is not set. If listeners are bound to IPv4-only addresses, setting this option will cause an error. | + + +### Circuit Breakers + +| Field Name | Type | Default | Description | +| --------------- | ------ | ------- | ----------------------------------------------------------------------------- | +| max-connections | int | 0 | The maximum number of connections that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. | +| max-pending-requests | int | 0 | The maximum number of pending requests that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. | +| max-requests | int | 0 | The maximum parallel requests a single Envoy instance allows to the Kubernetes Service; defaults to 1024 | +| max-retries | int | 0 | The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3. This setting only makes sense if the cluster is configured to do retries.| + +### Configuration Example + +The following is an example ConfigMap with configuration file included: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: contour + namespace: projectcontour +data: + contour.yaml: | + # + # server: + # determine which XDS Server implementation to utilize in Contour. + # xds-server-type: envoy + # + # specify the gateway-api Gateway Contour should configure + # gateway: + # namespace: projectcontour + # name: contour + # + # should contour expect to be running inside a k8s cluster + # incluster: true + # + # path to kubeconfig (if not running inside a k8s cluster) + # kubeconfig: /path/to/.kube/config + # + # Disable RFC-compliant behavior to strip "Content-Length" header if + # "Tranfer-Encoding: chunked" is also set. + # disableAllowChunkedLength: false + # Disable HTTPProxy permitInsecure field + disablePermitInsecure: false + tls: + # minimum TLS version that Contour will negotiate + # minimum-protocol-version: "1.2" + # TLS ciphers to be supported by Envoy TLS listeners when negotiating + # TLS 1.2. + # cipher-suites: + # - '[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' + # Defines the Kubernetes name/namespace matching a secret to use + # as the fallback certificate when requests which don't match the + # SNI defined for a vhost. + fallback-certificate: + # name: fallback-secret-name + # namespace: projectcontour + envoy-client-certificate: + # name: envoy-client-cert-secret-name + # namespace: projectcontour + ### Logging options + # Default setting + accesslog-format: envoy + # The default access log format is defined by Envoy but it can be customized by setting following variable. + # accesslog-format-string: "...\n" + # To enable JSON logging in Envoy + # accesslog-format: json + # accesslog-level: info + # The default fields that will be logged are specified below. + # To customise this list, just add or remove entries. + # The canonical list is available at + # https://godoc.org/github.com/projectcontour/contour/internal/envoy#JSONFields + # json-fields: + # - "@timestamp" + # - "authority" + # - "bytes_received" + # - "bytes_sent" + # - "downstream_local_address" + # - "downstream_remote_address" + # - "duration" + # - "method" + # - "path" + # - "protocol" + # - "request_id" + # - "requested_server_name" + # - "response_code" + # - "response_flags" + # - "uber_trace_id" + # - "upstream_cluster" + # - "upstream_host" + # - "upstream_local_address" + # - "upstream_service_time" + # - "user_agent" + # - "x_forwarded_for" + # + # default-http-versions: + # - "HTTP/2" + # - "HTTP/1.1" + # + # The following shows the default proxy timeout settings. + # timeouts: + # request-timeout: infinity + # connection-idle-timeout: 60s + # stream-idle-timeout: 5m + # max-connection-duration: infinity + # connection-shutdown-grace-period: 5s + # + # Envoy cluster settings. + # cluster: + # configure the cluster dns lookup family + # valid options are: auto (default), v4, v6, all + # dns-lookup-family: auto + # the maximum requests for upstream connections. + # If not specified, there is no limit. + # Setting this parameter to 1 will effectively disable keep alive + # max-requests-per-connection: 0 + # the soft limit on size of the cluster’s new connection read and write buffers + # per-connection-buffer-limit-bytes: 32768 + # + # network: + # Configure the number of additional ingress proxy hops from the + # right side of the x-forwarded-for HTTP header to trust. + # num-trusted-hops: 0 + # Configure the port used to access the Envoy Admin interface. + # admin-port: 9001 + # + # Configure an optional global rate limit service. + # rateLimitService: + # Identifies the extension service defining the rate limit service, + # formatted as /. + # extensionService: projectcontour/ratelimit + # Defines the rate limit domain to pass to the rate limit service. + # Acts as a container for a set of rate limit definitions within + # the RLS. + # domain: contour + # Defines whether to allow requests to proceed when the rate limit + # service fails to respond with a valid rate limit decision within + # the timeout defined on the extension service. + # failOpen: false + # Defines whether to include the X-RateLimit headers X-RateLimit-Limit, + # X-RateLimit-Remaining, and X-RateLimit-Reset (as defined by the IETF + # Internet-Draft linked below), on responses to clients when the Rate + # Limit Service is consulted for a request. + # ref. https://tools.ietf.org/id/draft-polli-ratelimit-headers-03.html + # enableXRateLimitHeaders: false + # Defines whether to translate status code 429 to grpc code RESOURCE_EXHAUSTED + # instead of the default UNAVAILABLE + # enableResourceExhaustedCode: false + # + # Global Policy settings. + # policy: + # # Default headers to set on all requests (unless set/removed on the HTTPProxy object itself) + # request-headers: + # set: + # # example: the hostname of the Envoy instance that proxied the request + # X-Envoy-Hostname: %HOSTNAME% + # # example: add a l5d-dst-override header to instruct Linkerd what service the request is destined for + # l5d-dst-override: %CONTOUR_SERVICE_NAME%.%CONTOUR_NAMESPACE%.svc.cluster.local:%CONTOUR_SERVICE_PORT% + # # default headers to set on all responses (unless set/removed on the HTTPProxy object itself) + # response-headers: + # set: + # # example: Envoy flags that provide additional details about the response or connection + # X-Envoy-Response-Flags: %RESPONSE_FLAGS% + # Whether or not the policy settings should apply to ingress objects + # applyToIngress: true + # + # metrics: + # contour: + # address: 0.0.0.0 + # port: 8000 + # server-certificate-path: /path/to/server-cert.pem + # server-key-path: /path/to/server-private-key.pem + # ca-certificate-path: /path/to/root-ca-for-client-validation.pem + # envoy: + # address: 0.0.0.0 + # port: 8002 + # server-certificate-path: /path/to/server-cert.pem + # server-key-path: /path/to/server-private-key.pem + # ca-certificate-path: /path/to/root-ca-for-client-validation.pem + # + # listener: + # connection-balancer: exact + # socket-options: + # tos: 64 + # traffic-class: 64 +``` + +_Note:_ The default example `contour` includes this [file][1] for easy deployment of Contour. + +## Environment Variables + +### CONTOUR_NAMESPACE + +If present, the value of the `CONTOUR_NAMESPACE` environment variable is used as: + +1. The value for the `contour bootstrap --namespace` flag unless otherwise specified. +1. The value for the `contour certgen --namespace` flag unless otherwise specified. +1. The value for the `contour serve --envoy-service-namespace` flag unless otherwise specified. +1. The value for the `contour serve --leader-election-resource-namespace` flag unless otherwise specified. + +The `CONTOUR_NAMESPACE` environment variable is set via the [Downward API][6] in the Contour [example manifests][7]. + +## Bootstrap Config File + +The bootstrap configuration file is generated by an initContainer in the Envoy daemonset which runs the `contour bootstrap` command to generate the file. +This configuration file configures the Envoy container to connect to Contour and receive configuration via xDS. + +The next section outlines all the available flags that can be passed to the `contour bootstrap` command which are used to customize +the configuration file to match the environment in which Envoy is deployed. + +### Bootstrap Flags + +There are flags that can be passed to `contour bootstrap` that help configure how Envoy +connects to Contour: + +| Flag | Default | Description | +| -------------------------------------- |-------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| --resources-dir | "" | Directory where resource files will be written. | +| --admin-address | /admin/admin.sock | Path to Envoy admin unix domain socket. | +| --admin-port (Deprecated) | 9001 | Deprecated: Port is now configured as a Contour flag. | +| --xds-address | 127.0.0.1 | Address to connect to Contour xDS server on. | +| --xds-port | 8001 | Port to connect to Contour xDS server on. | +| --envoy-cafile | "" | CA filename for Envoy secure xDS gRPC communication. | +| --envoy-cert-file | "" | Client certificate filename for Envoy secure xDS gRPC communication. | +| --envoy-key-file | "" | Client key filename for Envoy secure xDS gRPC communication. | +| --namespace | projectcontour | Namespace the Envoy container will run, also configured via ENV variable "CONTOUR_NAMESPACE". Namespace is used as part of the metric names on static resources defined in the bootstrap configuration file. | +| --xds-resource-version | v3 | Currently, the only valid xDS API resource version is `v3`. | +| --dns-lookup-family | auto | Defines what DNS Resolution Policy to use for Envoy -> Contour cluster name lookup. Either v4, v6, auto or all. | +| --log-format | text | Log output format for Contour. Either text or json. | +| --overload-max-heap | 0 | Defines the maximum heap memory of the envoy controlled by the overload manager. When the value is greater than 0, the overload manager is enabled, and when envoy reaches 95% of the maximum heap size, it performs a shrink heap operation. When it reaches 98% of the maximum heap size, Envoy Will stop accepting requests. | + + +[1]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour/01-contour-config.yaml +[2]: config/access-logging +[3]: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/ +[4]: https://golang.org/pkg/time/#ParseDuration +[5]: https://godoc.org/github.com/projectcontour/contour/internal/envoy#DefaultFields +[6]: https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/ +[7]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout +[9]: 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-stream-idle-timeout +[10]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-max-connection-duration +[11]: 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-drain-timeout +[12]: 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-request-timeout +[13]: 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-delayed-close-timeout +[14]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener-connectionbalanceconfig diff --git a/site/content/docs/1.29/deploy-options.md b/site/content/docs/1.29/deploy-options.md new file mode 100644 index 00000000000..0ae74a53bd9 --- /dev/null +++ b/site/content/docs/1.29/deploy-options.md @@ -0,0 +1,383 @@ +# Deployment Options + +The [Getting Started][8] guide shows you a simple way to get started with Contour on your cluster. +This topic explains the details and shows you additional options. +Most of this covers running Contour using a Kubernetes Service of `Type: LoadBalancer`. +If you don't have a cluster with that capability see the [Running without a Kubernetes LoadBalancer][1] section. + +## Installation + +Contour requires a secret containing TLS certificates that are used to secure the gRPC communication between Contour<>Envoy. +This secret can be auto-generated by the Contour `certgen` job or provided by an administrator. +Traffic must be forwarded to Envoy, typically via a Service of `type: LoadBalancer`. +All other requirements such as RBAC permissions, configuration details, are provided or have good defaults for most installations. + +### Setting resource requests and limits + +It is recommended that resource requests and limits be set on all Contour and Envoy containers. +The example YAML manifests used in the [Getting Started][8] guide do not include these, because the appropriate values can vary widely from user to user. +The table below summarizes the Contour and Envoy containers, and provides some reasonable resource requests to start with (note that these should be adjusted based on observed usage and expected load): + +| Workload | Container | Request (mem) | Request (cpu) | +| ------------------- | ---------------- | ------------- | ------------- | +| deployment/contour | contour | 128Mi | 250m | +| daemonset/envoy | envoy | 256Mi | 500m | +| daemonset/envoy | shutdown-manager | 50Mi | 25m | + + +### Envoy as Daemonset + +The recommended installation is for Contour to run as a Deployment and Envoy to run as a Daemonset. +The example Damonset places a single instance of Envoy per node in the cluster as well as attaches to `hostPorts` on each node. +This model allows for simple scaling of Envoy instances as well as ensuring even distribution of instances across the cluster. + +The [example daemonset manifest][2] or [Contour Gateway Provisioner][12] will create an installation based on these recommendations. + +_Note: If the size of the cluster is scaled down, connections can be lost since Kubernetes Damonsets do not follow proper `preStop` hooks._ + +### Envoy as Deployment + +An alternative Envoy deployment model is utilizing a Kubernetes Deployment with a configured `podAntiAffinity` which attempts to mirror the Daemonset deployment model. +A benefit of this model compared to the Daemonset version is when a node is removed from the cluster, the proper shutdown events are available so connections can be cleanly drained from Envoy before terminating. + +The [example deployment manifest][14] will create an installation based on these recommendations. + +## Testing your installation + +### Get your hostname or IP address + +To retrieve the IP address or DNS name assigned to your Contour deployment, run: + +```bash +$ kubectl get -n projectcontour service envoy -o wide +``` + +On AWS, for example, the response looks like: + +``` +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR +contour 10.106.53.14 a47761ccbb9ce11e7b27f023b7e83d33-2036788482.ap-southeast-2.elb.amazonaws.com 80:30274/TCP 3h app=contour +``` + +Depending on your cloud provider, the `EXTERNAL-IP` value is an IP address, or, in the case of Amazon AWS, the DNS name of the ELB created for Contour. Keep a record of this value. + +Note that if you are running an Elastic Load Balancer (ELB) on AWS, you must add more details to your configuration to get the remote address of your incoming connections. +See the [instructions for enabling the PROXY protocol.][4] + +#### Minikube + +On Minikube, to get the IP address of the Contour service run: + +```bash +$ minikube service -n projectcontour envoy --url +``` + +The response is always an IP address, for example `http://192.168.99.100:30588`. This is used as CONTOUR_IP in the rest of the documentation. + +#### kind + +When creating the cluster on Kind, pass a custom configuration to allow Kind to expose port 80/443 to your local host: + +```yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: worker + extraPortMappings: + - containerPort: 80 + hostPort: 80 + listenAddress: "0.0.0.0" + - containerPort: 443 + hostPort: 443 + listenAddress: "0.0.0.0" +``` + +Then run the create cluster command passing the config file as a parameter. +This file is in the `examples/kind` directory: + +```bash +$ kind create cluster --config examples/kind/kind-expose-port.yaml +``` + +Then, your CONTOUR_IP (as used below) will just be `localhost:80`. + +_Note: We've created a public DNS record (`local.projectcontour.io`) which is configured to resolve to `127.0.0.1``. This allows you to use a real domain name in your kind cluster._ + +### Test with Ingress + +The Contour repository contains an example deployment of the Kubernetes Up and Running demo application, [kuard][5]. +To test your Contour deployment, deploy `kuard` with the following command: + +```bash +$ kubectl apply -f https://projectcontour.io/examples/kuard.yaml +``` + +Then monitor the progress of the deployment with: + +```bash +$ kubectl get po,svc,ing -l app=kuard +``` + +You should see something like: + +``` +NAME READY STATUS RESTARTS AGE +po/kuard-370091993-ps2gf 1/1 Running 0 4m +po/kuard-370091993-r63cm 1/1 Running 0 4m +po/kuard-370091993-t4dqk 1/1 Running 0 4m + +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc/kuard 10.110.67.121 80/TCP 4m + +NAME HOSTS ADDRESS PORTS AGE +ing/kuard * 10.0.0.47 80 4m +``` + +... showing that there are three Pods, one Service, and one Ingress that is bound to all virtual hosts (`*`). + +In your browser, navigate your browser to the IP or DNS address of the Contour Service to interact with the demo application. + +### Test with HTTPProxy + +To test your Contour deployment with [HTTPProxy][9], run the following command: + +```sh +$ kubectl apply -f https://projectcontour.io/examples/kuard-httpproxy.yaml +``` + +Then monitor the progress of the deployment with: + +```sh +$ kubectl get po,svc,httpproxy -l app=kuard +``` + +You should see something like: + +```sh +NAME READY STATUS RESTARTS AGE +pod/kuard-bcc7bf7df-9hj8d 1/1 Running 0 1h +pod/kuard-bcc7bf7df-bkbr5 1/1 Running 0 1h +pod/kuard-bcc7bf7df-vkbtl 1/1 Running 0 1h + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/kuard ClusterIP 10.102.239.168 80/TCP 1h + +NAME FQDN TLS SECRET FIRST ROUTE STATUS STATUS DESCRIPT +httpproxy.projectcontour.io/kuard kuard.local valid valid HTTPProxy +``` + +... showing that there are three Pods, one Service, and one HTTPProxy . + +In your terminal, use curl with the IP or DNS address of the Contour Service to send a request to the demo application: + +```sh +$ curl -H 'Host: kuard.local' ${CONTOUR_IP} +``` + +## Running without a Kubernetes LoadBalancer + +If you can't or don't want to use a Service of `type: LoadBalancer` there are other ways to run Contour. + +### NodePort Service + +If your cluster doesn't have the capability to configure a Kubernetes LoadBalancer, +or if you want to configure the load balancer outside Kubernetes, +you can change the Envoy Service in the [`02-service-envoy.yaml`][7] file and set `type` to `NodePort`. + +This will have every node in your cluster listen on the resultant port and forward traffic to Contour. +That port can be discovered by taking the second number listed in the `PORT` column when listing the service, for example `30274` in `80:30274/TCP`. + +Now you can point your browser at the specified port on any node in your cluster to communicate with Contour. + +### Host Networking + +You can run Contour without a Kubernetes Service at all. +This is done by having the Envoy pod run with host networking. +Contour's examples utilize this model in the `/examples` directory. +To configure, set: `hostNetwork: true` and `dnsPolicy: ClusterFirstWithHostNet` on your Envoy pod definition. +Next, pass `--envoy-service-http-port=80 --envoy-service-https-port=443` to the contour `serve` command which instructs Envoy to listen directly on port 80/443 on each host that it is running. +This is best paired with a DaemonSet (perhaps paired with Node affinity) to ensure that a single instance of Contour runs on each Node. +See the [AWS NLB tutorial][10] as an example. + +## Disabling Features + +You can run Contour with certain features disabled by passing `--disable-feature` flag to the Contour `serve` command. +The flag is used to disable the informer for a custom resource, effectively making the corresponding CRD optional in the cluster. +You can provide the flag multiple times. + +For example, to disable ExtensionService CRD, use the flag as follows: `--disable-feature=extensionservices`. + +See the [configuration section entry][19] for all options. + +## Upgrading Contour/Envoy + +At times, it's needed to upgrade Contour, the version of Envoy, or both. +The included `shutdown-manager` can assist with watching Envoy for open connections while draining and give signal back to Kubernetes as to when it's fine to delete Envoy pods during this process. + +See the [redeploy envoy][11] docs for more information about how to not drop active connections to Envoy. +Also see the [upgrade guides][15] on steps to roll out a new version of Contour. + +## Running Multiple Instances of Contour + +It's possible to run multiple instances of Contour within a single Kubernetes cluster. +This can be useful for separating external vs. internal ingress, for having separate ingress controllers for different ingress classes, and more. +Each Contour instance can also be configured via the `--watch-namespaces` flag to handle their own namespaces. This allows the Kubernetes RBAC objects +to be restricted further. + +The recommended way to deploy multiple Contour instances is to put each instance in its own namespace. +This avoids most naming conflicts that would otherwise occur, and provides better logical separation between the instances. +However, it is also possible to deploy multiple instances in a single namespace if needed; this approach requires more modifications to the example manifests to function properly. +Each approach is described in detail below, using the [examples/contour][17] directory's manifests for reference. + +### In Separate Namespaces (recommended) + +In general, this approach requires updating the `namespace` of all resources, as well as giving unique names to cluster-scoped resources to avoid conflicts. + +- `00-common.yaml`: + - update the name of the `Namespace` + - update the namespace of both `ServiceAccounts` +- `01-contour-config.yaml`: + - update the namespace of the `ConfigMap` + - if you have any namespaced references within the ConfigMap contents (e.g. `fallback-certificate`, `envoy-client-certificate`), ensure those point to the correct namespace as well. +- `01-crds.yaml` will be shared between the two instances; no changes are needed. +- `02-job-certgen.yaml`: + - update the namespace of all resources + - update the namespace of the `ServiceAccount` subject within the `RoleBinding` +- `02-role-contour.yaml`: + - update the name of the `ClusterRole` to be unique + - update the namespace of the `Role` +- `02-rbac.yaml`: + - update the name of the `ClusterRoleBinding` to be unique + - update the namespace of the `RoleBinding` + - update the namespaces of the `ServiceAccount` subject within both resources + - update the name of the ClusterRole within the ClusterRoleBinding's roleRef to match the unique name used in `02-role-contour.yaml` +- `02-service-contour.yaml`: + - update the namespace of the `Service` +- `02-service-envoy.yaml`: + - update the namespace of the `Service` +- `03-contour.yaml`: + - update the namespace of the `Deployment` + - add an argument to the container, `--ingress-class-name=`, so this instance only processes Ingresses/HTTPProxies with the given ingress class. +- `03-envoy.yaml`: + - update the namespace of the `DaemonSet` + - remove the two `hostPort` definitions from the container (otherwise, these would conflict between the two instances) + + +### In The Same Namespace + +This approach requires giving unique names to all resources to avoid conflicts, and updating all resource references to use the correct names. + +- `00-common.yaml`: + - update the names of both `ServiceAccounts` to be unique +- `01-contour-config.yaml`: + - update the name of the `ConfigMap` to be unique +- `01-crds.yaml` will be shared between the two instances; no changes are needed. +- `02-job-certgen.yaml`: + - update the names of all resources to be unique + - update the name of the `Role` within the `RoleBinding`'s roleRef to match the unique name used for the `Role` + - update the name of the `ServiceAccount` within the `RoleBinding`'s subjects to match the unique name used for the `ServiceAccount` + - update the serviceAccountName of the `Job` + - add an argument to the container, `--secrets-name-suffix=`, so the generated TLS secrets have unique names + - update the spec.template.metadata.labels on the `Job` to be unique +- `02-role-contour.yaml`: + - update the names of the `ClusterRole` and `Role` to be unique +- `02-rbac.yaml`: + - update the names of the `ClusterRoleBinding` and `RoleBinding` to be unique + - update the roleRefs within both resources to reference the unique `Role` and `ClusterRole` names used in `02-role-contour.yaml` + - update the subjects within both resources to reference the unique `ServiceAccount` name used in `00-common.yaml` +- `02-service-contour.yaml`: + - update the name of the `Service` to be unique + - update the selector to be unique (this must match the labels used in `03-contour.yaml`, below) +- `02-service-envoy.yaml`: + - update the name of the `Service` to be unique + - update the selector to be unique (this must match the labels used in `03-envoy.yaml`, below) +- `03-contour.yaml`: + - update the name of the `Deployment` to be unique + - update the metadata.labels, the spec.selector.matchLabels, the spec.template.metadata.labels, and the spec.template.spec.affinity.podAntiAffinity labels to match the labels used in `02-service-contour.yaml` + - update the serviceAccountName to match the unique name used in `00-common.yaml` + - update the `contourcert` volume to reference the unique `Secret` name generated from `02-certgen.yaml` (e.g. `contourcert`) + - update the `contour-config` volume to reference the unique `ConfigMap` name used in `01-contour-config.yaml` + - add an argument to the container, `--leader-election-resource-name=`, so this Contour instance uses a separate leader election `Lease` + - add an argument to the container, `--envoy-service-name=`, referencing the unique name used in `02-service-envoy.yaml` + - add an argument to the container, `--ingress-class-name=`, so this instance only processes Ingresses/HTTPProxies with the given ingress class. +- `03-envoy.yaml`: + - update the name of the `DaemonSet` to be unique + - update the metadata.labels, the spec.selector.matchLabels, and the spec.template.metadata.labels to match the unique labels used in `02-service-envoy.yaml` + - update the `--xds-address` argument to the initContainer to use the unique name of the contour Service from `02-service-contour.yaml` + - update the serviceAccountName to match the unique name used in `00-common.yaml` + - update the `envoycert` volume to reference the unique `Secret` name generated from `02-certgen.yaml` (e.g. `envoycert`) + - remove the two `hostPort` definitions from the container (otherwise, these would conflict between the two instances) + +### Using the Gateway provisioner + +The Contour Gateway provisioner also supports deploying multiple instances of Contour, either in the same namespace or different namespaces. +See [Getting Started with the Gateway provisioner][16] for more information on getting started with the Gateway provisioner. +To deploy multiple Contour instances, you create multiple `Gateways`, either in the same namespace or in different namespaces. + +Note that although the provisioning request itself is made via a Gateway API resource (`Gateway`), this method of installation still allows you to use *any* of the supported APIs for defining virtual hosts and routes: `Ingress`, `HTTPProxy`, or Gateway API's `HTTPRoute` and `TLSRoute`. + +If you are using `Ingress` or `HTTPProxy`, you will likely want to assign each Contour instance a different ingress class, so they each handle different subsets of `Ingress`/`HTTPProxy` resources. +To do this, [create two separate GatewayClasses][18], each with a different `ContourDeployment` parametersRef. +The `ContourDeployment` specs should look like: + +```yaml +kind: ContourDeployment +apiVersion: projectcontour.io/v1alpha1 +metadata: + namespace: projectcontour + name: ingress-class-1 +spec: + runtimeSettings: + ingress: + classNames: + - ingress-class-1 +--- +kind: ContourDeployment +apiVersion: projectcontour.io/v1alpha1 +metadata: + namespace: projectcontour + name: ingress-class-2 +spec: + runtimeSettings: + ingress: + classNames: + - ingress-class-2 +``` + +Then create each `Gateway` with the appropriate `spec.gatewayClassName`. + +## Running Contour in tandem with another ingress controller + +If you're running multiple ingress controllers, or running on a cloudprovider that natively handles ingress, +you can specify the annotation `kubernetes.io/ingress.class: "contour"` on all ingresses that you would like Contour to claim. +You can customize the class name with the `--ingress-class-name` flag at runtime. (A comma-separated list of class names is allowed.) +If the `kubernetes.io/ingress.class` annotation is present with a value other than `"contour"`, Contour will ignore that ingress. + +## Uninstall Contour + +To remove Contour or the Contour Gateway Provisioner from your cluster, delete the namespace: + +```bash +$ kubectl delete ns projectcontour +``` +**Note**: Your namespace may differ from above. + +[1]: #running-without-a-kubernetes-loadbalancer +[2]: {{< param github_url>}}/tree/{{< param branch >}}/examples/render/contour.yaml +[3]: #host-networking +[4]: guides/proxy-proto.md +[5]: https://github.com/kubernetes-up-and-running/kuard +[7]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour/02-service-envoy.yaml +[8]: /getting-started +[9]: config/fundamentals.md +[10]: guides/deploy-aws-nlb.md +[11]: redeploy-envoy.md +[12]: {{< param github_url>}}/tree/{{< param branch >}}/examples/render/contour-gateway-provisioner.yaml +[13]: https://projectcontour.io/resources/deprecation-policy/ +[14]: {{< param github_url>}}/tree/{{< param branch >}}/examples/render/contour-deployment.yaml +[15]: /resources/upgrading/ +[16]: https://projectcontour.io/getting-started/#option-3-contour-gateway-provisioner-alpha +[17]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour +[18]: guides/gateway-api/#next-steps +[19]: configuration.md \ No newline at end of file diff --git a/site/content/docs/1.29/github.md b/site/content/docs/1.29/github.md new file mode 100644 index 00000000000..8a0f36b4f4d --- /dev/null +++ b/site/content/docs/1.29/github.md @@ -0,0 +1,80 @@ +This document outlines how we use GitHub. + +## Milestones + +Contour attempts to ship on a quarterly basis. +These releases are tracked with a milestone. +The _current_ release is the milestone with the closest delivery date. + +Issues which are not assigned to the current milestone _should not be worked on_. + +## Priorities + +This project has three levels of priority: + +- p0 - Must fix immediately. +This is reserved for bugs and security issues. A milestone cannot ship with open p0 issues. +- p1 - Should be done. +p1 issues assigned to a milestone _should_ be completed during that milestone. +- p2 - May be done. +p2 issues assigned to a milestone _may_ be completed during that milestone if time permits. + +Issues without a priority are _unprioritised_. Priority will be assigned by a PM or release manager during issue triage. + +## Questions + +We encourage support questions via issues. +Questions will be tagged `question` and are not assigned a milestone or a priority. + +## Waiting for information + +Any issue which lacks sufficient information for triage will be tagged `waiting-for-info`. +Issues with this tag may be closed after a reasonable length of time if further information is not forthcoming. + +## Issue tagging + +Issues without tags have not be triaged. + +During issue triage, usually by a project member, release manager, or pm, one or more tags will be assigned. + +- `Needs-Product` indicates the issue needs attention by a product owner or PM. +- `Needs-design-doc` indicates the issue requires a design document to be circulated. + +These are blocking states, these labels must be resolved, either by PM or agreeing on a design. + +## Assigning an issue + +Issues within a milestone _should_ be assigned to an owner when work commences on them. +Assigning an issue indicates that you are working on it. + +Before you start to work on an issue you should assign yourself. +From that point onward you are responsible for the issue and you are expected to report timely status on the issue to anyone that asks. + +If you cease work on an issue, even if incomplete, you should leave a comment to that effect on the issue and remove yourself as the assignee. +From that point onward you are no longer responsible for the issue, however you may be approached as a subject matter expert--as the last person to touch the issue--by future assignees. + +For infrequent contributors who are not members of the Contour project, assign yourself by leaving a comment to that effect on the issue. + +*Do not hoard issues, you won't enjoy it* + +## Requesting a review + +PRs which are related to issues in the current milestone should be assigned to the current milestone. +This is an indicator to reviewers that the PR is ready for review and should be reviewed in the current milestone. +Occasionally PRs may be assigned to the next milestone indicating they are for review at the start of the next development cycle. + +All PRs should reference the issue they relate to either by one of the following; + +- `Fixes #NNNN` indicating that merging this issue will fix issue #NNNN +- `Updates #NNNN` indicating that merging this issue will progress issue #NNNN to some degree. + +If there is no `Updates` or `Fixes` line in the PR the review will, with the exception of trivial or self evident fixes, be deferred. + +[Further reading][1] + +## Help wanted and good first issues + +The `help wanted` and `good first issue` tags _may_ be assigned to issues _in the current milestone_. +To limit the amount of work in progress, `help wanted` and `good first issue` should not be used for issues outside the current milestone. + +[1]: https://dave.cheney.net/2019/02/18/talk-then-code \ No newline at end of file diff --git a/site/content/docs/1.29/grpc-tls-howto.md b/site/content/docs/1.29/grpc-tls-howto.md new file mode 100644 index 00000000000..51770de950d --- /dev/null +++ b/site/content/docs/1.29/grpc-tls-howto.md @@ -0,0 +1,169 @@ +# Enabling TLS between Envoy and Contour + +This document describes the steps required to secure communication between Envoy and Contour. +The outcome of this is that we will have two Secrets available in the `projectcontour` namespace: + +- **contourcert:** contains Contour's keypair which is used for serving TLS secured gRPC, and the CA's public certificate bundle which is used for validating Envoy's client certificate. +Contour's certificate must be a valid certificate for the name `contour` in order for this to work. +This is currently hardcoded by Contour. +- **envoycert:** contains Envoy's keypair which used as a client for connecting to Contour, and the CA's public certificate bundle which is used for validating Contour's server certificate. + +Note that both Secrets contain a copy of the CA certificate bundle under the `ca.crt` data key. + +## Ways you can get the certificates into your cluster + +- Deploy the Job from [certgen.yaml][1]. +This will run `contour certgen --kube --secrets-format=compact` for you. +- Run `contour certgen --kube` locally. +- Run the manual procedure below. + +## Caveats and warnings + +**Be very careful with your production certificates!** + +This is intended as an example to help you get started. +For any real deployment, you should **carefully** manage all the certificates and control who has access to them. +Make sure you don't commit them to any git repositories either. + +## Manual TLS certificate generation process + +### Generating a CA keypair + +First, we need to generate a keypair: + +``` +$ openssl req -x509 -new -nodes \ + -keyout certs/cakey.pem -sha256 \ + -days 1825 -out certs/cacert.pem \ + -subj "/O=Project Contour/CN=Contour CA" +``` + +Then, the new CA key will be stored in `certs/cakey.pem` and the cert in `certs/cacert.pem`. + +### Generating Contour's keypair + +Next, we need to generate a keypair for Contour. +First, we make a new private key: + +``` +$ openssl genrsa -out certs/contourkey.pem 2048 +``` + +Then, we create a CSR and have our CA sign the CSR and issue a certificate. +This uses the file [certs/cert-contour.ext][2], which ensures that at least one of the valid names of the certificate is the bareword `contour`. +This is required for the handshake to succeed, as `contour bootstrap` configures Envoy to pass this as the SNI server name for the connection. + +``` +$ openssl req -new -key certs/contourkey.pem \ + -out certs/contour.csr \ + -subj "/O=Project Contour/CN=contour" + +$ openssl x509 -req -in certs/contour.csr \ + -CA certs/cacert.pem \ + -CAkey certs/cakey.pem \ + -CAcreateserial \ + -out certs/contourcert.pem \ + -days 1825 -sha256 \ + -extfile certs/cert-contour.ext +``` + +At this point, the contour certificate and key are in the files `certs/contourcert.pem` and `certs/contourkey.pem` respectively. + +### Generating Envoy's keypair + +Next, we generate a keypair for Envoy: + +``` +$ openssl genrsa -out certs/envoykey.pem 2048 +``` + +Then, we generate a CSR and have the CA sign it: + +``` +$ openssl req -new -key certs/envoykey.pem \ + -out certs/envoy.csr \ + -subj "/O=Project Contour/CN=envoy" + +$ openssl x509 -req -in certs/envoy.csr \ + -CA certs/cacert.pem \ + -CAkey certs/cakey.pem \ + -CAcreateserial \ + -out certs/envoycert.pem \ + -days 1825 -sha256 \ + -extfile certs/cert-envoy.ext +``` + +Like the Contour certificate, this CSR uses the file [certs/cert-envoy.ext][3]. +However, in this case, there are no special names required. + +### Putting the certificates in the cluster + +Next, we create the required Secrets in the target Kubernetes cluster: + +```bash +$ kubectl create secret -n projectcontour generic contourcert \ + --from-file=tls.key=./certs/contourkey.pem \ + --from-file=tls.crt=./certs/contourcert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --save-config + +$ kubectl create secret -n projectcontour generic envoycert \ + --from-file=tls.key=./certs/envoykey.pem \ + --from-file=tls.crt=./certs/envoycert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --save-config +``` + +Note that we don't put the CA **key** into the cluster, there's no reason for that to be there, and that would create a security problem. + +## Rotating Certificates + +Eventually the certificates that Contour and Envoy use will need to be rotated. +The following steps can be taken to replace the certificates that Contour and Envoy are using: + +1. Generate a new keypair for both Contour and Envoy (optionally also for the CA) +2. Update the Secrets that hold the gRPC TLS keypairs +3. Contour and Envoy will automatically rotate their certificates after mounted secrets have been updated by the kubelet + +The secrets can be updated in-place by running: + +```bash +$ kubectl create secret -n projectcontour generic contourcert \ + --from-file=tls.key=./certs/contourkey.pem \ + --from-file=tls.crt=./certs/contourcert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --dry-run -o json \ + | kubectl apply -f - + +$ kubectl create secret -n projectcontour generic envoycert \ + --from-file=tls.key=./certs/envoykey.pem \ + --from-file=tls.crt=./certs/envoycert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --dry-run -o json \ + | kubectl apply -f - +``` + +There are few preconditions that need to be met before Envoy can automatically reload certificate and key files: + +- Envoy must be version v1.14.1 or later +- The bootstrap configuration must be generated with `contour bootstrap` using the `--resources-dir` argument, see [examples/contour/03-envoy.yaml][4] + +### Rotate using the contour-certgen job + +When using the built-in Contour certificate generation, the following steps can be used: + +1. Delete the contour-certgen job + - `kubectl delete job contour-certgen -n projectcontour` +2. Reapply the contour-certgen job from [certgen.yaml][1] + +## Conclusion + +Once this process is done, the certificates will be present as Secrets in the `projectcontour` namespace, as required by +[examples/contour][5]. + +[1]: {{< param github_url >}}/tree/{{< param branch >}}/examples/contour/02-job-certgen.yaml +[2]: {{< param github_url >}}/tree/{{< param branch >}}/certs/cert-contour.ext +[3]: {{< param github_url >}}/tree/{{< param branch >}}/certs/cert-envoy.ext +[4]: {{< param github_url >}}/tree/{{< param branch >}}/examples/contour/03-envoy.yaml +[5]: {{< param github_url >}}/tree/{{< param branch >}}/examples/contour + diff --git a/site/content/guides/_index.md b/site/content/docs/1.29/guides/_index.md similarity index 92% rename from site/content/guides/_index.md rename to site/content/docs/1.29/guides/_index.md index 3fa48bfa893..8981b8fbd79 100644 --- a/site/content/guides/_index.md +++ b/site/content/docs/1.29/guides/_index.md @@ -1,5 +1,4 @@ --- -# layout: page title: Guides description: Contour Resources id: guides diff --git a/site/content/guides/cert-manager.md b/site/content/docs/1.29/guides/cert-manager.md similarity index 99% rename from site/content/guides/cert-manager.md rename to site/content/docs/1.29/guides/cert-manager.md index ef67a1f6046..0f926946eda 100644 --- a/site/content/guides/cert-manager.md +++ b/site/content/docs/1.29/guides/cert-manager.md @@ -1,6 +1,5 @@ --- title: Deploying HTTPS services with Contour and cert-manager -layout: page --- This tutorial shows you how to securely deploy an HTTPS web application on a Kubernetes cluster, using: @@ -663,7 +662,7 @@ __Note:__ For HTTPProxy resources this happens automatically without the need fo [4]: https://docs.cert-manager.io/en/latest/getting-started/install/kubernetes.html [5]: https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml [6]: https://letsencrypt.org/getting-started/ -[7]: /docs/{{< param latest_version >}}/deploy-options/#get-your-hostname-or-ip-address +[7]: ../deploy-options/#get-your-hostname-or-ip-address [8]: /img/cert-manager/httpbinhomepage.png [9]: /img/cert-manager/httpbin.png [10]: {{< param github_url >}}/issues/950 diff --git a/site/content/guides/deploy-aws-nlb.md b/site/content/docs/1.29/guides/deploy-aws-nlb.md similarity index 93% rename from site/content/guides/deploy-aws-nlb.md rename to site/content/docs/1.29/guides/deploy-aws-nlb.md index 48f3f3095f2..af3f8df1019 100644 --- a/site/content/guides/deploy-aws-nlb.md +++ b/site/content/docs/1.29/guides/deploy-aws-nlb.md @@ -1,6 +1,5 @@ --- title: Deploying Contour on AWS with NLB -layout: page --- This is an advanced deployment guide to configure Contour on AWS with the [Network Load Balancer (NLB)][1]. @@ -43,6 +42,6 @@ You can now test your NLB. - Notice that Envoy fills out `X-Forwarded-For`, because it was the first to see the traffic directly from the browser. [1]: https://aws.amazon.com/blogs/aws/new-network-load-balancer-effortless-scaling-to-millions-of-requests-per-second/ -[2]: /docs/{{< param latest_version >}}/deploy-options/#testing-your-installation +[2]: ../deploy-options/#testing-your-installation [3]: https://github.com/kubernetes/kubernetes/issues/52173 -[4]: {{< param github_url >}}/tree/{{< param latest_version >}} +[4]: {{< param github_url >}}/tree/{{< param branch >}} diff --git a/site/content/guides/deploy-aws-tls-nlb.md b/site/content/docs/1.29/guides/deploy-aws-tls-nlb.md similarity index 96% rename from site/content/guides/deploy-aws-tls-nlb.md rename to site/content/docs/1.29/guides/deploy-aws-tls-nlb.md index 892eade5a5e..7f4f83f685e 100644 --- a/site/content/guides/deploy-aws-tls-nlb.md +++ b/site/content/docs/1.29/guides/deploy-aws-tls-nlb.md @@ -1,6 +1,5 @@ --- title: AWS Network Load Balancer TLS Termination with Contour -layout: page --- ## Motivation @@ -17,7 +16,7 @@ The TLS implementation used by the AWS NLB is formally verified and maintained. An external client transmits a request to the NLB. The request is encrypted with TLS using the production (e.g., client facing) certificate, and on port 443. -The NLB decrypts the request, and transmits it on to your cluster on port 80. It follows the standard request routing configured within the cluster. Notably, the request received within the cluster includes the actual origin IP address of the external client. +The NLB decrypts the request, and transmits it on to Envoy running in your cluster on port 8080. It follows the standard request routing configured within the cluster. Notably, the request received within the cluster includes the actual origin IP address of the external client. Alternate ports may be configured. End-to-end encryption technically requires the segment between the NLB and cluster pods be encrypted also. A follow-up post will describe the NLB originating TLS based on a cluster certificate. diff --git a/site/content/guides/external-authorization.md b/site/content/docs/1.29/guides/external-authorization.md similarity index 66% rename from site/content/guides/external-authorization.md rename to site/content/docs/1.29/guides/external-authorization.md index 367b76b9043..74076ede518 100644 --- a/site/content/guides/external-authorization.md +++ b/site/content/docs/1.29/guides/external-authorization.md @@ -1,6 +1,5 @@ --- title: External Authorization Support -layout: page --- Starting in version 1.9, Contour supports routing client requests to an @@ -120,8 +119,8 @@ patchesJson6902: images: - name: contour-authserver:latest - newName: docker.io/projectcontour/contour-authserver - newTag: v2 + newName: ghcr.io/projectcontour/contour-authserver + newTag: v4 ``` Note that the kustomization patches the `Certificate` resource to use the @@ -361,20 +360,179 @@ $ curl -k --user user1:password1 https://local.projectcontour.io/test/$((RANDOM) {"TestId":"","Path":"/test/27132","Host":"local.projectcontour.io","Method":"GET","Proto":"HTTP/1.1","Headers":{"Accept":["*/*"],"Auth-Handler":["htpasswd"],"Auth-Realm":["default"],"Auth-Username":["user1"],"Authorization":["Basic dXNlcjE6cGFzc3dvcmQx"],"Content-Length":["0"],"User-Agent":["curl/7.64.1"],"X-Envoy-Expected-Rq-Timeout-Ms":["15000"],"X-Envoy-Internal":["true"],"X-Forwarded-For":["172.18.0.1"],"X-Forwarded-Proto":["https"],"X-Request-Id":["2c0ae102-4cf6-400e-a38f-5f0b844364cc"],"X-Request-Start":["t=1601601826.102"]}} ``` +## Global External Authorization + +Starting from version 1.25, Contour supports global external authorization. This allows you to setup a single external authorization configuration for all your virtual hosts (HTTP and HTTPS). + +To get started, ensure you have `contour-authserver` and the `ExtensionService` deployed as described above. + +### Global Configuration + +Define the global external authorization configuration in your contour config. + +```yaml +globalExtAuth: + extensionService: projectcontour-auth/htpasswd + failOpen: false + authPolicy: + context: + header1: value1 + header2: value2 + responseTimeout: 1s +``` + +Setup a HTTPProxy without TLS +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - services: + - name: ingress-conformance-echo + port: 80 +``` + +``` +$ kubectl apply -f echo-proxy.yaml +httpproxy.projectcontour.io/echo created +``` + +When we make a HTTP request without authentication details, we can see that the endpoint is secured and returns a 401. + +``` +$ curl -k -I http://local.projectcontour.io/test/$((RANDOM)) +HTTP/1.1 401 Unauthorized +www-authenticate: Basic realm="default", charset="UTF-8" +vary: Accept-Encoding +date: Mon, 20 Feb 2023 13:45:31 GMT +``` + +If you add the username and password to the same request you can verify that the request succeeds. +``` +$ curl -k --user user1:password1 http://local.projectcontour.io/test/$((RANDOM)) +{"TestId":"","Path":"/test/27748","Host":"local.projectcontour.io","Method":"GET","Proto":"HTTP/1.1","Headers":{"Accept":["*/*"],"Auth-Context-Header1":["value1"],"Auth-Context-Header2":["value2"],"Auth-Context-Routq":["global"],"Auth-Handler":["htpasswd"],"Auth-Realm":["default"],"Auth-Username":["user1"],"Authorization":["Basic dXNlcjE6cGFzc3dvcmQx"],"User-Agent":["curl/7.86.0"],"X-Envoy-Expected-Rq-Timeout-Ms":["15000"],"X-Envoy-Internal":["true"],"X-Forwarded-For":["172.18.0.1"],"X-Forwarded-Proto":["http"],"X-Request-Id":["b6bb7036-8408-4b03-9ce5-7011d89799b4"],"X-Request-Start":["t=1676900780.118"]}} +``` + +Global external authorization can also be configured with TLS virtual hosts. Update your HTTPProxy by adding `tls` and `secretName` to it. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + tls: + secretName: ingress-conformance-echo + routes: + - services: + - name: ingress-conformance-echo + port: 80 +``` + +``` +$ kubectl apply -f echo-proxy.yaml +httpproxy.projectcontour.io/echo configured +``` + +you can verify the HTTPS requests succeeds +``` +$ curl -k --user user1:password1 https://local.projectcontour.io/test/$((RANDOM)) +{"TestId":"","Path":"/test/13499","Host":"local.projectcontour.io","Method":"GET","Proto":"HTTP/1.1","Headers":{"Accept":["*/*"],"Auth-Context-Header1":["value1"],"Auth-Context-Header2":["value2"],"Auth-Context-Routq":["global"],"Auth-Handler":["htpasswd"],"Auth-Realm":["default"],"Auth-Username":["user1"],"Authorization":["Basic dXNlcjE6cGFzc3dvcmQx"],"User-Agent":["curl/7.86.0"],"X-Envoy-Expected-Rq-Timeout-Ms":["15000"],"X-Envoy-Internal":["true"],"X-Forwarded-For":["172.18.0.1"],"X-Forwarded-Proto":["https"],"X-Request-Id":["2b3edbed-3c68-44ef-a659-2e1245d7fe13"],"X-Request-Start":["t=1676901557.918"]}} +``` + +### Excluding a virtual host from global external authorization + +You can exclude a virtual host from the global external authorization policy by setting the `disabled` flag to true under `authPolicy`. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + tls: + secretName: ingress-conformance-echo + authorization: + authPolicy: + disabled: true + routes: + - services: + - name: ingress-conformance-echo + port: 80 +``` + +``` +$ kubectl apply -f echo-proxy.yaml +httpproxy.projectcontour.io/echo configured +``` + +You can verify that an insecure request succeeds without being authorized. + +``` +$ curl -k https://local.projectcontour.io/test/$((RANDOM)) +{"TestId":"","Path":"/test/51","Host":"local.projectcontour.io","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":["172.18.0.1"],"X-Forwarded-Proto":["https"],"X-Request-Id":["18716e12-dcce-45ba-a3bb-bc26af3775d2"],"X-Request-Start":["t=1676901847.802"]}} +``` + +### Overriding global external authorization for a HTTPS virtual host + +You may want a different configuration than what is defined globally. To override the global external authorization, add the `authorization` block to your TLS enabled HTTPProxy as shown below + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + tls: + secretName: ingress-conformance-echo + authorization: + extensionRef: + name: htpasswd + namespace: projectcontour-auth + routes: + - services: + - name: ingress-conformance-echo + port: 80 +``` + +``` +$ kubectl apply -f echo-proxy.yaml +httpproxy.projectcontour.io/echo configured +``` + +You can verify that the endpoint has applied the overridden external authorization configuration. + +``` +$ curl -k --user user1:password1 https://local.projectcontour.io/test/$((RANDOM)) +{"TestId":"","Path":"/test/4514","Host":"local.projectcontour.io","Method":"GET","Proto":"HTTP/1.1","Headers":{"Accept":["*/*"],"Auth-Context-Overriden_message":["overriden_value"],"Auth-Handler":["htpasswd"],"Auth-Realm":["default"],"Auth-Username":["user1"],"Authorization":["Basic dXNlcjE6cGFzc3dvcmQx"],"User-Agent":["curl/7.86.0"],"X-Envoy-Expected-Rq-Timeout-Ms":["15000"],"X-Envoy-Internal":["true"],"X-Forwarded-For":["172.18.0.1"],"X-Forwarded-Proto":["https"],"X-Request-Id":["8a02d6ce-8be0-4e87-8ed8-cca7e239e986"],"X-Request-Start":["t=1676902237.111"]}} +``` + +NOTE: You can only override the global external configuration on a HTTPS virtual host. + ## Caveats There are a few caveats to consider when deploying external authorization: 1. Only one external authorization server can be configured on a virtual host -1. Only HTTPS virtual hosts are supported +1. HTTP hosts are only supported with global external authorization. 1. External authorization cannot be used with the TLS fallback certificate (i.e. client SNI support is required) [1]: https://github.com/projectcontour/contour-authserver [2]: https://httpd.apache.org/docs/current/misc/password_encryptions.html [3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto -[4]: /docs/{{< param latest_version >}}/config/api/#projectcontour.io/v1alpha1.ExtensionService -[5]: /docs/{{< param latest_version >}}/config/api/#projectcontour.io/v1.HTTPProxy +[4]: ../config/api/#projectcontour.io/v1alpha1.ExtensionService +[5]: ../config/api/#projectcontour.io/v1.HTTPProxy [6]: https://cert-manager.io/ [7]: https://httpd.apache.org/docs/current/programs/htpasswd.html [8]: https://kubernetes-sigs.github.io/kustomize/ diff --git a/site/content/guides/fips.md b/site/content/docs/1.29/guides/fips.md similarity index 91% rename from site/content/guides/fips.md rename to site/content/docs/1.29/guides/fips.md index 08dfee86418..d79498c64f2 100644 --- a/site/content/guides/fips.md +++ b/site/content/docs/1.29/guides/fips.md @@ -1,6 +1,5 @@ --- title: FIPS 140-2 in Contour -layout: page --- The [Federal Information Processing Standard (FIPS) 140-2][0] publication describes United States government approved security requirements for cryptographic modules. @@ -102,23 +101,28 @@ Note that if you do build with FIPS mode outside of the build container, you can We can first compile the Envoy binary by running the following in a `bash` shell from the Envoy source directory: ```bash -BAZEL_BUILD_EXTRA_OPTIONS="--define boringssl=fips" ENVOY_DOCKER_BUILD_DIR= ./ci/run_envoy_docker.sh './ci/do_ci.sh bazel.release.server_only' +BAZEL_BUILD_EXTRA_OPTIONS="--define boringssl=fips" ENVOY_DOCKER_BUILD_DIR= ./ci/run_envoy_docker.sh './ci/do_ci.sh bazel.release //test/exe:envoy_static_test' ``` +*This command mimics the Envoy release CI process with the target `bazel.release` but differs in only running a single test for brevity. You may omit the `//test/exe:envoy_static_test` test entirely to run the full suite of Envoy tests.* + Replace `` with a directory you would like the build output to be placed on your host computer. -Once that build completes, you should have a file named `envoy_binary.tar.gz` in your specified output directory. -If you would like to build an image with Envoy according to your own specifications, you can unpack the resulting tar archive and you will find a stripped Envoy binary in the `build_release_stripped` directory and a unstripped Envoy with debug info in the `build_release` directory. +Once that build completes, you should have a file named `release.tar.zst` in your specified output directory. +This file is a [Zstandard](https://github.com/facebook/zstd) compressed archive containing the compiled Envoy release and debug binaries. +If you would like to build an image with Envoy according to your own specifications, you can unpack the resulting archive and you will find a stripped Envoy binary in the root and an unstripped Envoy binary with debug info in the `dbg` directory. To build an image matching the canonical Envoy upstream release image ([`envoyproxy/envoy`][13]), run the following: +*Note: You will need a recent version of Docker/BuildKit that supports Zstandard decompression.* + ```bash # Make ./linux/amd64 directories. mkdir -p ./linux/amd64 -# Untar tar archive from build step. -tar xzf /envoy_binary.tar.gz -C ./linux/amd64 +# Copy Zstandard archive from build step. +cp -a /envoy/x64/bin/release.tar.zst ./linux/amd64/release.tar.zst # Run the Docker image build. -docker build -f ./ci/Dockerfile-envoy . +docker build -f ./ci/Dockerfile-envoy --target envoy . ``` Once you have an image built, you can tag it as needed, push the image to a registry, and use it in an Envoy deployment. diff --git a/site/content/guides/gatekeeper.md b/site/content/docs/1.29/guides/gatekeeper.md similarity index 99% rename from site/content/guides/gatekeeper.md rename to site/content/docs/1.29/guides/gatekeeper.md index 0e1844fb9f3..fa6d01cab41 100644 --- a/site/content/guides/gatekeeper.md +++ b/site/content/docs/1.29/guides/gatekeeper.md @@ -1,6 +1,5 @@ --- title: Using Gatekeeper as a validating admission controller with Contour -layout: page --- This tutorial demonstrates how to use [Gatekeeper](https://github.com/open-policy-agent/gatekeeper) as a validating admission controller for Contour. diff --git a/site/content/guides/gateway-api.md b/site/content/docs/1.29/guides/gateway-api.md similarity index 51% rename from site/content/guides/gateway-api.md rename to site/content/docs/1.29/guides/gateway-api.md index 61e2bc968f0..4bcc3140c03 100644 --- a/site/content/guides/gateway-api.md +++ b/site/content/docs/1.29/guides/gateway-api.md @@ -1,62 +1,26 @@ --- title: Using Gateway API with Contour -layout: page --- -## Introduction - -[Gateway API][1] is an open source project managed by the Kubernetes SIG-NETWORK community. The project's goal is to -evolve service networking APIs within the Kubernetes ecosystem. Gateway API consists of multiple resources that provide -user interfaces to expose Kubernetes applications- Services, Ingress, and more. - -This guide covers using version **v1** of the Gateway API, with Contour `v1.28.0` or higher. - -### Background - -Gateway API targets three personas: - -- __Platform Provider__: The Platform Provider is responsible for the overall environment that the cluster runs in, i.e. - the cloud provider. The Platform Provider will interact with `GatewayClass` resources. -- __Platform Operator__: The Platform Operator is responsible for overall cluster administration. They manage policies, - network access, application permissions and will interact with `Gateway` resources. -- __Service Operator__: The Service Operator is responsible for defining application configuration and service - composition. They will interact with `HTTPRoute` and `TLSRoute` resources and other typical Kubernetes resources. - -Gateway API contains three primary resources: - -- __GatewayClass__: Defines a set of gateways with a common configuration and behavior. -- __Gateway__: Requests a point where traffic can be translated to a Service within the cluster. -- __HTTPRoute/TLSRoute__: Describes how traffic coming via the Gateway maps to the Services. - -Resources are meant to align with personas. For example, a platform operator will create a `Gateway`, so a developer can -expose an HTTP application using an `HTTPRoute` resource. +This tutorial walks through an example of using [Gateway API][1] with Contour. +See the [Contour reference documentation][5] for more information on Contour's Gateway API support. ### Prerequisites -The following prerequisites must be met before using Gateway API with Contour: +The following prerequisites must be met before following this guide: - A working [Kubernetes][2] cluster. Refer to the [compatibility matrix][3] for cluster version requirements. - The [kubectl][4] command-line tool, installed and configured to access your cluster. -## Deploying Contour with Gateway API +## Deploy Contour with Gateway API enabled -Contour supports two modes of provisioning for use with Gateway API: **static** and **dynamic**. - -In **static** provisioning, the platform operator defines a `Gateway` resource, and then manually deploys a Contour instance corresponding to that `Gateway` resource. -It is up to the platform operator to ensure that all configuration matches between the `Gateway` and the Contour/Envoy resources. -Contour will then process that `Gateway` and its routes. - -**Note:** configuring Contour with a controller name is deprecated and will be removed in a future release. Use a specific gateway reference or dynamic provisioning instead. - -In **dynamic** provisioning, the platform operator first deploys Contour's Gateway provisioner. Then, the platform operator defines a `Gateway` resource, and the provisioner automatically deploys a Contour instance that corresponds to the `Gateway's` configuration and will process that `Gateway` and its routes. - -Static provisioning may be more appropriate for users who prefer the traditional model of deploying Contour, have just a single Contour instance, or have highly customized YAML for deploying Contour. -Dynamic provisioning may be more appropriate for users who want a simple declarative API for provisioning Contour instances. +First, deploy Contour with Gateway API enabled. +This can be done using either [static or dynamic provisioning][6]. ### Option #1: Statically provisioned Create Gateway API CRDs: ```shell -$ kubectl apply -f {{< param github_raw_url>}}/{{< param latest_version >}}/examples/gateway/00-crds.yaml +$ kubectl apply -f {{< param github_raw_url>}}/{{< param branch >}}/examples/gateway/00-crds.yaml ``` Create a GatewayClass: @@ -122,7 +86,7 @@ data: contour.yaml: | gateway: gatewayRef: - name: cotour + name: contour namespace: projectcontour EOF @@ -185,13 +149,13 @@ The above creates: - A `Gateway` resource named `contour` in the `projectcontour` namespace, using the `contour` GatewayClass - Contour and Envoy resources in the `projectcontour` namespace to implement the `Gateway`, i.e. a Contour deployment, an Envoy daemonset, an Envoy service, etc. -See the next section ([Testing the Gateway API](#testing-the-gateway-api)) for how to deploy an application and route traffic to it using Gateway API! +See the next section ([Testing the Gateway API](#test-routing)) for how to deploy an application and route traffic to it using Gateway API! -## Testing the Gateway API +## Configure an HTTPRoute Deploy the test application: ```shell -$ kubectl apply -f {{< param github_raw_url>}}/{{< param latest_version >}}/examples/example-workload/gatewayapi/kuard/kuard.yaml +$ kubectl apply -f {{< param github_raw_url>}}/{{< param branch >}}/examples/example-workload/gatewayapi/kuard/kuard.yaml ``` This command creates: @@ -214,7 +178,7 @@ NAME HOSTNAMES httproute.gateway.networking.k8s.io/kuard ["local.projectcontour.io"] ``` -Test access to the kuard application: +## Test Routing _Note, for simplicity and compatibility across all platforms we'll use `kubectl port-forward` to get traffic to Envoy, but in a production environment you would typically use the Envoy service's address._ @@ -235,44 +199,6 @@ You should receive a 200 response code along with the HTML body of the main `kua You can also open http://local.projectcontour.io:8888/ in a browser. -## Next Steps - -### Customizing your dynamically provisioned Contour instances - -In the dynamic provisioning example, we used a default set of options for provisioning the Contour gateway. -However, Gateway API also [supports attaching parameters to a GatewayClass][5], which can customize the Gateways that are provisioned for that GatewayClass. - -Contour defines a CRD called `ContourDeployment`, which can be used as `GatewayClass` parameters. - -A simple example of a parameterized Contour GatewayClass that provisions Envoy as a Deployment instead of the default DaemonSet looks like: - -```yaml -kind: GatewayClass -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: contour-with-envoy-deployment -spec: - controllerName: projectcontour.io/gateway-controller - parametersRef: - kind: ContourDeployment - group: projectcontour.io - name: contour-with-envoy-deployment-params - namespace: projectcontour ---- -kind: ContourDeployment -apiVersion: projectcontour.io/v1alpha1 -metadata: - namespace: projectcontour - name: contour-with-envoy-deployment-params -spec: - envoy: - workloadType: Deployment -``` - -All Gateways provisioned using the `contour-with-envoy-deployment` GatewayClass would get an Envoy Deployment. - -See [the API documentation][6] for all `ContourDeployment` options. - ### Further reading This guide only scratches the surface of the Gateway API's capabilities. See the [Gateway API website][1] for more information. @@ -282,7 +208,5 @@ This guide only scratches the surface of the Gateway API's capabilities. See the [2]: https://kubernetes.io/ [3]: https://projectcontour.io/resources/compatibility-matrix/ [4]: https://kubernetes.io/docs/tasks/tools/install-kubectl/ -[5]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/#gatewayclass-parameters -[6]: https://projectcontour.io/docs/main/config/api/#projectcontour.io/v1alpha1.ContourDeployment -[7]: https://projectcontour.io/docs/main/config/api/#projectcontour.io/v1alpha1.GatewayConfig -[8]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/#gatewayclass-controller-selection +[5]: /docs/{{< param version >}}/config/gateway-api +[6]: /docs/{{< param version >}}/config/gateway-api#enabling-gateway-api-in-contour \ No newline at end of file diff --git a/site/content/guides/global-rate-limiting.md b/site/content/docs/1.29/guides/global-rate-limiting.md similarity index 85% rename from site/content/guides/global-rate-limiting.md rename to site/content/docs/1.29/guides/global-rate-limiting.md index f13919dc212..99a3c45d1bc 100644 --- a/site/content/guides/global-rate-limiting.md +++ b/site/content/docs/1.29/guides/global-rate-limiting.md @@ -1,6 +1,5 @@ --- title: Global Rate Limiting -layout: page --- Starting in version 1.13, Contour supports [Envoy global rate limiting][1]. @@ -45,7 +44,7 @@ data: ratelimit-config.yaml: | domain: contour descriptors: - + # requests with a descriptor of ["generic_key": "foo"] # are limited to one per minute. - key: generic_key @@ -53,7 +52,7 @@ data: rate_limit: unit: minute requests_per_unit: 1 - + # each unique remote address (i.e. client IP) # is limited to three requests per minute. - key: remote_address @@ -91,7 +90,7 @@ spec: - name: REDIS_URL value: redis:6379 - name: ratelimit - image: docker.io/envoyproxy/ratelimit:6f5de117 + image: docker.io/envoyproxy/ratelimit:19f2079f ports: - containerPort: 8080 name: http @@ -130,7 +129,7 @@ spec: initialDelaySeconds: 5 periodSeconds: 5 volumes: - - name: ratelimit-config + - name: ratelimit-config configMap: name: ratelimit-config ``` @@ -156,7 +155,7 @@ spec: Check the progress of the deployment: ```bash -$ kubectl -n projectcontour get pods -l app=ratelimit +$ kubectl -n projectcontour get pods -l app=ratelimit NAME READY STATUS RESTARTS AGE ratelimit-658f4b8f6b-2hnrf 2/2 Running 0 12s ``` @@ -182,7 +181,7 @@ spec: - name: ratelimit port: 8081 timeoutPolicy: - response: 100ms + response: 100ms ``` Update the Contour configmap to have the following RLS configuration: @@ -292,7 +291,7 @@ $ curl -k http://local.projectcontour.io/test/$((RANDOM)) ## Add global rate limit policies -Now that we have a working application exposed by a `HTTPProxy` resource, we can add add global rate limiting to it. +Now that we have a working application exposed by a `HTTPProxy` resource, we can add global rate limiting to it. Edit the `HTTPProxy` that we created in the previous step to add rate limit policies to both routes: @@ -330,6 +329,75 @@ spec: value: foo ``` +## Default Global rate limit policy + +Contour supports defining a default global rate limit policy in the `rateLimitService` configuration +which is applied to all virtual hosts unless the host is opted-out by +explicitly setting `disabled` to `true`. This is useful for a single-tenant +setup use-case. This means you don't have to edit all HTTPProxy objects with the same rate limit policies, instead you can +define the policies in the `rateLimitService` configuration like this: +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: contour + namespace: projectcontour +data: + contour.yaml: | + rateLimitService: + extensionService: projectcontour/ratelimit + domain: contour + failOpen: false + defaultGlobalRateLimitPolicy: + descriptors: + - entries: + - requestHeader: + headerName: X-Custom-Header + descriptorKey: CustomHeader +``` + +Virtual host can opt out by setting `disabled` to `true`. +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + global: + disabled: true + routes: + - conditions: + - prefix: / + services: + - name: ingress-conformance-echo + port: 80 +``` + +Also, the default global rate limit policy is not applied in case the virtual host defines its own global rate limit policy. +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + global: + descriptors: + - entries: + - remoteAddress: {} + routes: + - conditions: + - prefix: / + services: + - name: ingress-conformance-echo + port: 80 +``` + ## Make requests Before making requests to our `HTTPProxy`, let's quickly revisit the `ratelimit-config` config map. @@ -345,7 +413,7 @@ descriptors: rate_limit: unit: minute requests_per_unit: 1 - + # each unique remote address (i.e. client IP) # is limited to three total requests per minute. - key: remote_address @@ -424,12 +492,12 @@ For more information, see the [Contour rate limiting documentation][7] and the [ The YAML used in this guide is available [in the Contour repository][9]. [1]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting -[2]: /docs/{{< param latest_version >}}/deploy-options/#kind +[2]: ../deploy-options/#kind [3]: https://projectcontour.io/getting-started/#option-1-quickstart [4]: https://github.com/envoyproxy/ratelimit [5]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto [6]: https://github.com/envoyproxy/ratelimit#configuration -[7]: /docs/{{< param latest_version >}}/config/rate-limiting/ -[8]: /docs/{{< param latest_version >}}/config/api/ +[7]: ../config/rate-limiting/ +[8]: ../config/api/ [9]: {{< param github_url>}}/tree/main/examples/ratelimit [10]: https://github.com/lyft/goruntime diff --git a/site/content/guides/grpc.md b/site/content/docs/1.29/guides/grpc.md similarity index 79% rename from site/content/guides/grpc.md rename to site/content/docs/1.29/guides/grpc.md index c9b1811bb8c..12f0d9035fb 100644 --- a/site/content/guides/grpc.md +++ b/site/content/docs/1.29/guides/grpc.md @@ -1,6 +1,5 @@ --- title: Configuring ingress to gRPC services with Contour -layout: page --- ## Example gRPC Service @@ -86,7 +85,7 @@ spec: protocol: h2c ``` -Using the sample deployment above along with this HTTPProxy example, you can test calling this plaintext gRPC server with the following [grpccurl][5] command: +Using the sample deployment above along with this HTTPProxy example, you can test calling this plaintext gRPC server with the following [grpcurl][5] command: ``` grpcurl -plaintext -authority=my-grpc-service.foo.com yages.Echo/Ping @@ -145,10 +144,44 @@ spec: ## Gateway API Configuration -At the moment, configuring gRPC routes with Gateway API resources is achieved by the same method as with Ingress v1: annotation to select a protocol and port on a Service referenced by HTTPRoute `spec.rules[].backendRefs`. +Gateway API now supports a specific resource [GRPCRoute][6] for routing gRPC requests. + +Configuring GRPCRoute for routing gRPC requests needs to specify parentRefs, hostnames, and routing rules with specific backendRefs. In the below example, route path matching is conducted via method matching rule for declared services and their methods. + +```yaml +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: GRPCRoute +metadata: + name: yages +spec: + parentRefs: + - namespace: projectcontour + name: contour + hostnames: + - my-grpc-service.foo.com + rules: + - matches: + - method: + service: yages.Echo + method: Ping + - method: + service: grpc.reflection.v1alpha.ServerReflection + method: ServerReflectionInfo + backendRefs: + - name: grpc-echo + port: 9000 +``` +Using the sample deployment above along with this GRPCRoute example, you can test calling this plaintext gRPC server with the same grpcurl command: + +```yaml +grpcurl -plaintext -authority=my-grpc-service.foo.com yages.Echo/Ping +``` +Note that the second matching method for service of ServerReflection is required by grpcurl command. + +When using GRPCRoute, user should annotate their Service similarly to when using Ingress Configuration, to indicate the protocol to use when connecting to the backend Service, i.e. h2c for HTTP plaintext and h2 for TLS encrypted HTTPS. If it's not specified, Contour will infer the protocol based on the Gateway Listener protocol, h2c for HTTP and h2 for HTTPS. + + -Gateway API does include a specific resource [GRPCRoute][6] for routing gRPC requests. -This may be supported in future versions of Contour. ## gRPC-Web diff --git a/site/content/guides/health-checking.md b/site/content/docs/1.29/guides/health-checking.md similarity index 97% rename from site/content/guides/health-checking.md rename to site/content/docs/1.29/guides/health-checking.md index 2c68df985eb..8e7bcdb5bb5 100644 --- a/site/content/guides/health-checking.md +++ b/site/content/docs/1.29/guides/health-checking.md @@ -1,6 +1,5 @@ --- title: Health Checking -layout: page --- Contour exposes two health endpoints `/health` and `/healthz`. By default these paths are serviced by `0.0.0.0:8000` and are configurable using the `--health-address` and `--health-port` flags. diff --git a/site/content/guides/kind.md b/site/content/docs/1.29/guides/kind.md similarity index 99% rename from site/content/guides/kind.md rename to site/content/docs/1.29/guides/kind.md index e58111ea6ba..dcc374b70af 100644 --- a/site/content/guides/kind.md +++ b/site/content/docs/1.29/guides/kind.md @@ -1,6 +1,5 @@ --- title: Creating a Contour-compatible kind cluster -layout: page --- This guide walks through creating a kind (Kubernetes in Docker) cluster on your local machine that can be used for developing and testing Contour. diff --git a/site/content/guides/metrics/table.md b/site/content/docs/1.29/guides/metrics/table.md similarity index 57% rename from site/content/guides/metrics/table.md rename to site/content/docs/1.29/guides/metrics/table.md index e328cef5c2a..89405d815c6 100644 --- a/site/content/guides/metrics/table.md +++ b/site/content/docs/1.29/guides/metrics/table.md @@ -2,6 +2,8 @@ | ---- | ---- | ------ | ----------- | | contour_build_info | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | branch, revision, version | Build information for Contour. Labels include the branch and git SHA that Contour was built from, and the Contour version. | | contour_cachehandler_onupdate_duration_seconds | [SUMMARY](https://prometheus.io/docs/concepts/metric_types/#summary) | | Histogram for the runtime of xDS cache regeneration. | +| contour_dag_cache_object | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | kind | Total number of items that are currently in the DAG cache. | +| contour_dagrebuild_seconds | [SUMMARY](https://prometheus.io/docs/concepts/metric_types/#summary) | | Duration in seconds of DAG rebuilds | | contour_dagrebuild_timestamp | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | | Timestamp of the last DAG rebuild. | | contour_dagrebuild_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | | Total number of times DAG has been rebuilt since startup | | contour_eventhandler_operation_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind, op | Total number of Kubernetes object changes Contour has received by operation and object kind. | @@ -10,3 +12,9 @@ | contour_httpproxy_orphaned | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace | Total number of orphaned HTTPProxies which have no root delegating to them. | | contour_httpproxy_root | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace | Total number of root HTTPProxies. Note there will only be a single root HTTPProxy per vhost. | | contour_httpproxy_valid | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace, vhost | Total number of valid HTTPProxies. | +| contour_status_update_conflict_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status update conflicts encountered by object kind. | +| contour_status_update_duration_seconds | [SUMMARY](https://prometheus.io/docs/concepts/metric_types/#summary) | error, kind | How long a status update takes to finish. | +| contour_status_update_failed_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status updates that failed by object kind. | +| contour_status_update_noop_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status updates that are no-ops by object kind. This is a subset of successful status updates. | +| contour_status_update_success_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status updates that succeeded by object kind. | +| contour_status_update_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Total number of status updates by object kind. | diff --git a/site/content/guides/prometheus.md b/site/content/docs/1.29/guides/prometheus.md similarity index 98% rename from site/content/guides/prometheus.md rename to site/content/docs/1.29/guides/prometheus.md index f066dc57eba..f0b7364c340 100644 --- a/site/content/guides/prometheus.md +++ b/site/content/docs/1.29/guides/prometheus.md @@ -1,6 +1,5 @@ --- title: Collecting Metrics with Prometheus -layout: page --- @@ -27,7 +26,7 @@ Contour exposes a Prometheus-compatible `/metrics` endpoint that defaults to lis **The metrics endpoint exposes the following metrics:** -{{% include "guides/metrics/table.md" %}} +{{% metrics-table %}} ## Sample Deployment diff --git a/site/content/guides/proxy-proto.md b/site/content/docs/1.29/guides/proxy-proto.md similarity index 78% rename from site/content/guides/proxy-proto.md rename to site/content/docs/1.29/guides/proxy-proto.md index dafbcd6df23..7753d8c5776 100644 --- a/site/content/guides/proxy-proto.md +++ b/site/content/docs/1.29/guides/proxy-proto.md @@ -1,6 +1,5 @@ --- title: How to Configure PROXY v1/v2 Support -layout: page --- If you deploy Contour as a Deployment or Daemonset, you will likely use a `type: LoadBalancer` Service to request an [external load balancer][1] from your hosting provider. @@ -36,15 +35,13 @@ spec: ... ``` -**NOTE**: The service annotation `service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*'` used to toggle the PROXY protocol is found to have no effect on NLBs (Due to this open [issue][2]). Hence, follow the steps mentioned in this AWS [documentation][3] to manually toggle PROXY protocol on NLBs - ## Enable PROXY protocol support for all Envoy listening ports ``` ... spec: containers: - - image: ghcr.io/projectcontour/contour:{{< param latest_version >}} + - image: ghcr.io/projectcontour/contour: imagePullPolicy: Always name: contour command: ["contour"] @@ -53,6 +50,4 @@ spec: ``` [0]: http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt -[1]: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer -[2]: https://github.com/kubernetes/kubernetes/issues/57250 -[3]: https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#enable-proxy-protocol +[1]: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer \ No newline at end of file diff --git a/site/content/guides/resource-limits.md b/site/content/docs/1.29/guides/resource-limits.md similarity index 99% rename from site/content/guides/resource-limits.md rename to site/content/docs/1.29/guides/resource-limits.md index 1e811d27c35..a531221a88f 100644 --- a/site/content/guides/resource-limits.md +++ b/site/content/docs/1.29/guides/resource-limits.md @@ -1,6 +1,5 @@ --- title: Contour / Envoy Resource Limits -layout: page --- ## Performance Testing Contour / Envoy diff --git a/site/content/docs/1.29/img/archoverview.png b/site/content/docs/1.29/img/archoverview.png new file mode 100644 index 00000000000..f79bbfe1b4b Binary files /dev/null and b/site/content/docs/1.29/img/archoverview.png differ diff --git a/site/content/docs/1.29/img/contour_deployment_in_k8s.png b/site/content/docs/1.29/img/contour_deployment_in_k8s.png new file mode 100644 index 00000000000..add5e554a07 Binary files /dev/null and b/site/content/docs/1.29/img/contour_deployment_in_k8s.png differ diff --git a/site/content/docs/1.29/img/shutdownmanager.png b/site/content/docs/1.29/img/shutdownmanager.png new file mode 100644 index 00000000000..ab8b7821d3c Binary files /dev/null and b/site/content/docs/1.29/img/shutdownmanager.png differ diff --git a/site/content/docs/1.29/img/source/shutdownmanager.drawio b/site/content/docs/1.29/img/source/shutdownmanager.drawio new file mode 100644 index 00000000000..99b86620c42 --- /dev/null +++ b/site/content/docs/1.29/img/source/shutdownmanager.drawio @@ -0,0 +1 @@ +7Vtbc9o4FP41zOw+kLF84fKYG2236ZTZZKbNo7AFdiNbVBYJ9NfvkS3fjQ3EYWlKXmIdyUdC33duEvSMa3/9geOl+4U5hPZ0zVn3jJueriNkIvgnJZtYMhqYsWDBPUcNygT33i+ihJqSrjyHhIWBgjEqvGVRaLMgILYoyDDn7KU4bM5ocdYlXpCK4N7GtCr95jnCTT6XpmUdH4m3cNXUI0t1zLD9tOBsFaj5eroxj/7ibh8nutT40MUOe8mJjNuecc0ZE/GTv74mVO5tsm3xe5Mtvem6OQnELi8MZ3iGkW3ObH04N2daX481PGO6UntxGzyzjVqt2CQ7BAtfyseVT++8OaFeAK2rJeGeTwTh0EOVeJrJrl5cT5D7Jbblqy/AHZC5wqfQQvAIcAoMr/C0TSleht4smlUDCSf2iofeM/mXhDFrpJSthJzpOmVDNFSiQBylKt3oWK/v2WoYxTNCr1LYrhllcvqARR8oFJw9pRyQ785hjRPse1RS+25lew6GnYGpQyZXGfUrQiOA8wpTbxFAwwZEoj2oQqRQeyZckHVOpCD7QBjsHwcMNNVrJjxMzEs1X3JcTYa4OZoOEiFW9rFIVWccgQdFkx0pkxhtjjMVuuRAXjIvENH81lXPuimxhnHhsgULMM3zJsNSy2OpnR6WWw1qd3CtIraoBtsqtOZw/AbQGhVk792VgM0PQPoFB+AG+dk1dEanBcVhqCbvwE1Y1km5iSqZzm6iYmkHu4k6bGvcxKgDaBff6cPPZ775yZxBXzy6/6zNSR9ZFXinLHrt65IE8X5JE/Rg25pwlzvgQSZ2qTZxxoRgPnSQwLmUqZ2UUWY/tQK5L2yEziLtyQqkyIG0UC0zo9xtJr0Cn/OcepLdcZaKd0FZuxho5riAtGpxQrEAb1fMfWtQVbqn0p620scYDIoaQrbiNlEv5RPIZj2mZhX1CMwXRFT0AJJ4kxumrH3rcvuolPIkC962rsoLycoyjsdrKL2eLIjN5yERvbJVpAgd5gNHNS5wQIUiIzwv5PPnFdBaTh53wSz53nO8PaVUHILlCcXY8TnEbne9o32xPaVMHKEKtFMOUYgtZTRZEzs6DfF9HDjw9Jc0X/Dgsi8u37VQJe5/n2jwzUXaKBDng2xdZA5gR7+DrK9d6En7UbLvwhiaieBmrfgYtzb5Vo7VzQl3HMJastrdA7pmIrOTEG6gUgw3Sy5l1xhujbVmRVuC+LGiZrJfOe5/fHiYgh5delHt6+f3wWkHh25DLqkIEqPanF42Una0L2Mt9EaMhcUdytjxRYuqjhJPs2QbyTzbVmaUam7Lahlf1l8cf5Q0tbaeG1ZsTh0EazccEsPfoqDb0/62mlyrqbzSLqxxqYpCB3py02pRtMUquiJNNf+8g10JSAgM0aaczUhS1Mx4Vs9MXIKpcH+9cxY1OuU90wjIetDQ0gtg9y2jIy89LOhFY3QgG80WRa15RfJpLbP+k769G6zJu7eV7DyAbFIS/XL66Vy7/wa1O0JFAzpq7V7PNr2GbX9qAd9sj7/vQXm1mnkg3PcCLIiMkszpKg6mNXJa8z7uhO67zbPQsFToHppnGeXT6CPnWWhQ4VB2GhTXxtpHxp7gH3j4JSBHXksqJm9xSjUqdCsejGRr7YmUbfAcn8ZAats13w7nTy57QokneW22pJcKPkM/LMkpn8JUFLWS8wjZUPUCI6kKJ9ijEd2w4xUT/k54d0InM7C4iSf3rfnYsJWMSTI77IaHWjHZNvemT+IkBy2KjnsaWMvDxOYKl80QN7U0kp6D6FsF0YrDK2dKux9WtCh64yCq15V25xOIN6ZPK+o7nwGPjkYfM+gPfiB0F5DBT/poDb0f80/9pgu5Qgr2HiiV5nYX40J2ZxpD1c6u2mRjk2vsfNHWeLMx/n+8mzHsyLtVFB03jNZSeL/Thj+TraXUL7t1lnlS4d5ZaT+xe+fXuutBhcYXhm4cZhOVi+YObWLvi70t9ll78daVwdV9BXYSpl+pLtmexPZOGlLxeLdydFY2TN9znMg0uDzdxdmxb/W8sEq+RkdRPnRLf4GjJunlf8VSf5lsmGOl7ZXM7MvvUqAChv3yMcwhrhOa2e9v4uHZj5yM2/8A \ No newline at end of file diff --git a/site/content/docs/1.29/redeploy-envoy.md b/site/content/docs/1.29/redeploy-envoy.md new file mode 100644 index 00000000000..2456b53d2bf --- /dev/null +++ b/site/content/docs/1.29/redeploy-envoy.md @@ -0,0 +1,72 @@ +# Redeploying Envoy + +The Envoy process, the data path component of Contour, at times needs to be re-deployed. +This could be due to an upgrade, a change in configuration, or a node-failure forcing a redeployment. + +When implementing this roll out, the following steps should be taken: + +1. Stop Envoy from accepting new connections +2. Start draining existing connections in Envoy by sending a `POST` request to `/healthcheck/fail` endpoint +3. Wait for connections to drain before allowing Kubernetes to `SIGTERM` the pod + +## Overview + +Contour implements an `envoy` sub-command named `shutdown-manager` whose job is to manage a single Envoy instances lifecycle for Kubernetes. +The `shutdown-manager` runs as a new container alongside the Envoy container in the same pod. +It uses a Kubernetes `preStop` event hook to keep the Envoy container running while waiting for connections to drain. The `/shutdown` endpoint blocks until the connections are drained. + +```yaml + - name: shutdown-manager + command: + - /bin/contour + args: + - envoy + - shutdown-manager + image: ghcr.io/projectcontour/contour:main + imagePullPolicy: Always + lifecycle: + preStop: + exec: + command: + - /bin/contour + - envoy + - shutdown +``` + +The Envoy container also has some configuration to implement the shutdown manager. +First the `preStop` hook is configured to use the `/shutdown` endpoint which blocks the Envoy container from exiting. +Finally, the pod's `terminationGracePeriodSeconds` is customized to extend the time in which Kubernetes will allow the pod to be in the `Terminating` state. +The termination grace period defines an upper bound for long-lived sessions. +If during shutdown, the connections aren't drained to the configured amount, the `terminationGracePeriodSeconds` will send a `SIGTERM` to the pod killing it. + +![shutdown-manager overview][1] + +### Shutdown Manager Config Options + +The `shutdown-manager` runs as another container in the Envoy pod. +When the pod is requested to terminate, the `preStop` hook on the `shutdown-manager` executes the `contour envoy shutdown` command initiating the shutdown sequence. + +The shutdown manager has a single argument that can be passed to change how it behaves: + +| Name | Type | Default | Description | +|------------|------|---------|-------------| +| serve-port | integer | 8090 | Port to serve the http server on | +| ready-file | string | /admin/ok | File to poll while waiting shutdown to be completed. | + +### Shutdown Config Options + +The `shutdown` command does the work of draining connections from Envoy and polling for open connections. + +The shutdown command has a few arguments that can be passed to change how it behaves: + +| Name | Type | Default | Description | +|------------|------|---------|-------------| +| check-interval | duration | 5s | Time interval to poll Envoy for open connections. | +| check-delay | duration | 0s | Time wait before polling Envoy for open connections. | +| drain-delay | duration | 0s | Time wait before draining Envoy connections. | +| min-open-connections | integer | 0 | Min number of open connections when polling Envoy. | +| admin-port (Deprecated) | integer | 9001 | Deprecated: No longer used, Envoy admin interface runs as a unix socket. | +| admin-address | string | /admin/admin.sock | Path to Envoy admin unix domain socket. | +| ready-file | string | /admin/ok | File to write when shutdown is completed. | + + [1]: ../img/shutdownmanager.png diff --git a/site/content/docs/1.29/start-contributing.md b/site/content/docs/1.29/start-contributing.md new file mode 100644 index 00000000000..2ddefb6c485 --- /dev/null +++ b/site/content/docs/1.29/start-contributing.md @@ -0,0 +1,130 @@ +# Getting Started with Contributing + +Thanks for your interest in contributing to Contour. Community contributions are always needed, welcome, and appreciated. This guide shows how you can contribute to Contour in the following areas: + +- Code +- Website +- Documentation + +Please familiarize yourself with the [Code of Conduct][1] and project [Philosophy][15] before contributing. + +# Getting Started with Code + +Everything is managed on the [Project Contour GitHub][2] organization. Create an issue for a new idea or look for issues labeled **good first issue** to get started. + +## How we work + +See [How We Work][3] for an overview: +- Issue management +- Code reviews +- Coding practice +- GitHub labels + +## Contribution workflow + +Review the [Contribution workflow][4] to understand how to work with the code. + +Below is a list of workflow areas: +- Building from source +- Contribution workflow +- Contour testing +- Developer Certificate of Origin (DCO) sign off + +# Getting Started with the Website + +Updates, corrections, or improvements are managed through [GitHub][16] issues. + +When you are ready to take on an issue, see [Website Contribution Guidelines][5] to understand how the Contour website contributions are managed. There is information on: +- Site structure +- Link formatting +- Testing +- Setting up your environment + +# Getting Started with Documentation + +Documentation is critical to the success of any project. Open to all levels, Contour needs help to create and update its documentation. Join the [Contour Community Meetings][8] meeting and learn more about the Tech Docs Working Group. + +Review the [Contour Technical Documentation Contributing Guide][6] for instructions to set up your environment. + +Technical documentation will follow the [Website Contribution Guidelines][5]. + +## New documentation suggestions + +If you have a document suggestion, create an issue in [GitHub][16]. The team will triage and prioritize the issue. Connect on Slack or in a meeting to discuss your issue or request. + +## Helping with identified document issues + +Take a look at the project issues list with the label **area/documentation**. If you are new to technical writing, add in the **good first issue** label: +[area/documentation and good first issue][7] + +Reach out on Slack or a Contour meeting for any assistance. Help is always appreciated. + +# Filing and Working on Issues + +Whether code, website, or documentation, Contour uses GitHub to create, track, and manage all issues. + +If there is a fix or a suggestion for improvement, create an issue in [GitHub][16]. + +All issues are reviewed and evaluated by the Contour team. + +# Meet the Community and the Team + +To find out more about contributing to Contour, connect with us at a Contour Community Meeting, on Slack, or through the mailing list. We also have an Office Hours meeting to answer “How do I…” questions. + +## Contour Community meetings + +Discuss issues, features, or suggestions with the Contour team and other community members. Ask anything and find out more about Contour. + +Ask questions: +- “How do I do this in Contour?” +- “Why does Contour do this thing this way?” +- “Where can I find…?” + +See the [Community][8] page for: +- Meeting schedule +- Meeting notes with zoom link +- Meeting recordings + +## Mailing list + +To get email updates to Contour, join the [mailing list][10]. Topics include: +- Release notifications +- Issues +- Feedback and suggestions +- Meeting notifications + +## Find us +There are many ways to connect with the Contour team: + +- Slack: Kubernetes [#contour][11] +- Contour YouTube Channel: [CNCF Contour][12] +- Twitter: [@projectcontour][13] +- GitHub: [projectcontour][14] + +# Want More Contributing Information? + +Slack or a meeting is a great way to introduce yourself. Let us know what you are interested in, your background, and what you want to accomplish. + +# Next steps + +Come out and join a [Community meeting][8] or an [Office Hours meeting][9]. Ask questions about how to get started or just sit back and get to know the team. + + + +[1]: {{< param github_url >}}/blob/main/CODE_OF_CONDUCT.md +[2]: https://github.com/projectcontour +[3]: {{< relref "resources/how-we-work.md" >}} +[4]: {{< param github_url >}}/blob/main/CONTRIBUTING.md +[5]: {{< param github_url >}}/blob/main/SITE_CONTRIBUTION.md +[6]: {{< relref "resources/contributing-docs.md" >}} +[7]: {{< param github_url >}}/issues/?q=is%3Aopen+is%3Aissue+label%3Aarea%2Fdocumentation+label%3A%22good+first+issue%22 +[8]: {{< relref "community.md" >}} +[9]: https://github.com/projectcontour/community/wiki/Office-Hours +[10]: https://lists.cncf.io/g/cncf-contour-users/ +[11]: {{< param slack_url >}} +[12]: https://www.youtube.com/channel/UCCde7QSfcyYJ8AuXofD5bTA +[13]: https://twitter.com/projectcontour +[14]: https://github.com/projectcontour +[15]: {{< relref "resources/philosophy.md" >}} +[16]: {{< param github_url >}}/issues/ +[17]: {{< param github_url >}}/ \ No newline at end of file diff --git a/site/content/docs/1.29/troubleshooting.md b/site/content/docs/1.29/troubleshooting.md new file mode 100644 index 00000000000..28461bd8641 --- /dev/null +++ b/site/content/docs/1.29/troubleshooting.md @@ -0,0 +1,41 @@ +## Troubleshooting + +If you encounter issues, follow the guides below for help. For topics not covered here, you can [file an issue][0], or talk to us on the [#contour channel][1] on Kubernetes Slack. + +### [Troubleshooting Common Proxy Errors][2] +A guide on how to investigate common errors with Contour and Envoy. + +### [Envoy Administration Access][3] +Review the linked steps to learn how to access the administration interface for your Envoy instance. + +### [Contour Debug Logging][4] +Learn how to enable debug logging to diagnose issues between Contour and the Kubernetes API. + +### [Envoy Debug Logging][5] +Learn how to enable debug logging to diagnose TLS connection issues. + +### [Visualize the Contour Graph][6] +Learn how to visualize Contour's internal object graph in [DOT][9] format, or as a png file. + +### [Show Contour xDS Resources][7] +Review the linked steps to view the [xDS][10] resource data exchanged by Contour and Envoy. + +### [Profiling Contour][8] +Learn how to profile Contour by using [net/http/pprof][11] handlers. + +### [Envoy container stuck in unready/draining state][12] +Read the linked document if you have Envoy containers stuck in an unready/draining state. + +[0]: {{< param github_url >}}/issues +[1]: {{< param slack_url >}} +[2]: /docs/{{< param version >}}/troubleshooting/common-proxy-errors/ +[3]: /docs/{{< param version >}}/troubleshooting/envoy-admin-interface/ +[4]: /docs/{{< param version >}}/troubleshooting/contour-debug-log/ +[5]: /docs/{{< param version >}}/troubleshooting/envoy-debug-log/ +[6]: /docs/{{< param version >}}/troubleshooting/contour-graph/ +[7]: /docs/{{< param version >}}/troubleshooting/contour-xds-resources/ +[8]: /docs/{{< param version >}}/troubleshooting/profiling-contour/ +[9]: https://en.wikipedia.org/wiki/Dot +[10]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol +[11]: https://golang.org/pkg/net/http/pprof/ +[12]: /docs/{{< param version >}}/troubleshooting/envoy-container-draining/ diff --git a/site/content/docs/1.29/troubleshooting/common-proxy-errors.md b/site/content/docs/1.29/troubleshooting/common-proxy-errors.md new file mode 100644 index 00000000000..e05f153242d --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/common-proxy-errors.md @@ -0,0 +1,96 @@ +# Troubleshooting Common Proxy Errors + +## Unexpected HTTP errors + +Here are some steps to take in investigating common HTTP errors that users may encounter. +We'll include example error cases to debug with these steps. + +1. Inspect the HTTP response in detail (possibly via `curl -v`). + + Here we're looking to validate if the error response is coming from the backend app, Envoy, or possibly another proxy in front of Envoy. + If the response has the `server: envoy` header set, the request at least made it to the Envoy proxy so we can likely rule out anything before it. + The error may originate from Envoy itself or the backend app. + Look for headers or a response body that may originate from the backend app to verify if the error is in fact just the intended app behavior. + In the example below, we can see the response looks like it originates from Envoy, based on the `server: envoy` header and response body string. + + ``` + curl -vvv example.projectcontour.io + ... + > GET / HTTP/1.1 + > Host: example.projectcontour.io + ... + > + < HTTP/1.1 503 Service Unavailable + < content-length: 91 + < content-type: text/plain + < vary: Accept-Encoding + < date: Tue, 06 Feb 2024 03:44:30 GMT + < server: envoy + < + * Connection #0 to host example.projectcontour.io left intact + upstream connect error or disconnect/reset before headers. reset reason: connection failure + ``` + +1. Look at the Envoy pod logs for the access logs corresponding to the erroring request/response. + + The exact fields/field ordering present in the access log may vary if you have [configured a custom access log string or JSON access logs][0]. + For example for a Contour installation using the [default Envoy access log format][1] we would want to inspect: + * `%REQ(:METHOD)%`, `%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%`, `%REQ(:AUTHORITY)%`, `%PROTOCOL%`: Ensure these are sensible values based on your configured route and HTTP request + * `%RESPONSE_FLAGS%`: See the [documentation on Envoy response flags][2] and below how to interpret a few of them in a Contour context: + * `UF`: Likely that Envoy could not connect to the upstream + * `UH`: Upstream Service has no health/ready pods + * `NR`: No configured route matching the request + * `%DURATION%`: Can correlate this with any configured timeouts + * `%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%`: Can correlate this with any configured timeouts. If `-` then this is a hint the request was never forwarded to the upstream. + * `%UPSTREAM_HOST%`: This is the IP of the upstream pod that was selected to proxy the request to and can be used to verify the exact upstream instance that might be erroring. + + For example in this access log: + + ``` + [2024-02-06T15:18:17.437Z] "GET / HTTP/1.1" 503 UF 0 91 1998 - "103.67.2.26" "curl/8.4.0" "d70640ec-2feb-46f8-9f63-24c44142c42e" "example.projectcontour.io" "10.244.8.27:8080" + ``` + + We can see the `UF` response flag as the cause of the `503` response code. + We also see the `-` for upstream request time. + It is likely in this case that Envoy was not able to establish a connection to the upstream. + That is further supported by the request duration of `1998` which is approximately the default upstream connection timeout of `2s`. + +1. Inspect Envoy metrics + + This method of debugging can be useful especially for deployments that service a large volume of traffic. + In this case, access logs are possibly not suitable to use, as the volume of logs may be too large to pinpoint an exact erroring request. + + Metrics from individual Envoy instances can be viewed manually or scraped using Envoy's prometheus endpoints and graphed using common visualization tools. + See the `/stats/prometheus` endpoint of the [Envoy admin interface][3]. + + Metrics that may be useful to inspect: + * [Listener metrics][4] + * `downstream_cx_total` + * `ssl.connection_error` + * [HTTP metrics][5] + * `downstream_cx_total` + * `downstream_cx_protocol_error` + * `downstream_rq_total` + * `downstream_rq_rx_reset` + * `downstream_rq_tx_reset` + * `downstream_rq_timeout` + * `downstream_rq_5xx` (and other status code groups) + * [Upstream metrics][6] + * `upstream_cx_total` + * `upstream_cx_connect_fail` + * `upstream_cx_connect_timeout` + * `upstream_rq_total` + * `upstream_rq_timeout` + +1. Send a direct request to the backend app to narrow down where the error may be originating. + + This can be done via a port-forward to send a request to the app directly, skipping over the Envoy proxy. + If this sort of request succeeds, we know the issue likely originates from Contour configuration or the Envoy proxy rather than the app itself. + +[0]: /docs/{{< param latest_version >}}/config/access-logging/ +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string +[2]: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-response-flags +[3]: /docs/{{< param latest_version >}}/guides/prometheus/#envoy-metrics +[4]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/stats +[5]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/stats +[6]: https://www.envoyproxy.io/docs/envoy/latest/configuration/upstream/cluster_manager/cluster_stats diff --git a/site/content/docs/1.29/troubleshooting/contour-debug-log.md b/site/content/docs/1.29/troubleshooting/contour-debug-log.md new file mode 100644 index 00000000000..821634242c6 --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/contour-debug-log.md @@ -0,0 +1,6 @@ +# Enabling Contour Debug Logging + +The `contour serve` subcommand has two command-line flags that can be helpful for debugging. +The `--debug` flag enables general Contour debug logging, which logs more information about how Contour is processing API resources. +The `--kubernetes-debug` flag enables verbose logging in the Kubernetes client API, which can help debug interactions between Contour and the Kubernetes API server. +This flag requires an integer log level argument, where higher number indicates more detailed logging. diff --git a/site/content/docs/1.29/troubleshooting/contour-graph.md b/site/content/docs/1.29/troubleshooting/contour-graph.md new file mode 100644 index 00000000000..5abcfeb22af --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/contour-graph.md @@ -0,0 +1,25 @@ +# Visualizing Contour's Internal Object Graph + +Contour models its configuration using a directed acyclic graph (DAG) of internal objects. +This can be visualized through a debug endpoint that outputs the DAG in [DOT][2] format. +To visualize the graph, you must have [`graphviz`][3] installed on your system. + +To download the graph and save it as a PNG: + +```bash +# Port forward into the contour pod +$ CONTOUR_POD=$(kubectl -n projectcontour get pod -l app=contour -o name | head -1) +# Do the port forward to that pod +$ kubectl -n projectcontour port-forward $CONTOUR_POD 6060 +# Download and store the DAG in png format +$ curl localhost:6060/debug/dag | dot -T png > contour-dag.png +``` + +The following is an example of a DAG that maps `http://kuard.local:80/` to the +`kuard` service in the `default` namespace: + +![Sample DAG][4] + +[2]: https://en.wikipedia.org/wiki/DOT +[3]: https://graphviz.gitlab.io/ +[4]: /img/kuard-dag.png diff --git a/site/content/docs/1.29/troubleshooting/contour-xds-resources.md b/site/content/docs/1.29/troubleshooting/contour-xds-resources.md new file mode 100644 index 00000000000..69f413a8cb3 --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/contour-xds-resources.md @@ -0,0 +1,19 @@ +# Interrogate Contour's xDS Resources + +Sometimes it's helpful to be able to interrogate Contour to find out exactly what [xDS][1] resource data it is sending to Envoy. +Contour ships with a `contour cli` subcommand which can be used for this purpose. + +Because Contour secures its communications with Envoy using Secrets in the cluster, the easiest way is to run `contour cli` commands _inside_ the pod. +Do this is via `kubectl exec`: + +```bash +# Get one of the pods that matches the examples/daemonset +$ CONTOUR_POD=$(kubectl -n projectcontour get pod -l app=contour -o jsonpath='{.items[0].metadata.name}') +# Do the port forward to that pod +$ kubectl -n projectcontour exec $CONTOUR_POD -c contour -- contour cli lds --cafile=/certs/ca.crt --cert-file=/certs/tls.crt --key-file=/certs/tls.key +``` + +Which will stream changes to the LDS api endpoint to your terminal. +Replace `contour cli lds` with `contour cli rds` for route resources, `contour cli cds` for cluster resources, and `contour cli eds` for endpoints. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol diff --git a/site/content/docs/1.29/troubleshooting/envoy-admin-interface.md b/site/content/docs/1.29/troubleshooting/envoy-admin-interface.md new file mode 100644 index 00000000000..c44b6fe3e9d --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/envoy-admin-interface.md @@ -0,0 +1,32 @@ +# Accessing the Envoy Administration Interface + +Getting access to the Envoy [administration interface][1] can be useful for diagnosing issues with routing or cluster health. +However, Contour doesn't expose the entire Envoy Administration interface since that interface contains many options, such as shutting down Envoy or draining traffic. +To prohibit this behavior, Contour only exposes the read-only options from the admin interface which still allows for debugging Envoy, but without the options mentioned previously. + +Those endpoints are: + - /certs + - /clusters + - /listeners + - /config_dump + - /memory + - /ready + - /runtime + - /server_info + - /stats + - /stats/prometheus + - /stats/recentlookups + +The Envoy administration interface is bound by default to `http://127.0.0.1:9001`. +To access it from your workstation use `kubectl port-forward` like so: + +```sh +# Get one of the pods that matches the Envoy daemonset +ENVOY_POD=$(kubectl -n projectcontour get pod -l app=envoy -o name | head -1) +# Do the port forward to that pod +kubectl -n projectcontour port-forward $ENVOY_POD 9001 +``` + +Then navigate to `http://127.0.0.1:9001/` to access the administration interface for the Envoy container running on that pod. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin diff --git a/site/content/docs/1.29/troubleshooting/envoy-container-draining.md b/site/content/docs/1.29/troubleshooting/envoy-container-draining.md new file mode 100644 index 00000000000..82bb47cb883 --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/envoy-container-draining.md @@ -0,0 +1,29 @@ +# Envoy container stuck in unready/draining state + +It's possible for the Envoy containers to become stuck in an unready/draining state. +This is an unintended side effect of the shutdown-manager sidecar container being restarted by the kubelet. +For more details on exactly how this happens, see [this issue][1]. + +If you observe Envoy containers in this state, you should `kubectl delete` them to allow new Pods to be created to replace them. + +To make this issue less likely to occur, you should: +- ensure you have [resource requests][2] on all your containers +- ensure you do **not** have a liveness probe on the shutdown-manager sidecar container in the envoy daemonset (this was removed from the example YAML in Contour 1.24.0). + +If the above are not sufficient for preventing the issue, you may also add a liveness probe to the envoy container itself, like the following: + +```yaml +livenessProbe: + httpGet: + path: /ready + port: 8002 + initialDelaySeconds: 15 + periodSeconds: 5 + failureThreshold: 6 +``` + +This will cause the kubelet to restart the envoy container if it does get stuck in this state, resulting in a return to normal operations load balancing traffic. +Note that in this case, it's possible that a graceful drain of connections may or may not occur, depending on the exact sequence of operations that preceded the envoy container failing the liveness probe. + +[1]: https://github.com/projectcontour/contour/issues/4851 +[2]: /docs/{{< param latest_version >}}/deploy-options/#setting-resource-requests-and-limits \ No newline at end of file diff --git a/site/content/docs/1.29/troubleshooting/envoy-debug-log.md b/site/content/docs/1.29/troubleshooting/envoy-debug-log.md new file mode 100644 index 00000000000..bfef4fa5531 --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/envoy-debug-log.md @@ -0,0 +1,8 @@ +# Enabling Envoy Debug Logging + +The `envoy` command has a `--log-level` [flag][1] that can be useful for debugging. +By default, it's set to `info`. +To change it to `debug`, edit the `envoy` DaemonSet in the `projectcontour` namespace and replace the `--log-level info` flag with `--log-level debug`. +Setting the Envoy log level to `debug` can be particilarly useful for debugging TLS connection failures. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/operations/cli diff --git a/site/content/docs/1.29/troubleshooting/profiling-contour.md b/site/content/docs/1.29/troubleshooting/profiling-contour.md new file mode 100644 index 00000000000..95bb0164210 --- /dev/null +++ b/site/content/docs/1.29/troubleshooting/profiling-contour.md @@ -0,0 +1,14 @@ +# Accessing Contour's /debug/pprof Service + +Contour exposes the [net/http/pprof][1] handlers for `go tool pprof` and `go tool trace` by default on `127.0.0.1:6060`. +This service is useful for profiling Contour. +To access it from your workstation use `kubectl port-forward` like so, + +```bash +# Get one of the pods that matches the Contour deployment +$ CONTOUR_POD=$(kubectl -n projectcontour get pod -l app=contour -o name | head -1) +# Do the port forward to that pod +$ kubectl -n projectcontour port-forward $CONTOUR_POD 6060 +``` + +[1]: https://golang.org/pkg/net/http/pprof diff --git a/site/content/docs/1.30/_index.md b/site/content/docs/1.30/_index.md new file mode 100644 index 00000000000..d78f3f1571f --- /dev/null +++ b/site/content/docs/1.30/_index.md @@ -0,0 +1,48 @@ +--- +cascade: + layout: docs + version: "1.30" + branch: release-1.30 +--- + +## Overview +Contour is an Ingress controller for Kubernetes that works by deploying the [Envoy proxy][1] as a reverse proxy and load balancer. +Contour supports dynamic configuration updates out of the box while maintaining a lightweight profile. + +## Philosophy +- Follow an opinionated approach which allows us to better serve most users +- Design Contour to serve both the cluster administrator and the application developer +- Use our experience with ingress to define reasonable defaults for both cluster administrators and application developers. +- Meet users where they are by understanding and adapting Contour to their use cases + +See the full [Contour Philosophy][8] page. + +## Why Contour? +Contour bridges other solution gaps in several ways: +- Dynamically update the ingress configuration with minimal dropped connections +- Safely support multiple types of ingress config in multi-team Kubernetes clusters + - [Ingress/v1][10] + - [HTTPProxy (Contour custom resource)][2] + - [Gateway API][9] +- Cleanly integrate with the Kubernetes object model + +## Prerequisites +Contour is tested with Kubernetes clusters running version [1.21 and later][4]. + +## Get started +Getting started with Contour is as simple as one command. +See the [Getting Started][3] document. + +## Troubleshooting +If you encounter issues review the [troubleshooting][5] page, [file an issue][6], or talk to us on the [#contour channel][7] on Kubernetes slack. + +[1]: https://www.envoyproxy.io/ +[2]: config/fundamentals.md +[3]: /getting-started +[4]: /resources/compatibility-matrix.md +[5]: /docs/main/troubleshooting +[6]: https://github.com/projectcontour/contour/issues +[7]: https://kubernetes.slack.com/messages/contour +[8]: /resources/philosophy +[9]: guides/gateway-api +[10]: /docs/{{< param version >}}/config/ingress diff --git a/site/content/docs/1.30/architecture.md b/site/content/docs/1.30/architecture.md new file mode 100644 index 00000000000..b29cb409d39 --- /dev/null +++ b/site/content/docs/1.30/architecture.md @@ -0,0 +1,74 @@ +# Contour Architecture + +The Contour Ingress controller is a collaboration between: + +* Envoy, which provides the high performance reverse proxy. +* Contour, which acts as a management server for Envoy and provides it with configuration. + +These containers are deployed separately, Contour as a Deployment and Envoy as a Kubernetes Daemonset or Deployment, although other configurations are possible. + +In the Envoy Pods, Contour runs as an initcontainer in `bootstrap` mode and writes an Envoy bootstrap configuration to a temporary volume. +This volume is passed to the Envoy container and directs Envoy to treat Contour as its [management server][1]. + +After initialization is complete, the Envoy container starts, retrieves the bootstrap configuration written by Contour's `bootstrap` mode, and establishes a GRPC session with Contour to receive configuration. + +Envoy will gracefully retry if the management server is unavailable, which removes any container startup ordering issues. + +Contour is a client of the Kubernetes API. +Contour watches Ingress, HTTPProxy, Gateway API, Secret, Service, and Endpoint objects, and acts as the management server for its Envoy sibling by translating its cache of objects into the relevant JSON stanzas: Service objects for CDS, Ingress for RDS, Endpoint objects for EDS, and so on). + +The transfer of information from Kubernetes to Contour is by watching the Kubernetes API utilizing [controller-runtime][4] primitives. + +Kubernetes readiness probes are configured to check whether Envoy is ready to accept connections. +The Envoy readiness probe sends GET requests to `/ready` in Envoy's administration endpoint. + +For Contour, a liveness probe checks the `/healthz` running on the Pod's metrics port. +Readiness probe is a check that Contour can access the Kubernetes API. + +## Architectural Overview +Below are a couple of high level architectural diagrams of how Contour works inside a Kubernetes cluster as well as showing the data path of a request to a backend pod. + +A request to `projectcontour.io/blog` gets routed via a load balancer to an instance of an Envoy proxy which then sends the request to a pod. + +![architectural overview][2] + +Following is a diagram of how Contour and Envoy are deployed in a Kubernetes cluster. + +### Kubernetes API Server + +The following API objects are watched: +- Services +- Endpoints +- Secrets +- Ingress +- HTTPProxy +- Gateway API (Optional) + +### Contour Deployment + +Contour is deployed in the cluster using a Kubernetes Deployment. +It has built-in leader election which is responsible for updating httproxy/ingress/gateway api resources via Kube API server. +All instances are able to serve xDS configuration to any Envoy instance, but only the leader can write status back to the API server. + +The data being served from contour instances are eventually consistent in an HA based deployment. +However HA mode is operationally scalable when you have high request rate from envoy to contour as requests are loadbalanced among contour instances. +This also helps availability zone /data center degradation events as your service continue to function. + +### Envoy Deployment + +Envoy can be deployed in two different models, as a Kubernetes Daemonset or as a Kubernetes Deployment. + +Daemonset is the standard deployment model where a single instance of Envoy is deployed per Kubernetes Node. +This allows for simple Envoy pod distribution across the cluster as well as being able to expose Envoy using `hostPorts` to improve network performance. +One potential downside of this deployment model is when a node is removed from the cluster (e.g. on a cluster scale down, etc) then the configured `preStop` hooks are not available so connections can be dropped. +This is a limitation that applies to any Daemonset in Kubernetes. + +An alternative Envoy deployment model is utilizing a Kubernetes Deployment with a configured `podAntiAffinity` which attempts to mirror the Daemonset deployment model. +A benefit of this model compared to the Daemonset version is when a node is removed from the cluster, the proper shutdown events are available so connections can be cleanly drained from Envoy before terminating. + +![architectural overview 2][3] + +[1]: https://www.envoyproxy.io/docs/envoy/v1.13.0/api-docs/xds_protocol +[2]: ../img/archoverview.png +[3]: ../img/contour_deployment_in_k8s.png +[4]: https://github.com/kubernetes-sigs/controller-runtime diff --git a/site/content/docs/1.30/config/access-logging.md b/site/content/docs/1.30/config/access-logging.md new file mode 100644 index 00000000000..0c5b6e1583c --- /dev/null +++ b/site/content/docs/1.30/config/access-logging.md @@ -0,0 +1,148 @@ +# Access Logging + +## Overview + +Contour allows you to control Envoy's access logging. +By default, HTTP and HTTPS access logs are written to `/dev/stdout` by the Envoy containers and look like following: + +``` +[2021-04-14T16:36:00.361Z] "GET /foo HTTP/1.1" 200 - 0 463 6 3 "-" "HTTPie/1.0.3" "837aa8dc-344f-4faa-b7d5-c9cce1028519" "localhost:8080" "127.0.0.1:8081" +``` + +The detailed description of each field can be found in [Envoy access logging documentation][7]. + + +## Customizing Access Log Destination + +You can change the destination file where the access log is written by using Contour [command line parameters][1] `--envoy-http-access-log` and `--envoy-https-access-log`. + +## Customizing Access Log Format + +The access log can take two different formats, both can be customized + +* Text based access logs, like shown in the example above. +* Structured JSON logging. + +### Text Based Access Logging + +Ensure that you have selected `envoy` as the access log format. +Note that this is the default format if the parameters are not given. + +- Add `--accesslog-format=envoy` to your Contour startup line, or +- Add `accesslog-format: envoy` to your configuration file. + +Customize the access log format by defining `accesslog-format-string` in your configuration file. + +```yaml +accesslog-format-string: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %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" +``` +After restarting Contour and successful validation of the configuration, the new format will take effect in a short while. + +Refer to [Envoy access logging documentation][7] for the description of the command operators, and note that the format string needs to end in a linefeed `\n`. + +### Structured JSON Logging + +Contour allows you to choose from a set of JSON fields that will be expanded into Envoy templates and sent to Envoy. +There is a default set of fields if you enable JSON logging, and you may customize which fields you log. + +The list of available fields are discoverable in the following objects: +- [jsonFields][2] are fields that have built in mappings to commonly used envoy operators. +- [envoySimpleOperators][3] are the names of simple envoy operators that don't require arguments, they are case-insensitive when configured. +- [envoyComplexOperators][4] are the names of complex envoy operators that require arguments. + +The default list of fields is available at [DefaultAccessLogJSONFields][5]. + +#### Enabling the Feature + +To enable the feature you have two options: + +- Add `--accesslog-format=json` to your Contour startup line. +- Add `accesslog-format: json` to your configuration file. + +Without any further customization, the [default fields][5] will be used. + +#### Customizing Logged Fields + +To customize the logged fields, add a `json-fields` list of strings to your configuration file. +If the `json-fields` key is not specified, the [default fields][5] will be configured. + +To use a value from [jsonFields][2] or [envoySimpleOperators][3], simply include the name of the value in the list of strings. +The jsonFields are case-sensitive, but envoySimpleOperators are not. + +To use [envoyComplexOperators][4] or to use alternative field names, specify strings as key/value pairs like `"fieldName=%OPERATOR(...)%"`. + +Unknown field names in non key/value fields will result in validation errors, as will unknown Envoy operators in key/value fields. +Note that the `DYNAMIC_METADATA` and `FILTER_STATE` Envoy logging operators are not supported at this time due to the complexity of their validation. + +See the [example config file][6] to see this used in context. + +#### Omitting Logs with Empty Values + +Contour automatically omits empty fields in Envoy JSON access logs, enhancing clarity and delivering more concise and relevant log outputs by default. + +#### Sample Configuration File + +Here is a sample config: + +```yaml +accesslog-format: json +json-fields: + - "@timestamp" + - "authority" + - "bytes_received" + - "bytes_sent" + - "customer_id=%REQ(X-CUSTOMER-ID)%" + - "downstream_local_address" + - "downstream_remote_address" + - "duration" + - "method" + - "path" + - "protocol" + - "request_id" + - "requested_server_name" + - "response_code" + - "response_flags" + - "uber_trace_id" + - "upstream_cluster" + - "upstream_host" + - "upstream_local_address" + - "upstream_service_time" + - "user_agent" + - "x_forwarded_for" +``` + +### Logging the route source + +Contour can log the kind, namespace and name of the Kubernetes resource that generated the route for a given access log entry. + +For text-based access logging, the following command operators can be used: +- `%METADATA(ROUTE:envoy.access_loggers.file:io.projectcontour.kind)%` +- `%METADATA(ROUTE:envoy.access_loggers.file:io.projectcontour.namespace)%` +- `%METADATA(ROUTE:envoy.access_loggers.file:io.projectcontour.name)%` + +For JSON access logging, the following fields can be added (these are Contour-specific aliases to the above command operators): +- `contour_config_kind` +- `contour_config_namespace` +- `contour_config_name` + +## Using Access Log Formatter Extensions + +Envoy allows implementing custom access log command operators as extensions. +Following extensions are supported by Contour: + +| Command operator | Description | +|------------------|-------------| +| [REQ_WITHOUT_QUERY][8] | Works the same way as REQ except that it will remove the query string. It is used to avoid logging any sensitive information into the access log. | +| [METADATA][9] | Prints all types of metadata. | + + + +[1]: ../configuration#serve-flags +[2]: https://github.com/search?q=%22var+jsonFields%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[3]: https://github.com/search?q=%22var+envoySimpleOperators%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[4]: https://github.com/search?q=%22var+envoyComplexOperators%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[5]: https://github.com/search?q=%22var+DefaultAccessLogJSONFields%22+repo%3Aprojectcontour%2Fcontour+path%3Aapis&type=code +[6]: {{< param github_url >}}/tree/{{< param latest_version >}}/examples/contour/01-contour-config.yaml +[7]: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/formatter/req_without_query/v3/req_without_query.proto +[9]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/formatter/metadata/v3/metadata.proto \ No newline at end of file diff --git a/site/content/docs/1.30/config/annotations.md b/site/content/docs/1.30/config/annotations.md new file mode 100644 index 00000000000..4d805f8f0f1 --- /dev/null +++ b/site/content/docs/1.30/config/annotations.md @@ -0,0 +1,98 @@ +# Annotations Reference + + + +Annotations are used in Ingress Controllers to configure features that are not covered by the Kubernetes Ingress API. + +Some of the features that have been historically configured via annotations are supported as first-class features in Contour's [HTTPProxy API][15], which provides a more robust configuration interface over annotations. + +However, Contour still supports a number of annotations on the Ingress resources. + +## Standard Kubernetes Ingress annotations + +The following Kubernetes annotations are supported on `Ingress` objects: + +### Ingress Class + +The Ingress class annotation can be used to specify which Ingress controller should serve a particular Ingress object. +This annotation may be specified as the standard `kubernetes.io/ingress.class` or a Contour-specific `projectcontour.io/ingress.class`. +In both cases, they will behave as follows, by default: + +* If not set, then all Ingress controllers serve the Ingress. +* If specified as `kubernetes.io/ingress.class: contour`, then Contour serves the Ingress. +* If any other value, Contour ignores the Ingress definition. + +You can override the default class `contour` by providing the `--ingress-class-name` flag to Contour. +This can be useful while you are migrating from another controller, or if you need multiple instances of Contour. +If you do this, the behavior is as follows: +* If the annotation is not set, Contour will ignore the Ingress. +* If the annotation is set to any value other than the one passed to the `--ingress-class-name` flag, Contour will ignore the Ingress. +* If the annotation matches the value that you passed to `--ingress-class-name` flag, Contour will serve the Ingress. + +This same logic applies for these annotations on HTTPProxy objects. + +_Note: Both `Ingress` and `HTTPProxy` now have an `IngressClassName` field in their spec. Going forward this is the preferred way to specify an ingress class, rather than using an annotation. If both the annotation and the spec field are specified on an object, the annotation takes preference for backwards compatibility._ + +_Note: The `--ingress-class-name` value can be a comma-separated list of class names to match against. Contour will serve the Ingress or HTTPProxy if the annotation or IngressClassName matches any of the specified class name values. + +### Other annotations + + - `ingress.kubernetes.io/force-ssl-redirect`: Requires TLS/SSL for the Ingress to Envoy by setting the [Envoy virtual host option require_tls][16]. + - `kubernetes.io/ingress.allow-http`: Instructs Contour to not create an Envoy HTTP route for the virtual host. The Ingress exists only for HTTPS requests. Specify `"false"` for Envoy to mark the endpoint as HTTPS only. All other values are ignored. + +The `ingress.kubernetes.io/force-ssl-redirect` annotation takes precedence over `kubernetes.io/ingress.allow-http`. If they are set to `"true"` and `"false"` respectively, Contour *will* create an Envoy HTTP route for the Virtual host, and set the `require_tls` virtual host option. + +## Contour specific Ingress annotations + + - `projectcontour.io/ingress.class`: The Ingress class that should interpret and serve the Ingress. See the [main Ingress class annotation section](#ingress-class) for more details. + - `projectcontour.io/num-retries`: [The maximum number of retries][1] Envoy should make before abandoning and returning an error to the client. Applies only if `projectcontour.io/retry-on` is specified. Set to -1 to disable retries. + - `projectcontour.io/per-try-timeout`: [The timeout per retry attempt][2], if there should be one. Applies only if `projectcontour.io/retry-on` is specified. + - `projectcontour.io/response-timeout`: [The Envoy HTTP route timeout][3], specified as a [golang duration][4]. By default, Envoy has a 15 second timeout for a backend service to respond. Set this to `infinity` to specify that Envoy should never timeout the connection to the backend. Note that the value `0s` / zero has special semantics for Envoy. + - `projectcontour.io/retry-on`: [The conditions for Envoy to retry a request][5]. See also [possible values and their meanings for `retry-on`][6]. + - `projectcontour.io/tls-minimum-protocol-version`: [The minimum TLS protocol version][7] the TLS listener should support. Valid options are `1.3`, `1.2` (default). + - `projectcontour.io/tls-maximum-protocol-version`: [The maximum TLS protocol version][7] the TLS listener should support. Valid options are `1.2`, `1.3` (default). + - `projectcontour.io/websocket-routes`: [The routes supporting websocket protocol][8], the annotation value contains a list of route paths separated by a comma that must match with the ones defined in the `Ingress` definition. Defaults to Envoy's default behavior which is `use_websocket` to `false`. + - `projectcontour.io/tls-cert-namespace`: The namespace where all TLS secrets of this Ingress are searched. This is necessary to use [TLS Certificate Delegation][18] with Ingress v1 because the slash notation (ex: different-ns/app-cert) used by HTTPProxy and Ingress v1beta1 is not accepted. See [this issue][19] for details. + +## Contour specific Service annotations + +A [Kubernetes Service][9] maps to an [Envoy Cluster][10]. Envoy clusters have many settings to control specific behaviors. These annotations allow access to some of those settings. + +- `projectcontour.io/max-connections`: [The maximum number of connections][11] that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. +- `projectcontour.io/max-pending-requests`: [The maximum number of pending requests][13] that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. +- `projectcontour.io/max-requests`: [The maximum parallel requests][13] a single Envoy instance allows to the Kubernetes Service; defaults to 1024 +- `projectcontour.io/max-retries`: [The maximum number of parallel retries][14] a single Envoy instance allows to the Kubernetes Service; defaults to 3. This is independent of the per-Kubernetes Ingress number of retries (`projectcontour.io/num-retries`) and retry-on (`projectcontour.io/retry-on`), which control whether retries are attempted and how many times a single request can retry. +- `projectcontour.io/per-host-max-connections`: [The maximum number of connections][20] that a single Envoy instance allows to an individual Kubernetes Service endpoint; no default (unlimited). +- `projectcontour.io/upstream-protocol.{protocol}` : The protocol used to proxy requests to the upstream service. + The annotation value contains a comma-separated list of port names and/or numbers that must match with the ones defined in the `Service` definition. + This value can also be specified in the `spec.routes.services[].protocol` field on the HTTPProxy object, where it takes precedence over the Service annotation. + Supported protocol names are: `h2`, `h2c`, and `tls`: + - The `tls` protocol allows for requests which terminate at Envoy to proxy via TLS to the upstream. + This protocol should be used for HTTP/1.1 services over TLS. + _Note that validating the upstream TLS certificate requires additionally setting the [validation][17] field._ + - The `h2` protocol proxies requests to the upstream using HTTP/2 over TLS. + - The `h2c` protocol proxies requests to the upstream using cleartext HTTP/2. + +## Contour specific HTTPProxy annotations +- `projectcontour.io/ingress.class`: The Ingress class that should interpret and serve the HTTPProxy. See the [main Ingress class annotation section](#ingress-class) for more details. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries +[2]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-retrypolicy-retry-on +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-timeout +[4]: https://golang.org/pkg/time/#ParseDuration +[5]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-retrypolicy-retry-on +[6]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-retry-on +[7]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto.html#extensions-transport-sockets-tls-v3-tlsparameters +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-upgrade-configs +[9]: https://kubernetes.io/docs/concepts/services-networking/service/ +[10]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/intro/terminology +[11]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-connections +[12]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-pending-requests +[13]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-requests +[14]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-thresholds-max-retries +[15]: fundamentals.md +[16]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-virtualhost-require-tls +[17]: api/#projectcontour.io/v1.UpstreamValidation +[18]: ../config/tls-delegation/ +[19]: https://github.com/projectcontour/contour/issues/3544 +[20]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/circuit_breaker.proto#envoy-v3-api-field-config-cluster-v3-circuitbreakers-per-host-thresholds \ No newline at end of file diff --git a/site/content/docs/1.30/config/api-reference.html b/site/content/docs/1.30/config/api-reference.html new file mode 100644 index 00000000000..57bc87795fd --- /dev/null +++ b/site/content/docs/1.30/config/api-reference.html @@ -0,0 +1,9157 @@ +

Packages:

+ +

projectcontour.io/v1

+

+

Package v1 holds the specification for the projectcontour.io Custom Resource Definitions (CRDs).

+

In building this CRD, we’ve inadvertently overloaded the word “Condition”, so we’ve tried to make +this spec clear as to which types of condition are which.

+

MatchConditions are used by Routes and Includes to specify rules to match requests against for either +routing or inclusion.

+

DetailedConditions are used in the Status of these objects to hold information about the relevant +state of the object and the world around it.

+

SubConditions are used underneath DetailedConditions to give more detail to errors or warnings.

+

+Resource Types: + +

HTTPProxy +

+

+

HTTPProxy is an Ingress CRD specification.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1 + +
+kind
+string +
HTTPProxy
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +HTTPProxySpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+virtualhost +
+ + +VirtualHost + + +
+(Optional) +

Virtualhost appears at most once. If it is present, the object is considered +to be a “root” HTTPProxy.

+
+routes +
+ + +[]Route + + +
+(Optional) +

Routes are the ingress routes. If TCPProxy is present, Routes is ignored.

+
+tcpproxy +
+ + +TCPProxy + + +
+(Optional) +

TCPProxy holds TCP proxy information.

+
+includes +
+ + +[]Include + + +
+(Optional) +

Includes allow for specific routing configuration to be included from another HTTPProxy, +possibly in another namespace.

+
+ingressClassName +
+ +string + +
+(Optional) +

IngressClassName optionally specifies the ingress class to use for this +HTTPProxy. This replaces the deprecated kubernetes.io/ingress.class +annotation. For backwards compatibility, when that annotation is set, it +is given precedence over this field.

+
+
+status +
+ + +HTTPProxyStatus + + +
+(Optional) +

Status is a container for computed information about the HTTPProxy.

+
+

TLSCertificateDelegation +

+

+

TLSCertificateDelegation is an TLS Certificate Delegation CRD specification. +See design/tls-certificate-delegation.md for details.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1 + +
+kind
+string +
TLSCertificateDelegation
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +TLSCertificateDelegationSpec + + +
+
+
+ + + + + +
+delegations +
+ + +[]CertificateDelegation + + +
+
+
+status +
+ + +TLSCertificateDelegationStatus + + +
+(Optional) +
+

AuthorizationPolicy +

+

+(Appears on: +AuthorizationServer, +Route) +

+

+

AuthorizationPolicy modifies how client requests are authenticated.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+disabled +
+ +bool + +
+(Optional) +

When true, this field disables client request authentication +for the scope of the policy.

+
+context +
+ +map[string]string + +
+(Optional) +

Context is a set of key/value pairs that are sent to the +authentication server in the check request. If a context +is provided at an enclosing scope, the entries are merged +such that the inner scope overrides matching keys from the +outer scope.

+
+

AuthorizationServer +

+

+(Appears on: +VirtualHost, +ContourConfigurationSpec) +

+

+

AuthorizationServer configures an external server to authenticate +client requests. The external server must implement the v3 Envoy +external authorization GRPC protocol (https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto).

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+extensionRef +
+ + +ExtensionServiceReference + + +
+(Optional) +

ExtensionServiceRef specifies the extension resource that will authorize client requests.

+
+authPolicy +
+ + +AuthorizationPolicy + + +
+(Optional) +

AuthPolicy sets a default authorization policy for client requests. +This policy will be used unless overridden by individual routes.

+
+responseTimeout +
+ +string + +
+(Optional) +

ResponseTimeout configures maximum time to wait for a check response from the authorization server. +Timeout durations are expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. +The string “infinity” is also a valid input and specifies no timeout.

+
+failOpen +
+ +bool + +
+(Optional) +

If FailOpen is true, the client request is forwarded to the upstream service +even if the authorization server fails to respond. This field should not be +set in most cases. It is intended for use only while migrating applications +from internal authorization to Contour external authorization.

+
+withRequestBody +
+ + +AuthorizationServerBufferSettings + + +
+(Optional) +

WithRequestBody specifies configuration for sending the client request’s body to authorization server.

+
+

AuthorizationServerBufferSettings +

+

+(Appears on: +AuthorizationServer) +

+

+

AuthorizationServerBufferSettings enables ExtAuthz filter to buffer client request data and send it as part of authorization request

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+maxRequestBytes +
+ +uint32 + +
+(Optional) +

MaxRequestBytes sets the maximum size of message body ExtAuthz filter will hold in-memory.

+
+allowPartialMessage +
+ +bool + +
+(Optional) +

If AllowPartialMessage is true, then Envoy will buffer the body until MaxRequestBytes are reached.

+
+packAsBytes +
+ +bool + +
+(Optional) +

If PackAsBytes is true, the body sent to Authorization Server is in raw bytes.

+
+

CORSHeaderValue +(string alias)

+

+(Appears on: +CORSPolicy) +

+

+

CORSHeaderValue specifies the value of the string headers returned by a cross-domain request.

+

+

CORSPolicy +

+

+(Appears on: +VirtualHost) +

+

+

CORSPolicy allows setting the CORS policy

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+allowCredentials +
+ +bool + +
+(Optional) +

Specifies whether the resource allows credentials.

+
+allowOrigin +
+ +[]string + +
+

AllowOrigin specifies the origins that will be allowed to do CORS requests. +Allowed values include “*” which signifies any origin is allowed, an exact +origin of the form “scheme://host[:port]” (where port is optional), or a valid +regex pattern. +Note that regex patterns are validated and a simple “glob” pattern (e.g. *.foo.com) +will be rejected or produce unexpected matches when applied as a regex.

+
+allowMethods +
+ + +[]CORSHeaderValue + + +
+

AllowMethods specifies the content for the access-control-allow-methods header.

+
+allowHeaders +
+ + +[]CORSHeaderValue + + +
+(Optional) +

AllowHeaders specifies the content for the access-control-allow-headers header.

+
+exposeHeaders +
+ + +[]CORSHeaderValue + + +
+(Optional) +

ExposeHeaders Specifies the content for the access-control-expose-headers header.

+
+maxAge +
+ +string + +
+(Optional) +

MaxAge indicates for how long the results of a preflight request can be cached. +MaxAge durations are expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. +Only positive values are allowed while 0 disables the cache requiring a preflight OPTIONS +check for all cross-origin requests.

+
+allowPrivateNetwork +
+ +bool + +
+

AllowPrivateNetwork specifies whether to allow private network requests. +See https://developer.chrome.com/blog/private-network-access-preflight.

+
+

CertificateDelegation +

+

+(Appears on: +TLSCertificateDelegationSpec) +

+

+

CertificateDelegation maps the authority to reference a secret +in the current namespace to a set of namespaces.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+secretName +
+ +string + +
+

required, the name of a secret in the current namespace.

+
+targetNamespaces +
+ +[]string + +
+

required, the namespaces the authority to reference the +secret will be delegated to. +If TargetNamespaces is nil or empty, the CertificateDelegation’ +is ignored. If the TargetNamespace list contains the character, “*” +the secret will be delegated to all namespaces.

+
+

ClientCertificateDetails +

+

+(Appears on: +DownstreamValidation) +

+

+

ClientCertificateDetails defines which parts of the client certificate will be forwarded.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+subject +
+ +bool + +
+(Optional) +

Subject of the client cert.

+
+cert +
+ +bool + +
+(Optional) +

Client cert in URL encoded PEM format.

+
+chain +
+ +bool + +
+(Optional) +

Client cert chain (including the leaf cert) in URL encoded PEM format.

+
+dns +
+ +bool + +
+(Optional) +

DNS type Subject Alternative Names of the client cert.

+
+uri +
+ +bool + +
+(Optional) +

URI type Subject Alternative Name of the client cert.

+
+

CookieDomainRewrite +

+

+(Appears on: +CookieRewritePolicy) +

+

+

+ + + + + + + + + + + + + +
FieldDescription
+value +
+ +string + +
+

Value is the value to rewrite the Domain attribute to. +For now this is required.

+
+

CookiePathRewrite +

+

+(Appears on: +CookieRewritePolicy) +

+

+

+ + + + + + + + + + + + + +
FieldDescription
+value +
+ +string + +
+

Value is the value to rewrite the Path attribute to. +For now this is required.

+
+

CookieRewritePolicy +

+

+(Appears on: +Route, +Service) +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of the cookie for which attributes will be rewritten.

+
+pathRewrite +
+ + +CookiePathRewrite + + +
+(Optional) +

PathRewrite enables rewriting the Set-Cookie Path element. +If not set, Path will not be rewritten.

+
+domainRewrite +
+ + +CookieDomainRewrite + + +
+(Optional) +

DomainRewrite enables rewriting the Set-Cookie Domain element. +If not set, Domain will not be rewritten.

+
+secure +
+ +bool + +
+(Optional) +

Secure enables rewriting the Set-Cookie Secure element. +If not set, Secure attribute will not be rewritten.

+
+sameSite +
+ +string + +
+(Optional) +

SameSite enables rewriting the Set-Cookie SameSite element. +If not set, SameSite attribute will not be rewritten.

+
+

DetailedCondition +

+

+(Appears on: +HTTPProxyStatus, +TLSCertificateDelegationStatus, +ContourConfigurationStatus, +ExtensionServiceStatus) +

+

+

DetailedCondition is an extension of the normal Kubernetes conditions, with two extra +fields to hold sub-conditions, which provide more detailed reasons for the state (True or False) +of the condition.

+

errors holds information about sub-conditions which are fatal to that condition and render its state False.

+

warnings holds information about sub-conditions which are not fatal to that condition and do not force the state to be False.

+

Remember that Conditions have a type, a status, and a reason.

+

The type is the type of the condition, the most important one in this CRD set is Valid. +Valid is a positive-polarity condition: when it is status: true there are no problems.

+

In more detail, status: true means that the object is has been ingested into Contour with no errors. +warnings may still be present, and will be indicated in the Reason field. There must be zero entries in the errors +slice in this case.

+

Valid, status: false means that the object has had one or more fatal errors during processing into Contour. +The details of the errors will be present under the errors field. There must be at least one error in the errors +slice if status is false.

+

For DetailedConditions of types other than Valid, the Condition must be in the negative polarity. +When they have status true, there is an error. There must be at least one entry in the errors Subcondition slice. +When they have status false, there are no serious errors, and there must be zero entries in the errors slice. +In either case, there may be entries in the warnings slice.

+

Regardless of the polarity, the reason and message fields must be updated with either the detail of the reason +(if there is one and only one entry in total across both the errors and warnings slices), or +MultipleReasons if there is more than one entry.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+Condition +
+ + +Kubernetes meta/v1.Condition + + +
+

+(Members of Condition are embedded into this type.) +

+
+errors +
+ + +[]SubCondition + + +
+(Optional) +

Errors contains a slice of relevant error subconditions for this object.

+

Subconditions are expected to appear when relevant (when there is a error), and disappear when not relevant. +An empty slice here indicates no errors.

+
+warnings +
+ + +[]SubCondition + + +
+(Optional) +

Warnings contains a slice of relevant warning subconditions for this object.

+

Subconditions are expected to appear when relevant (when there is a warning), and disappear when not relevant. +An empty slice here indicates no warnings.

+
+

DownstreamValidation +

+

+(Appears on: +TLS) +

+

+

DownstreamValidation defines how to verify the client certificate.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caSecret +
+ +string + +
+(Optional) +

Name of a Kubernetes secret that contains a CA certificate bundle. +The secret must contain key named ca.crt. +The client certificate must validate against the certificates in the bundle. +If specified and SkipClientCertValidation is true, client certificates will +be required on requests. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret.

+
+skipClientCertValidation +
+ +bool + +
+(Optional) +

SkipClientCertValidation disables downstream client certificate +validation. Defaults to false. This field is intended to be used in +conjunction with external authorization in order to enable the external +authorization server to validate client certificates. When this field +is set to true, client certificates are requested but not verified by +Envoy. If CACertificate is specified, client certificates are required on +requests, but not verified. If external authorization is in use, they are +presented to the external authorization server.

+
+forwardClientCertificate +
+ + +ClientCertificateDetails + + +
+(Optional) +

ForwardClientCertificate adds the selected data from the passed client TLS certificate +to the x-forwarded-client-cert header.

+
+crlSecret +
+ +string + +
+(Optional) +

Name of a Kubernetes opaque secret that contains a concatenated list of PEM encoded CRLs. +The secret must contain key named crl.pem. +This field will be used to verify that a client certificate has not been revoked. +CRLs must be available from all CAs, unless crlOnlyVerifyLeafCert is true. +Large CRL lists are not supported since individual secrets are limited to 1MiB in size. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret.

+
+crlOnlyVerifyLeafCert +
+ +bool + +
+(Optional) +

If this option is set to true, only the certificate at the end of the +certificate chain will be subject to validation by CRL.

+
+optionalClientCertificate +
+ +bool + +
+(Optional) +

OptionalClientCertificate when set to true will request a client certificate +but allow the connection to continue if the client does not provide one. +If a client certificate is sent, it will be verified according to the +other properties, which includes disabling validation if +SkipClientCertValidation is set. Defaults to false.

+
+

ExtensionServiceReference +

+

+(Appears on: +AuthorizationServer) +

+

+

ExtensionServiceReference names an ExtensionService resource.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion +
+ +string + +
+(Optional) +

API version of the referent. +If this field is not specified, the default “projectcontour.io/v1alpha1” will be used

+
+namespace +
+ +string + +
+(Optional) +

Namespace of the referent. +If this field is not specifies, the namespace of the resource that targets the referent will be used.

+

More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

+
+name +
+ +string + +
+

Name of the referent.

+

More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

+
+

Feature +(string alias)

+

+(Appears on: +ContourSettings) +

+

+

+

GenericKeyDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

GenericKeyDescriptor defines a descriptor entry with a static key and +value.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+key +
+ +string + +
+(Optional) +

Key defines the key of the descriptor entry. If not set, the +key is set to “generic_key”.

+
+value +
+ +string + +
+

Value defines the value of the descriptor entry.

+
+

GlobalRateLimitPolicy +

+

+(Appears on: +RateLimitPolicy, +RateLimitServiceConfig) +

+

+

GlobalRateLimitPolicy defines global rate limiting parameters.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+disabled +
+ +bool + +
+(Optional) +

Disabled configures the HTTPProxy to not use +the default global rate limit policy defined by the Contour configuration.

+
+descriptors +
+ + +[]RateLimitDescriptor + + +
+(Optional) +

Descriptors defines the list of descriptors that will +be generated and sent to the rate limit service. Each +descriptor contains 1+ key-value pair entries.

+
+

HTTPDirectResponsePolicy +

+

+(Appears on: +Route) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+statusCode +
+ +int + +
+

StatusCode is the HTTP response status to be returned.

+
+body +
+ +string + +
+(Optional) +

Body is the content of the response body. +If this setting is omitted, no body is included in the generated response.

+

Note: Body is not recommended to set too long +otherwise it can have significant resource usage impacts.

+
+

HTTPHealthCheckPolicy +

+

+(Appears on: +Route) +

+

+

HTTPHealthCheckPolicy defines health checks on the upstream service.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+path +
+ +string + +
+

HTTP endpoint used to perform health checks on upstream service

+
+host +
+ +string + +
+

The value of the host header in the HTTP health check request. +If left empty (default value), the name “contour-envoy-healthcheck” +will be used.

+
+intervalSeconds +
+ +int64 + +
+(Optional) +

The interval (seconds) between health checks

+
+timeoutSeconds +
+ +int64 + +
+(Optional) +

The time to wait (seconds) for a health check response

+
+unhealthyThresholdCount +
+ +int64 + +
+(Optional) +

The number of unhealthy health checks required before a host is marked unhealthy

+
+healthyThresholdCount +
+ +int64 + +
+(Optional) +

The number of healthy health checks required before a host is marked healthy

+
+expectedStatuses +
+ + +[]HTTPStatusRange + + +
+(Optional) +

The ranges of HTTP response statuses considered healthy. Follow half-open +semantics, i.e. for each range the start is inclusive and the end is exclusive. +Must be within the range [100,600). If not specified, only a 200 response status +is considered healthy.

+
+

HTTPInternalRedirectPolicy +

+

+(Appears on: +Route) +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+maxInternalRedirects +
+ +uint32 + +
+(Optional) +

MaxInternalRedirects An internal redirect is not handled, unless the number of previous internal +redirects that a downstream request has encountered is lower than this value.

+
+redirectResponseCodes +
+ + +[]RedirectResponseCode + + +
+(Optional) +

RedirectResponseCodes If unspecified, only 302 will be treated as internal redirect. +Only 301, 302, 303, 307 and 308 are valid values.

+
+allowCrossSchemeRedirect +
+ +string + +
+(Optional) +

AllowCrossSchemeRedirect Allow internal redirect to follow a target URI with a different scheme +than the value of x-forwarded-proto. +SafeOnly allows same scheme redirect and safe cross scheme redirect, which means if the downstream +scheme is HTTPS, both HTTPS and HTTP redirect targets are allowed, but if the downstream scheme +is HTTP, only HTTP redirect targets are allowed.

+
+denyRepeatedRouteRedirect +
+ +bool + +
+(Optional) +

If DenyRepeatedRouteRedirect is true, rejects redirect targets that are pointing to a route that has +been followed by a previous redirect from the current route.

+
+

HTTPProxySpec +

+

+(Appears on: +HTTPProxy) +

+

+

HTTPProxySpec defines the spec of the CRD.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+virtualhost +
+ + +VirtualHost + + +
+(Optional) +

Virtualhost appears at most once. If it is present, the object is considered +to be a “root” HTTPProxy.

+
+routes +
+ + +[]Route + + +
+(Optional) +

Routes are the ingress routes. If TCPProxy is present, Routes is ignored.

+
+tcpproxy +
+ + +TCPProxy + + +
+(Optional) +

TCPProxy holds TCP proxy information.

+
+includes +
+ + +[]Include + + +
+(Optional) +

Includes allow for specific routing configuration to be included from another HTTPProxy, +possibly in another namespace.

+
+ingressClassName +
+ +string + +
+(Optional) +

IngressClassName optionally specifies the ingress class to use for this +HTTPProxy. This replaces the deprecated kubernetes.io/ingress.class +annotation. For backwards compatibility, when that annotation is set, it +is given precedence over this field.

+
+

HTTPProxyStatus +

+

+(Appears on: +HTTPProxy) +

+

+

HTTPProxyStatus reports the current state of the HTTPProxy.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+currentStatus +
+ +string + +
+(Optional) +
+description +
+ +string + +
+(Optional) +
+loadBalancer +
+ + +Kubernetes core/v1.LoadBalancerStatus + + +
+(Optional) +

LoadBalancer contains the current status of the load balancer.

+
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains information about the current status of the HTTPProxy, +in an upstream-friendly container.

+

Contour will update a single condition, Valid, that is in normal-true polarity. +That is, when currentStatus is valid, the Valid condition will be status: true, +and vice versa.

+

Contour will leave untouched any other Conditions set in this block, +in case some other controller wants to add a Condition.

+

If you are another controller owner and wish to add a condition, you should +namespace your condition with a label, like controller.domain.com/ConditionName.

+
+

HTTPRequestRedirectPolicy +

+

+(Appears on: +Route) +

+

+

HTTPRequestRedirectPolicy defines configuration for redirecting a request.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+scheme +
+ +string + +
+(Optional) +

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.

+
+hostname +
+ +string + +
+(Optional) +

Hostname is the precise hostname to be used in the value of the Location +header in the response. +When empty, the hostname of the request is used. +No wildcards are allowed.

+
+port +
+ +int32 + +
+(Optional) +

Port is the port to be used in the value of the Location +header in the response. +When empty, port (if specified) of the request is used.

+
+statusCode +
+ +int + +
+(Optional) +

StatusCode is the HTTP status code to be used in response.

+
+path +
+ +string + +
+(Optional) +

Path allows for redirection to a different path from the +original on the request. The path must start with a +leading slash.

+

Note: Only one of Path or Prefix can be defined.

+
+prefix +
+ +string + +
+(Optional) +

Prefix defines the value to swap the matched prefix or path with. +The prefix must start with a leading slash.

+

Note: Only one of Path or Prefix can be defined.

+
+

HTTPStatusRange +

+

+(Appears on: +HTTPHealthCheckPolicy) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+start +
+ +int64 + +
+

The start (inclusive) of a range of HTTP status codes.

+
+end +
+ +int64 + +
+

The end (exclusive) of a range of HTTP status codes.

+
+

HeaderHashOptions +

+

+(Appears on: +RequestHashPolicy) +

+

+

HeaderHashOptions contains options to configure a HTTP request header hash +policy, used in request attribute hash based load balancing.

+

+ + + + + + + + + + + + + +
FieldDescription
+headerName +
+ +string + +
+

HeaderName is the name of the HTTP request header that will be used to +calculate the hash key. If the header specified is not present on a +request, no hash will be produced.

+
+

HeaderMatchCondition +

+

+(Appears on: +MatchCondition, +RequestHeaderValueMatchDescriptor) +

+

+

HeaderMatchCondition specifies how to conditionally match against HTTP +headers. The Name field is required, only one of Present, NotPresent, +Contains, NotContains, Exact, NotExact and Regex can be set. +For negative matching rules only (e.g. NotContains or NotExact) you can set +TreatMissingAsEmpty. +IgnoreCase has no effect for Regex.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of the header to match against. Name is required. +Header names are case insensitive.

+
+present +
+ +bool + +
+(Optional) +

Present specifies that condition is true when the named header +is present, regardless of its value. Note that setting Present +to false does not make the condition true if the named header +is absent.

+
+notpresent +
+ +bool + +
+(Optional) +

NotPresent specifies that condition is true when the named header +is not present. Note that setting NotPresent to false does not +make the condition true if the named header is present.

+
+contains +
+ +string + +
+(Optional) +

Contains specifies a substring that must be present in +the header value.

+
+notcontains +
+ +string + +
+(Optional) +

NotContains specifies a substring that must not be present +in the header value.

+
+ignoreCase +
+ +bool + +
+(Optional) +

IgnoreCase specifies that string matching should be case insensitive. +Note that this has no effect on the Regex parameter.

+
+exact +
+ +string + +
+(Optional) +

Exact specifies a string that the header value must be equal to.

+
+notexact +
+ +string + +
+(Optional) +

NoExact specifies a string that the header value must not be +equal to. The condition is true if the header has any other value.

+
+regex +
+ +string + +
+(Optional) +

Regex specifies a regular expression pattern that must match the header +value.

+
+treatMissingAsEmpty +
+ +bool + +
+(Optional) +

TreatMissingAsEmpty specifies if the header match rule specified header +does not exist, this header value will be treated as empty. Defaults to false. +Unlike the underlying Envoy implementation this is only supported for +negative matches (e.g. NotContains, NotExact).

+
+

HeaderValue +

+

+(Appears on: +HeadersPolicy, +LocalRateLimitPolicy) +

+

+

HeaderValue represents a header name/value pair

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name represents a key of a header

+
+value +
+ +string + +
+

Value represents the value of a header specified by a key

+
+

HeadersPolicy +

+

+(Appears on: +Route, +Service) +

+

+

HeadersPolicy defines how headers are managed during forwarding. +The Host header is treated specially and if set in a HTTP request +will be used as the SNI server name when forwarding over TLS. It is an +error to attempt to set the Host header in a HTTP response.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+set +
+ + +[]HeaderValue + + +
+(Optional) +

Set specifies a list of HTTP header values that will be set in the HTTP header. +If the header does not exist it will be added, otherwise it will be overwritten with the new value.

+
+remove +
+ +[]string + +
+(Optional) +

Remove specifies a list of HTTP header names to remove.

+
+

IPFilterPolicy +

+

+(Appears on: +Route, +VirtualHost) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+source +
+ + +IPFilterSource + + +
+

Source indicates how to determine the ip address to filter on, and can be +one of two values: +- Remote filters on the ip address of the client, accounting for PROXY and +X-Forwarded-For as needed. +- Peer filters on the ip of the network request, ignoring PROXY and +X-Forwarded-For.

+
+cidr +
+ +string + +
+

CIDR is a CIDR block of ipv4 or ipv6 addresses to filter on. This can also be +a bare IP address (without a mask) to filter on exactly one address.

+
+

IPFilterSource +(string alias)

+

+(Appears on: +IPFilterPolicy) +

+

+

IPFilterSource indicates which IP should be considered for filtering

+

+ + + + + + + + + + + + +
ValueDescription

"Peer"

"Remote"

+

Include +

+

+(Appears on: +HTTPProxySpec) +

+

+

Include describes a set of policies that can be applied to an HTTPProxy in a namespace.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name of the HTTPProxy

+
+namespace +
+ +string + +
+(Optional) +

Namespace of the HTTPProxy to include. Defaults to the current namespace if not supplied.

+
+conditions +
+ + +[]MatchCondition + + +
+(Optional) +

Conditions are a set of rules that are applied to included HTTPProxies. +In effect, they are added onto the Conditions of included HTTPProxy Route +structs. +When applied, they are merged using AND, with one exception: +There can be only one Prefix MatchCondition per Conditions slice. +More than one Prefix, or contradictory Conditions, will make the +include invalid. Exact and Regex match conditions are not allowed +on includes.

+
+

JWTProvider +

+

+(Appears on: +VirtualHost) +

+

+

JWTProvider defines how to verify JWTs on requests.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Unique name for the provider.

+
+default +
+ +bool + +
+(Optional) +

Whether the provider should apply to all +routes in the HTTPProxy/its includes by +default. At most one provider can be marked +as the default. If no provider is marked +as the default, individual routes must explicitly +identify the provider they require.

+
+issuer +
+ +string + +
+(Optional) +

Issuer that JWTs are required to have in the “iss” field. +If not provided, JWT issuers are not checked.

+
+audiences +
+ +[]string + +
+(Optional) +

Audiences that JWTs are allowed to have in the “aud” field. +If not provided, JWT audiences are not checked.

+
+remoteJWKS +
+ + +RemoteJWKS + + +
+

Remote JWKS to use for verifying JWT signatures.

+
+forwardJWT +
+ +bool + +
+(Optional) +

Whether the JWT should be forwarded to the backend +service after successful verification. By default, +the JWT is not forwarded.

+
+

JWTVerificationPolicy +

+

+(Appears on: +Route) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+require +
+ +string + +
+(Optional) +

Require names a specific JWT provider (defined in the virtual host) +to require for the route. If specified, this field overrides the +default provider if one exists. If this field is not specified, +the default provider will be required if one exists. At most one of +this field or the “disabled” field can be specified.

+
+disabled +
+ +bool + +
+(Optional) +

Disabled defines whether to disable all JWT verification for this +route. This can be used to opt specific routes out of the default +JWT provider for the HTTPProxy. At most one of this field or the +“require” field can be specified.

+
+

LoadBalancerPolicy +

+

+(Appears on: +Route, +TCPProxy, +ExtensionServiceSpec) +

+

+

LoadBalancerPolicy defines the load balancing policy.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+strategy +
+ +string + +
+

Strategy specifies the policy used to balance requests +across the pool of backend pods. Valid policy names are +Random, RoundRobin, WeightedLeastRequest, Cookie, +and RequestHash. If an unknown strategy name is specified +or no policy is supplied, the default RoundRobin policy +is used.

+
+requestHashPolicies +
+ + +[]RequestHashPolicy + + +
+

RequestHashPolicies contains a list of hash policies to apply when the +RequestHash load balancing strategy is chosen. If an element of the +supplied list of hash policies is invalid, it will be ignored. If the +list of hash policies is empty after validation, the load balancing +strategy will fall back to the default RoundRobin.

+
+

LocalRateLimitPolicy +

+

+(Appears on: +RateLimitPolicy) +

+

+

LocalRateLimitPolicy defines local rate limiting parameters.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+requests +
+ +uint32 + +
+

Requests defines how many requests per unit of time should +be allowed before rate limiting occurs.

+
+unit +
+ +string + +
+

Unit defines the period of time within which requests +over the limit will be rate limited. Valid values are +“second”, “minute” and “hour”.

+
+burst +
+ +uint32 + +
+(Optional) +

Burst defines the number of requests above the requests per +unit that should be allowed within a short period of time.

+
+responseStatusCode +
+ +uint32 + +
+(Optional) +

ResponseStatusCode is the HTTP status code to use for responses +to rate-limited requests. Codes must be in the 400-599 range +(inclusive). If not specified, the Envoy default of 429 (Too +Many Requests) is used.

+
+responseHeadersToAdd +
+ + +[]HeaderValue + + +
+(Optional) +

ResponseHeadersToAdd is an optional list of response headers to +set when a request is rate-limited.

+
+

MatchCondition +

+

+(Appears on: +Include, +Route) +

+

+

MatchCondition are a general holder for matching rules for HTTPProxies. +One of Prefix, Exact, Regex, Header or QueryParameter must be provided.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+prefix +
+ +string + +
+(Optional) +

Prefix defines a prefix match for a request.

+
+exact +
+ +string + +
+(Optional) +

Exact defines a exact match for a request. +This field is not allowed in include match conditions.

+
+regex +
+ +string + +
+(Optional) +

Regex defines a regex match for a request. +This field is not allowed in include match conditions.

+
+header +
+ + +HeaderMatchCondition + + +
+(Optional) +

Header specifies the header condition to match.

+
+queryParameter +
+ + +QueryParameterMatchCondition + + +
+(Optional) +

QueryParameter specifies the query parameter condition to match.

+
+

Namespace +(string alias)

+

+(Appears on: +ContourSettings) +

+

+

Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.

+

This validation is based off of the corresponding Kubernetes validation: +https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187

+

This is used for Namespace name validation here: +https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63

+

Valid values include:

+
    +
  • “example”
  • +
+

Invalid values include:

+
    +
  • “example.com” - “.” is an invalid character
  • +
+

+

PathRewritePolicy +

+

+(Appears on: +Route) +

+

+

PathRewritePolicy specifies how a request URL path should be +rewritten. This rewriting takes place after a request is routed +and has no subsequent effects on the proxy’s routing decision. +No HTTP headers or body content is rewritten.

+

Exactly one field in this struct may be specified.

+

+ + + + + + + + + + + + + +
FieldDescription
+replacePrefix +
+ + +[]ReplacePrefix + + +
+(Optional) +

ReplacePrefix describes how the path prefix should be replaced.

+
+

QueryParameterHashOptions +

+

+(Appears on: +RequestHashPolicy) +

+

+

QueryParameterHashOptions contains options to configure a query parameter based hash +policy, used in request attribute hash based load balancing.

+

+ + + + + + + + + + + + + +
FieldDescription
+parameterName +
+ +string + +
+

ParameterName is the name of the HTTP request query parameter that will be used to +calculate the hash key. If the query parameter specified is not present on a +request, no hash will be produced.

+
+

QueryParameterMatchCondition +

+

+(Appears on: +MatchCondition) +

+

+

QueryParameterMatchCondition specifies how to conditionally match against HTTP +query parameters. The Name field is required, only one of Exact, Prefix, +Suffix, Regex, Contains and Present can be set. IgnoreCase has no effect +for Regex.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of the query parameter to match against. Name is required. +Query parameter names are case insensitive.

+
+exact +
+ +string + +
+(Optional) +

Exact specifies a string that the query parameter value must be equal to.

+
+prefix +
+ +string + +
+(Optional) +

Prefix defines a prefix match for the query parameter value.

+
+suffix +
+ +string + +
+(Optional) +

Suffix defines a suffix match for a query parameter value.

+
+regex +
+ +string + +
+(Optional) +

Regex specifies a regular expression pattern that must match the query +parameter value.

+
+contains +
+ +string + +
+(Optional) +

Contains specifies a substring that must be present in +the query parameter value.

+
+ignoreCase +
+ +bool + +
+(Optional) +

IgnoreCase specifies that string matching should be case insensitive. +Note that this has no effect on the Regex parameter.

+
+present +
+ +bool + +
+(Optional) +

Present specifies that condition is true when the named query parameter +is present, regardless of its value. Note that setting Present +to false does not make the condition true if the named query parameter +is absent.

+
+

RateLimitDescriptor +

+

+(Appears on: +GlobalRateLimitPolicy) +

+

+

RateLimitDescriptor defines a list of key-value pair generators.

+

+ + + + + + + + + + + + + +
FieldDescription
+entries +
+ + +[]RateLimitDescriptorEntry + + +
+

Entries is the list of key-value pair generators.

+
+

RateLimitDescriptorEntry +

+

+(Appears on: +RateLimitDescriptor) +

+

+

RateLimitDescriptorEntry is a key-value pair generator. Exactly +one field on this struct must be non-nil.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+genericKey +
+ + +GenericKeyDescriptor + + +
+(Optional) +

GenericKey defines a descriptor entry with a static key and value.

+
+requestHeader +
+ + +RequestHeaderDescriptor + + +
+(Optional) +

RequestHeader defines a descriptor entry that’s populated only if +a given header is present on the request. The descriptor key is static, +and the descriptor value is equal to the value of the header.

+
+requestHeaderValueMatch +
+ + +RequestHeaderValueMatchDescriptor + + +
+(Optional) +

RequestHeaderValueMatch defines a descriptor entry that’s populated +if the request’s headers match a set of 1+ match criteria. The +descriptor key is “header_match”, and the descriptor value is static.

+
+remoteAddress +
+ + +RemoteAddressDescriptor + + +
+(Optional) +

RemoteAddress defines a descriptor entry with a key of “remote_address” +and a value equal to the client’s IP address (from x-forwarded-for).

+
+

RateLimitPolicy +

+

+(Appears on: +Route, +VirtualHost) +

+

+

RateLimitPolicy defines rate limiting parameters.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+local +
+ + +LocalRateLimitPolicy + + +
+(Optional) +

Local defines local rate limiting parameters, i.e. parameters +for rate limiting that occurs within each Envoy pod as requests +are handled.

+
+global +
+ + +GlobalRateLimitPolicy + + +
+(Optional) +

Global defines global rate limiting parameters, i.e. parameters +defining descriptors that are sent to an external rate limit +service (RLS) for a rate limit decision on each request.

+
+

RedirectResponseCode +(uint32 alias)

+

+(Appears on: +HTTPInternalRedirectPolicy) +

+

+

RedirectResponseCode is a uint32 type alias with validation to ensure that the value is valid.

+

+

RemoteAddressDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

RemoteAddressDescriptor defines a descriptor entry with a key of +“remote_address” and a value equal to the client’s IP address +(from x-forwarded-for).

+

+

RemoteJWKS +

+

+(Appears on: +JWTProvider) +

+

+

RemoteJWKS defines how to fetch a JWKS from an HTTP endpoint.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+uri +
+ +string + +
+

The URI for the JWKS.

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the JWKS’s TLS certificate.

+
+timeout +
+ +string + +
+(Optional) +

How long to wait for a response from the URI. +If not specified, a default of 1s applies.

+
+cacheDuration +
+ +string + +
+(Optional) +

How long to cache the JWKS locally. If not specified, +Envoy’s default of 5m applies.

+
+dnsLookupFamily +
+ +string + +
+(Optional) +

The DNS IP address resolution policy for the JWKS URI. +When configured as “v4”, the DNS resolver will only perform a lookup +for addresses in the IPv4 family. If “v6” is configured, the DNS resolver +will only perform a lookup for addresses in the IPv6 family. +If “all” is configured, the DNS resolver +will perform a lookup for addresses in both the IPv4 and IPv6 family. +If “auto” is configured, the DNS resolver will first perform a lookup +for addresses in the IPv6 family and fallback to a lookup for addresses +in the IPv4 family. If not specified, the Contour-wide setting defined +in the config file or ContourConfiguration applies (defaults to “auto”).

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto.html#envoy-v3-api-enum-config-cluster-v3-cluster-dnslookupfamily +for more information.

+
+

ReplacePrefix +

+

+(Appears on: +PathRewritePolicy) +

+

+

ReplacePrefix describes a path prefix replacement.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+prefix +
+ +string + +
+(Optional) +

Prefix specifies the URL path prefix to be replaced.

+

If Prefix is specified, it must exactly match the MatchCondition +prefix that is rendered by the chain of including HTTPProxies +and only that path prefix will be replaced by Replacement. +This allows HTTPProxies that are included through multiple +roots to only replace specific path prefixes, leaving others +unmodified.

+

If Prefix is not specified, all routing prefixes rendered +by the include chain will be replaced.

+
+replacement +
+ +string + +
+

Replacement is the string that the routing path prefix +will be replaced with. This must not be empty.

+
+

RequestHashPolicy +

+

+(Appears on: +LoadBalancerPolicy) +

+

+

RequestHashPolicy contains configuration for an individual hash policy +on a request attribute.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+terminal +
+ +bool + +
+

Terminal is a flag that allows for short-circuiting computing of a hash +for a given request. If set to true, and the request attribute specified +in the attribute hash options is present, no further hash policies will +be used to calculate a hash for the request.

+
+headerHashOptions +
+ + +HeaderHashOptions + + +
+(Optional) +

HeaderHashOptions should be set when request header hash based load +balancing is desired. It must be the only hash option field set, +otherwise this request hash policy object will be ignored.

+
+queryParameterHashOptions +
+ + +QueryParameterHashOptions + + +
+(Optional) +

QueryParameterHashOptions should be set when request query parameter hash based load +balancing is desired. It must be the only hash option field set, +otherwise this request hash policy object will be ignored.

+
+hashSourceIP +
+ +bool + +
+(Optional) +

HashSourceIP should be set to true when request source IP hash based +load balancing is desired. It must be the only hash option field set, +otherwise this request hash policy object will be ignored.

+
+

RequestHeaderDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

RequestHeaderDescriptor defines a descriptor entry that’s populated only +if a given header is present on the request. The value of the descriptor +entry is equal to the value of the header (if present).

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+headerName +
+ +string + +
+

HeaderName defines the name of the header to look for on the request.

+
+descriptorKey +
+ +string + +
+

DescriptorKey defines the key to use on the descriptor entry.

+
+

RequestHeaderValueMatchDescriptor +

+

+(Appears on: +RateLimitDescriptorEntry) +

+

+

RequestHeaderValueMatchDescriptor defines a descriptor entry that’s populated +if the request’s headers match a set of 1+ match criteria. The descriptor key +is “header_match”, and the descriptor value is statically defined.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+headers +
+ + +[]HeaderMatchCondition + + +
+

Headers is a list of 1+ match criteria to apply against the request +to determine whether to populate the descriptor entry or not.

+
+expectMatch +
+ +bool + +
+

ExpectMatch defines whether the request must positively match the match +criteria in order to generate a descriptor entry (i.e. true), or not +match the match criteria in order to generate a descriptor entry (i.e. false). +The default is true.

+
+value +
+ +string + +
+

Value defines the value of the descriptor entry.

+
+

RetryOn +(string alias)

+

+(Appears on: +RetryPolicy) +

+

+

RetryOn is a string type alias with validation to ensure that the value is valid.

+

+

RetryPolicy +

+

+(Appears on: +Route) +

+

+

RetryPolicy defines the attributes associated with retrying policy.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+count +
+ +int64 + +
+(Optional) +

NumRetries is maximum allowed number of retries. +If set to -1, then retries are disabled. +If set to 0 or not supplied, the value is set +to the Envoy default of 1.

+
+perTryTimeout +
+ +string + +
+(Optional) +

PerTryTimeout specifies the timeout per retry attempt. +Ignored if NumRetries is not supplied.

+
+retryOn +
+ + +[]RetryOn + + +
+(Optional) +

RetryOn specifies the conditions on which to retry a request.

+

Supported HTTP conditions:

+
    +
  • 5xx
  • +
  • gateway-error
  • +
  • reset
  • +
  • connect-failure
  • +
  • retriable-4xx
  • +
  • refused-stream
  • +
  • retriable-status-codes
  • +
  • retriable-headers
  • +
+

Supported gRPC conditions:

+
    +
  • cancelled
  • +
  • deadline-exceeded
  • +
  • internal
  • +
  • resource-exhausted
  • +
  • unavailable
  • +
+
+retriableStatusCodes +
+ +[]uint32 + +
+(Optional) +

RetriableStatusCodes specifies the HTTP status codes that should be retried.

+

This field is only respected when you include retriable-status-codes in the RetryOn field.

+
+

Route +

+

+(Appears on: +HTTPProxySpec) +

+

+

Route contains the set of routes for a virtual host.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]MatchCondition + + +
+(Optional) +

Conditions are a set of rules that are applied to a Route. +When applied, they are merged using AND, with one exception: +There can be only one Prefix, Exact or Regex MatchCondition +per Conditions slice. More than one of these condition types, +or contradictory Conditions, will make the route invalid.

+
+services +
+ + +[]Service + + +
+(Optional) +

Services are the services to proxy traffic.

+
+enableWebsockets +
+ +bool + +
+(Optional) +

Enables websocket support for the route.

+
+permitInsecure +
+ +bool + +
+(Optional) +

Allow this path to respond to insecure requests over HTTP which are normally +not permitted when a virtualhost.tls block is present.

+
+authPolicy +
+ + +AuthorizationPolicy + + +
+(Optional) +

AuthPolicy updates the authorization policy that was set +on the root HTTPProxy object for client requests that +match this route.

+
+timeoutPolicy +
+ + +TimeoutPolicy + + +
+(Optional) +

The timeout policy for this route.

+
+retryPolicy +
+ + +RetryPolicy + + +
+(Optional) +

The retry policy for this route.

+
+healthCheckPolicy +
+ + +HTTPHealthCheckPolicy + + +
+(Optional) +

The health check policy for this route.

+
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The load balancing policy for this route.

+
+pathRewritePolicy +
+ + +PathRewritePolicy + + +
+(Optional) +

The policy for rewriting the path of the request URL +after the request has been routed to a Service.

+
+requestHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing request headers during proxying.

+

You may dynamically rewrite the Host header to be forwarded +upstream to the content of a request header using +the below format “%REQ(X-Header-Name)%”. If the value of the header +is empty, it is ignored.

+

*NOTE: Pay attention to the potential security implications of using this option. +Provided header must come from trusted source.

+

**NOTE: The header rewrite is only done while forwarding and has no bearing +on the routing decision.

+
+responseHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing response headers during proxying. +Rewriting the ‘Host’ header is not supported.

+
+cookieRewritePolicies +
+ + +[]CookieRewritePolicy + + +
+(Optional) +

The policies for rewriting Set-Cookie header attributes. Note that +rewritten cookie names must be unique in this list. Order rewrite +policies are specified in does not matter.

+
+rateLimitPolicy +
+ + +RateLimitPolicy + + +
+(Optional) +

The policy for rate limiting on the route.

+
+requestRedirectPolicy +
+ + +HTTPRequestRedirectPolicy + + +
+(Optional) +

RequestRedirectPolicy defines an HTTP redirection.

+
+directResponsePolicy +
+ + +HTTPDirectResponsePolicy + + +
+(Optional) +

DirectResponsePolicy returns an arbitrary HTTP response directly.

+
+internalRedirectPolicy +
+ + +HTTPInternalRedirectPolicy + + +
+(Optional) +

The policy to define when to handle redirects responses internally.

+
+jwtVerificationPolicy +
+ + +JWTVerificationPolicy + + +
+(Optional) +

The policy for verifying JWTs for requests to this route.

+
+ipAllowPolicy +
+ + +[]IPFilterPolicy + + +
+

IPAllowFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be allowed. All other requests will be denied. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here override any rules set on the root HTTPProxy.

+
+ipDenyPolicy +
+ + +[]IPFilterPolicy + + +
+

IPDenyFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be denied. All other requests will be allowed. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here override any rules set on the root HTTPProxy.

+
+

Service +

+

+(Appears on: +Route, +TCPProxy) +

+

+

Service defines an Kubernetes Service to proxy traffic.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of Kubernetes service to proxy traffic. +Names defined here will be used to look up corresponding endpoints which contain the ips to route.

+
+port +
+ +int + +
+

Port (defined as Integer) to proxy traffic to since a service can have multiple defined.

+
+healthPort +
+ +int + +
+(Optional) +

HealthPort is the port for this service healthcheck. +If not specified, Port is used for service healthchecks.

+
+protocol +
+ +string + +
+(Optional) +

Protocol may be used to specify (or override) the protocol used to reach this Service. +Values may be tls, h2, h2c. If omitted, protocol-selection falls back on Service annotations.

+
+weight +
+ +int64 + +
+(Optional) +

Weight defines percentage of traffic to balance traffic

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the backend service’s certificate

+
+mirror +
+ +bool + +
+

If Mirror is true the Service will receive a read only mirror of the traffic for this route. +If Mirror is true, then fractional mirroring can be enabled by optionally setting the Weight +field. Legal values for Weight are 1-100. Omitting the Weight field will result in 100% mirroring. +NOTE: Setting Weight explicitly to 0 will unexpectedly result in 100% traffic mirroring. This +occurs since we cannot distinguish omitted fields from those explicitly set to their default +values

+
+requestHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing request headers during proxying.

+
+responseHeadersPolicy +
+ + +HeadersPolicy + + +
+(Optional) +

The policy for managing response headers during proxying. +Rewriting the ‘Host’ header is not supported.

+
+cookieRewritePolicies +
+ + +[]CookieRewritePolicy + + +
+(Optional) +

The policies for rewriting Set-Cookie header attributes.

+
+slowStartPolicy +
+ + +SlowStartPolicy + + +
+(Optional) +

Slow start will gradually increase amount of traffic to a newly added endpoint.

+
+

SlowStartPolicy +

+

+(Appears on: +Service) +

+

+

SlowStartPolicy will gradually increase amount of traffic to a newly added endpoint. +It can be used only with RoundRobin and WeightedLeastRequest load balancing strategies.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+window +
+ +string + +
+

The duration of slow start window. +Duration is expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”.

+
+aggression +
+ +string + +
+(Optional) +

The speed of traffic increase over the slow start window. +Defaults to 1.0, so that endpoint would get linearly increasing amount of traffic. +When increasing the value for this parameter, the speed of traffic ramp-up increases non-linearly. +The value of aggression parameter should be greater than 0.0.

+

More info: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/slow_start

+
+minWeightPercent +
+ +uint32 + +
+(Optional) +

The minimum or starting percentage of traffic to send to new endpoints. +A non-zero value helps avoid a too small initial weight, which may cause endpoints in slow start mode to receive no traffic in the beginning of the slow start window. +If not specified, the default is 10%.

+
+

SubCondition +

+

+(Appears on: +DetailedCondition) +

+

+

SubCondition is a Condition-like type intended for use as a subcondition inside a DetailedCondition.

+

It contains a subset of the Condition fields.

+

It is intended for warnings and errors, so type names should use abnormal-true polarity, +that is, they should be of the form “ErrorPresent: true”.

+

The expected lifecycle for these errors is that they should only be present when the error or warning is, +and should be removed when they are not relevant.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+type +
+ +string + +
+

Type of condition in CamelCase or in foo.example.com/CamelCase.

+

This must be in abnormal-true polarity, that is, ErrorFound or controller.io/ErrorFound.

+

The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)

+
+status +
+ + +Kubernetes meta/v1.ConditionStatus + + +
+

Status of the condition, one of True, False, Unknown.

+
+reason +
+ +string + +
+

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.

+
+message +
+ +string + +
+

Message is a human readable message indicating details about the transition.

+

This may be an empty string.

+
+

TCPHealthCheckPolicy +

+

+(Appears on: +TCPProxy) +

+

+

TCPHealthCheckPolicy defines health checks on the upstream service.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+intervalSeconds +
+ +int64 + +
+(Optional) +

The interval (seconds) between health checks

+
+timeoutSeconds +
+ +int64 + +
+(Optional) +

The time to wait (seconds) for a health check response

+
+unhealthyThresholdCount +
+ +uint32 + +
+(Optional) +

The number of unhealthy health checks required before a host is marked unhealthy

+
+healthyThresholdCount +
+ +uint32 + +
+(Optional) +

The number of healthy health checks required before a host is marked healthy

+
+

TCPProxy +

+

+(Appears on: +HTTPProxySpec) +

+

+

TCPProxy contains the set of services to proxy TCP connections.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The load balancing policy for the backend services. Note that the +Cookie and RequestHash load balancing strategies cannot be used +here.

+
+services +
+ + +[]Service + + +
+(Optional) +

Services are the services to proxy traffic

+
+include +
+ + +TCPProxyInclude + + +
+(Optional) +

Include specifies that this tcpproxy should be delegated to another HTTPProxy.

+
+includes +
+ + +TCPProxyInclude + + +
+(Optional) +

IncludesDeprecated allow for specific routing configuration to be appended to another HTTPProxy in another namespace.

+

Exists due to a mistake when developing HTTPProxy and the field was marked plural +when it should have been singular. This field should stay to not break backwards compatibility to v1 users.

+
+healthCheckPolicy +
+ + +TCPHealthCheckPolicy + + +
+(Optional) +

The health check policy for this tcp proxy

+
+

TCPProxyInclude +

+

+(Appears on: +TCPProxy) +

+

+

TCPProxyInclude describes a target HTTPProxy document which contains the TCPProxy details.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name of the child HTTPProxy

+
+namespace +
+ +string + +
+(Optional) +

Namespace of the HTTPProxy to include. Defaults to the current namespace if not supplied.

+
+

TLS +

+

+(Appears on: +VirtualHost) +

+

+

TLS describes tls properties. The SNI names that will be matched on +are described in the HTTPProxy’s Spec.VirtualHost.Fqdn field.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+secretName +
+ +string + +
+

SecretName is the name of a TLS secret. +Either SecretName or Passthrough must be specified, but not both. +If specified, the named secret must contain a matching certificate +for the virtual host’s FQDN. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret.

+
+minimumProtocolVersion +
+ +string + +
+(Optional) +

MinimumProtocolVersion is the minimum TLS version this vhost should +negotiate. Valid options are 1.2 (default) and 1.3. Any other value +defaults to TLS 1.2.

+
+maximumProtocolVersion +
+ +string + +
+(Optional) +

MaximumProtocolVersion is the maximum TLS version this vhost should +negotiate. Valid options are 1.2 and 1.3 (default). Any other value +defaults to TLS 1.3.

+
+passthrough +
+ +bool + +
+(Optional) +

Passthrough defines whether the encrypted TLS handshake will be +passed through to the backing cluster. Either Passthrough or +SecretName must be specified, but not both.

+
+clientValidation +
+ + +DownstreamValidation + + +
+(Optional) +

ClientValidation defines how to verify the client certificate +when an external client establishes a TLS connection to Envoy.

+

This setting:

+
    +
  1. Enables TLS client certificate validation.
  2. +
  3. Specifies how the client certificate will be validated (i.e. +validation required or skipped).
  4. +
+

Note: Setting client certificate validation to be skipped should +be only used in conjunction with an external authorization server that +performs client validation as Contour will ensure client certificates +are passed along.

+
+enableFallbackCertificate +
+ +bool + +
+

EnableFallbackCertificate defines if the vhost should allow a default certificate to +be applied which handles all requests which don’t match the SNI defined in this vhost.

+
+

TLSCertificateDelegationSpec +

+

+(Appears on: +TLSCertificateDelegation) +

+

+

TLSCertificateDelegationSpec defines the spec of the CRD

+

+ + + + + + + + + + + + + +
FieldDescription
+delegations +
+ + +[]CertificateDelegation + + +
+
+

TLSCertificateDelegationStatus +

+

+(Appears on: +TLSCertificateDelegation) +

+

+

TLSCertificateDelegationStatus allows for the status of the delegation +to be presented to the user.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains information about the current status of the HTTPProxy, +in an upstream-friendly container.

+

Contour will update a single condition, Valid, that is in normal-true polarity. +That is, when currentStatus is valid, the Valid condition will be status: true, +and vice versa.

+

Contour will leave untouched any other Conditions set in this block, +in case some other controller wants to add a Condition.

+

If you are another controller owner and wish to add a condition, you should +namespace your condition with a label, like controller.domain.com\ConditionName.

+
+

TimeoutPolicy +

+

+(Appears on: +Route, +ExtensionServiceSpec) +

+

+

TimeoutPolicy configures timeouts that are used for handling network requests.

+

TimeoutPolicy durations are expressed in the Go Duration format. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. +The string “infinity” is also a valid input and specifies no timeout. +A value of “0s” will be treated as if the field were not set, i.e. by using Envoy’s default behavior.

+

Example input values: “300ms”, “5s”, “1m”.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+response +
+ +string + +
+(Optional) +

Timeout for receiving a response from the server after processing a request from client. +If not supplied, Envoy’s default value of 15s applies.

+
+idle +
+ +string + +
+(Optional) +

Timeout for how long the proxy should wait while there is no activity during single request/response (for HTTP/1.1) or stream (for HTTP/2). +Timeout will not trigger while HTTP/1.1 connection is idle between two consecutive requests. +If not specified, there is no per-route idle timeout, though a connection manager-wide +stream_idle_timeout default of 5m still applies.

+
+idleConnection +
+ +string + +
+(Optional) +

Timeout for how long connection from the proxy to the upstream service is kept when there are no active requests. +If not supplied, Envoy’s default value of 1h applies.

+
+

UpstreamValidation +

+

+(Appears on: +RemoteJWKS, +Service, +ExtensionServiceSpec) +

+

+

UpstreamValidation defines how to verify the backend service’s certificate

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caSecret +
+ +string + +
+

Name or namespaced name of the Kubernetes secret used to validate the certificate presented by the backend. +The secret must contain key named ca.crt. +The name can be optionally prefixed with namespace “namespace/name”. +When cross-namespace reference is used, TLSCertificateDelegation resource must exist in the namespace to grant access to the secret. +Max length should be the actual max possible length of a namespaced name (63 + 253 + 1 = 317)

+
+subjectName +
+ +string + +
+

Key which is expected to be present in the ‘subjectAltName’ of the presented certificate. +Deprecated: migrate to using the plural field subjectNames.

+
+subjectNames +
+ +[]string + +
+(Optional) +

List of keys, of which at least one is expected to be present in the ‘subjectAltName of the +presented certificate.

+
+

VirtualHost +

+

+(Appears on: +HTTPProxySpec) +

+

+

VirtualHost appears at most once. If it is present, the object is considered +to be a “root”.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+fqdn +
+ +string + +
+

The fully qualified domain name of the root of the ingress tree +all leaves of the DAG rooted at this object relate to the fqdn.

+
+tls +
+ + +TLS + + +
+(Optional) +

If present the fields describes TLS properties of the virtual +host. The SNI names that will be matched on are described in fqdn, +the tls.secretName secret must contain a certificate that itself +contains a name that matches the FQDN.

+
+authorization +
+ + +AuthorizationServer + + +
+(Optional) +

This field configures an extension service to perform +authorization for this virtual host. Authorization can +only be configured on virtual hosts that have TLS enabled. +If the TLS configuration requires client certificate +validation, the client certificate is always included in the +authentication check request.

+
+corsPolicy +
+ + +CORSPolicy + + +
+(Optional) +

Specifies the cross-origin policy to apply to the VirtualHost.

+
+rateLimitPolicy +
+ + +RateLimitPolicy + + +
+(Optional) +

The policy for rate limiting on the virtual host.

+
+jwtProviders +
+ + +[]JWTProvider + + +
+(Optional) +

Providers to use for verifying JSON Web Tokens (JWTs) on the virtual host.

+
+ipAllowPolicy +
+ + +[]IPFilterPolicy + + +
+

IPAllowFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be allowed. All other requests will be denied. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here may be overridden in a Route.

+
+ipDenyPolicy +
+ + +[]IPFilterPolicy + + +
+

IPDenyFilterPolicy is a list of ipv4/6 filter rules for which matching +requests should be denied. All other requests will be allowed. +Only one of IPAllowFilterPolicy and IPDenyFilterPolicy can be defined. +The rules defined here may be overridden in a Route.

+
+
+

projectcontour.io/v1alpha1

+

+

Package v1alpha1 contains API Schema definitions for the projectcontour.io v1alpha1 API group

+

+Resource Types: + +

ContourConfiguration +

+

+

ContourConfiguration is the schema for a Contour instance.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1alpha1 + +
+kind
+string +
ContourConfiguration
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +ContourConfigurationSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+xdsServer +
+ + +XDSServerConfig + + +
+(Optional) +

XDSServer contains parameters for the xDS server.

+
+ingress +
+ + +IngressConfig + + +
+(Optional) +

Ingress contains parameters for ingress options.

+
+debug +
+ + +DebugConfig + + +
+(Optional) +

Debug contains parameters to enable debug logging +and debug interfaces inside Contour.

+
+health +
+ + +HealthConfig + + +
+(Optional) +

Health defines the endpoints Contour uses to serve health checks.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+envoy +
+ + +EnvoyConfig + + +
+(Optional) +

Envoy contains parameters for Envoy as well +as how to optionally configure a managed Envoy fleet.

+
+gateway +
+ + +GatewayConfig + + +
+(Optional) +

Gateway contains parameters for the gateway-api Gateway that Contour +is configured to serve traffic.

+
+httpproxy +
+ + +HTTPProxyConfig + + +
+(Optional) +

HTTPProxy defines parameters on HTTPProxy.

+
+enableExternalNameService +
+ +bool + +
+(Optional) +

EnableExternalNameService allows processing of ExternalNameServices

+

Contour’s default is false for security reasons.

+
+globalExtAuth +
+ + +AuthorizationServer + + +
+(Optional) +

GlobalExternalAuthorization allows envoys external authorization filter +to be enabled for all virtual hosts.

+
+rateLimitService +
+ + +RateLimitServiceConfig + + +
+(Optional) +

RateLimitService optionally holds properties of the Rate Limit Service +to be used for global rate limiting.

+
+policy +
+ + +PolicyConfig + + +
+(Optional) +

Policy specifies default policy applied if not overridden by the user

+
+metrics +
+ + +MetricsConfig + + +
+(Optional) +

Metrics defines the endpoint Contour uses to serve metrics.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+tracing +
+ + +TracingConfig + + +
+

Tracing defines properties for exporting trace data to OpenTelemetry.

+
+featureFlags +
+ + +FeatureFlags + + +
+

FeatureFlags defines toggle to enable new contour features. +Available toggles are: +useEndpointSlices - Configures contour to fetch endpoint data +from k8s endpoint slices. defaults to true, +If false then reads endpoint data from the k8s endpoints.

+
+
+status +
+ + +ContourConfigurationStatus + + +
+(Optional) +
+

ContourDeployment +

+

+

ContourDeployment is the schema for a Contour Deployment.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1alpha1 + +
+kind
+string +
ContourDeployment
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +ContourDeploymentSpec + + +
+
+
+ + + + + + + + + + + + + + + + + +
+contour +
+ + +ContourSettings + + +
+(Optional) +

Contour specifies deployment-time settings for the Contour +part of the installation, i.e. the xDS server/control plane +and associated resources, including things like replica count +for the Deployment, and node placement constraints for the pods.

+
+envoy +
+ + +EnvoySettings + + +
+(Optional) +

Envoy specifies deployment-time settings for the Envoy +part of the installation, i.e. the xDS client/data plane +and associated resources, including things like the workload +type to use (DaemonSet or Deployment), node placement constraints +for the pods, and various options for the Envoy service.

+
+runtimeSettings +
+ + +ContourConfigurationSpec + + +
+(Optional) +

RuntimeSettings is a ContourConfiguration spec to be used when +provisioning a Contour instance that will influence aspects of +the Contour instance’s runtime behavior.

+
+resourceLabels +
+ +map[string]string + +
+(Optional) +

ResourceLabels is a set of labels to add to the provisioned Contour resources.

+

Deprecated: use Gateway.Spec.Infrastructure.Labels instead. This field will be +removed in a future release.

+
+
+status +
+ + +ContourDeploymentStatus + + +
+
+

ExtensionService +

+

+

ExtensionService is the schema for the Contour extension services API. +An ExtensionService resource binds a network service to the Contour +API so that Contour API features can be implemented by collaborating +components.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+ +projectcontour.io/v1alpha1 + +
+kind
+string +
ExtensionService
+metadata +
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec +
+ + +ExtensionServiceSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+services +
+ + +[]ExtensionServiceTarget + + +
+

Services specifies the set of Kubernetes Service resources that +receive GRPC extension API requests. +If no weights are specified for any of the entries in +this array, traffic will be spread evenly across all the +services. +Otherwise, traffic is balanced proportionally to the +Weight field in each entry.

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the backend service’s certificate

+
+protocol +
+ +string + +
+(Optional) +

Protocol may be used to specify (or override) the protocol used to reach this Service. +Values may be h2 or h2c. If omitted, protocol-selection falls back on Service annotations.

+
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The policy for load balancing GRPC service requests. Note that the +Cookie and RequestHash load balancing strategies cannot be used +here.

+
+timeoutPolicy +
+ + +TimeoutPolicy + + +
+(Optional) +

The timeout policy for requests to the services.

+
+protocolVersion +
+ + +ExtensionProtocolVersion + + +
+(Optional) +

This field sets the version of the GRPC protocol that Envoy uses to +send requests to the extension service. Since Contour always uses the +v3 Envoy API, this is currently fixed at “v3”. However, other +protocol options will be available in future.

+
+circuitBreakerPolicy +
+ + +CircuitBreakers + + +
+(Optional) +

CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. +If defined this overrides the global circuit breaker budget.

+
+
+status +
+ + +ExtensionServiceStatus + + +
+
+

AccessLogFormatString +(string alias)

+

+

+

AccessLogJSONFields +([]string alias)

+

+(Appears on: +EnvoyLogging) +

+

+

+

AccessLogLevel +(string alias)

+

+(Appears on: +EnvoyLogging) +

+

+

+ + + + + + + + + + + + + + + + +
ValueDescription

"critical"

Log only requests that result in an server error (i.e. 500+) response code.

+

"disabled"

Disable the access log.

+

"error"

Log only requests that result in a non-success (i.e. 300+) response code

+

"info"

Log all requests. This is the default.

+
+

AccessLogType +(string alias)

+

+(Appears on: +EnvoyLogging) +

+

+

AccessLogType is the name of a supported access logging mechanism.

+

+ + + + + + + + + + + + + + +
ValueDescription

"envoy"

DefaultAccessLogType is the default access log format.

+

"envoy"

Set the Envoy access logging to Envoy’s standard format. +Can be customized using accessLogFormatString.

+

"json"

Set the Envoy access logging to a JSON format. +Can be customized using jsonFields.

+
+

CircuitBreakers +

+

+(Appears on: +ClusterParameters, +ExtensionServiceSpec) +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+maxConnections +
+ +uint32 + +
+(Optional) +

The maximum number of connections that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

+
+maxPendingRequests +
+ +uint32 + +
+(Optional) +

The maximum number of pending requests that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

+
+maxRequests +
+ +uint32 + +
+(Optional) +

The maximum parallel requests a single Envoy instance allows to the Kubernetes Service; defaults to 1024

+
+maxRetries +
+ +uint32 + +
+(Optional) +

The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3.

+
+perHostMaxConnections +
+ +uint32 + +
+

PerHostMaxConnections is the maximum number of connections +that Envoy will allow to each individual host in a cluster.

+
+

ClusterDNSFamilyType +(string alias)

+

+(Appears on: +ClusterParameters) +

+

+

ClusterDNSFamilyType is the Ip family to use for resolving DNS +names in an Envoy cluster config.

+

+ + + + + + + + + + + + + + + + +
ValueDescription

"all"

DNS lookups will attempt both v4 and v6 queries.

+

"auto"

DNS lookups will do a v6 lookup first, followed by a v4 if that fails.

+

"v4"

DNS lookups will only attempt v4 queries.

+

"v6"

DNS lookups will only attempt v6 queries.

+
+

ClusterParameters +

+

+(Appears on: +EnvoyConfig) +

+

+

ClusterParameters holds various configurable cluster values.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+dnsLookupFamily +
+ + +ClusterDNSFamilyType + + +
+(Optional) +

DNSLookupFamily defines how external names are looked up +When configured as V4, the DNS resolver will only perform a lookup +for addresses in the IPv4 family. If V6 is configured, the DNS resolver +will only perform a lookup for addresses in the IPv6 family. +If AUTO is configured, the DNS resolver will first perform a lookup +for addresses in the IPv6 family and fallback to a lookup for addresses +in the IPv4 family. If ALL is specified, the DNS resolver will perform a lookup for +both IPv4 and IPv6 families, and return all resolved addresses. +When this is used, Happy Eyeballs will be enabled for upstream connections. +Refer to Happy Eyeballs Support for more information. +Note: This only applies to externalName clusters.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto.html#envoy-v3-api-enum-config-cluster-v3-cluster-dnslookupfamily +for more information.

+

Values: auto (default), v4, v6, all.

+

Other values will produce an error.

+
+maxRequestsPerConnection +
+ +uint32 + +
+(Optional) +

Defines the maximum requests for upstream connections. If not specified, there is no limit. +see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-msg-config-core-v3-httpprotocoloptions +for more information.

+
+per-connection-buffer-limit-bytes +
+ +uint32 + +
+(Optional) +

Defines the soft limit on size of the cluster’s new connection read and write buffers in bytes. +If unspecified, an implementation defined default is applied (1MiB). +see 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 +for more information.

+
+circuitBreakers +
+ + +CircuitBreakers + + +
+(Optional) +

GlobalCircuitBreakerDefaults specifies default circuit breaker budget across all services. +If defined, this will be used as the default for all services.

+
+upstreamTLS +
+ + +EnvoyTLS + + +
+(Optional) +

UpstreamTLS contains the TLS policy parameters for upstream connections

+
+

ContourConfigurationSpec +

+

+(Appears on: +ContourConfiguration, +ContourDeploymentSpec) +

+

+

ContourConfigurationSpec represents a configuration of a Contour controller. +It contains most of all the options that can be customized, the +other remaining options being command line flags.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+xdsServer +
+ + +XDSServerConfig + + +
+(Optional) +

XDSServer contains parameters for the xDS server.

+
+ingress +
+ + +IngressConfig + + +
+(Optional) +

Ingress contains parameters for ingress options.

+
+debug +
+ + +DebugConfig + + +
+(Optional) +

Debug contains parameters to enable debug logging +and debug interfaces inside Contour.

+
+health +
+ + +HealthConfig + + +
+(Optional) +

Health defines the endpoints Contour uses to serve health checks.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+envoy +
+ + +EnvoyConfig + + +
+(Optional) +

Envoy contains parameters for Envoy as well +as how to optionally configure a managed Envoy fleet.

+
+gateway +
+ + +GatewayConfig + + +
+(Optional) +

Gateway contains parameters for the gateway-api Gateway that Contour +is configured to serve traffic.

+
+httpproxy +
+ + +HTTPProxyConfig + + +
+(Optional) +

HTTPProxy defines parameters on HTTPProxy.

+
+enableExternalNameService +
+ +bool + +
+(Optional) +

EnableExternalNameService allows processing of ExternalNameServices

+

Contour’s default is false for security reasons.

+
+globalExtAuth +
+ + +AuthorizationServer + + +
+(Optional) +

GlobalExternalAuthorization allows envoys external authorization filter +to be enabled for all virtual hosts.

+
+rateLimitService +
+ + +RateLimitServiceConfig + + +
+(Optional) +

RateLimitService optionally holds properties of the Rate Limit Service +to be used for global rate limiting.

+
+policy +
+ + +PolicyConfig + + +
+(Optional) +

Policy specifies default policy applied if not overridden by the user

+
+metrics +
+ + +MetricsConfig + + +
+(Optional) +

Metrics defines the endpoint Contour uses to serve metrics.

+

Contour’s default is { address: “0.0.0.0”, port: 8000 }.

+
+tracing +
+ + +TracingConfig + + +
+

Tracing defines properties for exporting trace data to OpenTelemetry.

+
+featureFlags +
+ + +FeatureFlags + + +
+

FeatureFlags defines toggle to enable new contour features. +Available toggles are: +useEndpointSlices - Configures contour to fetch endpoint data +from k8s endpoint slices. defaults to true, +If false then reads endpoint data from the k8s endpoints.

+
+

ContourConfigurationStatus +

+

+(Appears on: +ContourConfiguration) +

+

+

ContourConfigurationStatus defines the observed state of a ContourConfiguration resource.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains the current status of the Contour resource.

+

Contour will update a single condition, Valid, that is in normal-true polarity.

+

Contour will not modify any other Conditions set in this block, +in case some other controller wants to add a Condition.

+
+

ContourDeploymentSpec +

+

+(Appears on: +ContourDeployment) +

+

+

ContourDeploymentSpec specifies options for how a Contour +instance should be provisioned.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+contour +
+ + +ContourSettings + + +
+(Optional) +

Contour specifies deployment-time settings for the Contour +part of the installation, i.e. the xDS server/control plane +and associated resources, including things like replica count +for the Deployment, and node placement constraints for the pods.

+
+envoy +
+ + +EnvoySettings + + +
+(Optional) +

Envoy specifies deployment-time settings for the Envoy +part of the installation, i.e. the xDS client/data plane +and associated resources, including things like the workload +type to use (DaemonSet or Deployment), node placement constraints +for the pods, and various options for the Envoy service.

+
+runtimeSettings +
+ + +ContourConfigurationSpec + + +
+(Optional) +

RuntimeSettings is a ContourConfiguration spec to be used when +provisioning a Contour instance that will influence aspects of +the Contour instance’s runtime behavior.

+
+resourceLabels +
+ +map[string]string + +
+(Optional) +

ResourceLabels is a set of labels to add to the provisioned Contour resources.

+

Deprecated: use Gateway.Spec.Infrastructure.Labels instead. This field will be +removed in a future release.

+
+

ContourDeploymentStatus +

+

+(Appears on: +ContourDeployment) +

+

+

ContourDeploymentStatus defines the observed state of a ContourDeployment resource.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]Kubernetes meta/v1.Condition + + +
+(Optional) +

Conditions describe the current conditions of the ContourDeployment resource.

+
+

ContourSettings +

+

+(Appears on: +ContourDeploymentSpec) +

+

+

ContourSettings contains settings for the Contour part of the installation, +i.e. the xDS server/control plane and associated resources.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+replicas +
+ +int32 + +
+(Optional) +

Deprecated: Use DeploymentSettings.Replicas instead.

+

Replicas is the desired number of Contour replicas. If if unset, +defaults to 2.

+

if both DeploymentSettings.Replicas and this one is set, use DeploymentSettings.Replicas.

+
+nodePlacement +
+ + +NodePlacement + + +
+(Optional) +

NodePlacement describes node scheduling configuration of Contour pods.

+
+kubernetesLogLevel +
+ +byte + +
+(Optional) +

KubernetesLogLevel Enable Kubernetes client debug logging with log level. If unset, +defaults to 0.

+
+logLevel +
+ + +LogLevel + + +
+(Optional) +

LogLevel sets the log level for Contour +Allowed values are “info”, “debug”.

+
+resources +
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Compute Resources required by contour container. +Cannot be updated. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

+
+deployment +
+ + +DeploymentSettings + + +
+(Optional) +

Deployment describes the settings for running contour as a Deployment.

+
+podAnnotations +
+ +map[string]string + +
+(Optional) +

PodAnnotations defines annotations to add to the Contour pods. +the annotations for Prometheus will be appended or overwritten with predefined value.

+
+watchNamespaces +
+ + +[]Namespace + + +
+(Optional) +

WatchNamespaces is an array of namespaces. Setting it will instruct the contour instance +to only watch this subset of namespaces.

+
+disabledFeatures +
+ + +[]Feature + + +
+(Optional) +

DisabledFeatures defines an array of resources that will be ignored by +contour reconciler.

+
+

CustomTag +

+

+

CustomTag defines custom tags with unique tag name +to create tags for the active span.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+tagName +
+ +string + +
+

TagName is the unique name of the custom tag.

+
+literal +
+ +string + +
+(Optional) +

Literal is a static custom tag value. +Precisely one of Literal, RequestHeaderName must be set.

+
+requestHeaderName +
+ +string + +
+(Optional) +

RequestHeaderName indicates which request header +the label value is obtained from. +Precisely one of Literal, RequestHeaderName must be set.

+
+

DaemonSetSettings +

+

+(Appears on: +EnvoySettings) +

+

+

DaemonSetSettings contains settings for DaemonSet resources.

+

+ + + + + + + + + + + + + +
FieldDescription
+updateStrategy +
+ + +Kubernetes apps/v1.DaemonSetUpdateStrategy + + +
+(Optional) +

Strategy describes the deployment strategy to use to replace existing DaemonSet pods with new pods.

+
+

DebugConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

DebugConfig contains Contour specific troubleshooting options.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines the Contour debug address interface.

+

Contour’s default is “127.0.0.1”.

+
+port +
+ +int + +
+(Optional) +

Defines the Contour debug address port.

+

Contour’s default is 6060.

+
+

DeploymentSettings +

+

+(Appears on: +ContourSettings, +EnvoySettings) +

+

+

DeploymentSettings contains settings for Deployment resources.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+replicas +
+ +int32 + +
+

Replicas is the desired number of replicas.

+
+strategy +
+ + +Kubernetes apps/v1.DeploymentStrategy + + +
+(Optional) +

Strategy describes the deployment strategy to use to replace existing pods with new pods.

+
+

EnvoyConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

EnvoyConfig defines how Envoy is to be Configured from Contour.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+listener +
+ + +EnvoyListenerConfig + + +
+(Optional) +

Listener hold various configurable Envoy listener values.

+
+service +
+ + +NamespacedName + + +
+(Optional) +

Service holds Envoy service parameters for setting Ingress status.

+

Contour’s default is { namespace: “projectcontour”, name: “envoy” }.

+
+http +
+ + +EnvoyListener + + +
+(Optional) +

Defines the HTTP Listener for Envoy.

+

Contour’s default is { address: “0.0.0.0”, port: 8080, accessLog: “/dev/stdout” }.

+
+https +
+ + +EnvoyListener + + +
+(Optional) +

Defines the HTTPS Listener for Envoy.

+

Contour’s default is { address: “0.0.0.0”, port: 8443, accessLog: “/dev/stdout” }.

+
+health +
+ + +HealthConfig + + +
+(Optional) +

Health defines the endpoint Envoy uses to serve health checks.

+

Contour’s default is { address: “0.0.0.0”, port: 8002 }.

+
+metrics +
+ + +MetricsConfig + + +
+(Optional) +

Metrics defines the endpoint Envoy uses to serve metrics.

+

Contour’s default is { address: “0.0.0.0”, port: 8002 }.

+
+clientCertificate +
+ + +NamespacedName + + +
+(Optional) +

ClientCertificate defines the namespace/name of the Kubernetes +secret containing the client certificate and private key +to be used when establishing TLS connection to upstream +cluster.

+
+logging +
+ + +EnvoyLogging + + +
+(Optional) +

Logging defines how Envoy’s logs can be configured.

+
+defaultHTTPVersions +
+ + +[]HTTPVersionType + + +
+(Optional) +

DefaultHTTPVersions defines the default set of HTTPS +versions the proxy should accept. HTTP versions are +strings of the form “HTTP/xx”. Supported versions are +“HTTP/1.1” and “HTTP/2”.

+

Values: HTTP/1.1, HTTP/2 (default: both).

+

Other values will produce an error.

+
+timeouts +
+ + +TimeoutParameters + + +
+(Optional) +

Timeouts holds various configurable timeouts that can +be set in the config file.

+
+cluster +
+ + +ClusterParameters + + +
+(Optional) +

Cluster holds various configurable Envoy cluster values that can +be set in the config file.

+
+network +
+ + +NetworkParameters + + +
+(Optional) +

Network holds various configurable Envoy network values.

+
+

EnvoyListener +

+

+(Appears on: +EnvoyConfig) +

+

+

EnvoyListener defines parameters for an Envoy Listener.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines an Envoy Listener Address.

+
+port +
+ +int + +
+(Optional) +

Defines an Envoy listener Port.

+
+accessLog +
+ +string + +
+(Optional) +

AccessLog defines where Envoy logs are outputted for this listener.

+
+

EnvoyListenerConfig +

+

+(Appears on: +EnvoyConfig) +

+

+

EnvoyListenerConfig hold various configurable Envoy listener values.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+useProxyProtocol +
+ +bool + +
+(Optional) +

Use PROXY protocol for all listeners.

+

Contour’s default is false.

+
+disableAllowChunkedLength +
+ +bool + +
+(Optional) +

DisableAllowChunkedLength disables the RFC-compliant Envoy behavior to +strip the “Content-Length” header if “Transfer-Encoding: chunked” is +also set. This is an emergency off-switch to revert back to Envoy’s +default behavior in case of failures. Please file an issue if failures +are encountered. +See: https://github.com/projectcontour/contour/issues/3221

+

Contour’s default is false.

+
+disableMergeSlashes +
+ +bool + +
+(Optional) +

DisableMergeSlashes disables Envoy’s non-standard merge_slashes path transformation option +which strips duplicate slashes from request URL paths.

+

Contour’s default is false.

+
+serverHeaderTransformation +
+ + +ServerHeaderTransformationType + + +
+(Optional) +

Defines the action to be applied to the Server header on the response path. +When configured as overwrite, overwrites any Server header with “envoy”. +When configured as append_if_absent, if a Server header is present, pass it through, otherwise set it to “envoy”. +When configured as pass_through, pass through the value of the Server header, and do not append a header if none is present.

+

Values: overwrite (default), append_if_absent, pass_through

+

Other values will produce an error. +Contour’s default is overwrite.

+
+connectionBalancer +
+ +string + +
+(Optional) +

ConnectionBalancer. If the value is exact, the listener will use the exact connection balancer +See https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/listener.proto#envoy-api-msg-listener-connectionbalanceconfig +for more information.

+

Values: (empty string): use the default ConnectionBalancer, exact: use the Exact ConnectionBalancer.

+

Other values will produce an error.

+
+maxRequestsPerConnection +
+ +uint32 + +
+(Optional) +

Defines the maximum requests for downstream connections. If not specified, there is no limit. +see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-msg-config-core-v3-httpprotocoloptions +for more information.

+
+per-connection-buffer-limit-bytes +
+ +uint32 + +
+(Optional) +

Defines the soft limit on size of the listener’s new connection read and write buffers in bytes. +If unspecified, an implementation defined default is applied (1MiB). +see 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 +for more information.

+
+tls +
+ + +EnvoyTLS + + +
+(Optional) +

TLS holds various configurable Envoy TLS listener values.

+
+socketOptions +
+ + +SocketOptions + + +
+(Optional) +

SocketOptions defines configurable socket options for the listeners. +Single set of options are applied to all listeners.

+
+maxRequestsPerIOCycle +
+ +uint32 + +
+(Optional) +

Defines the limit on number of HTTP requests that Envoy will process from a single +connection in a single I/O cycle. Requests over this limit are processed in subsequent +I/O cycles. Can be used as a mitigation for CVE-2023-44487 when abusive traffic is +detected. Configures the http.max_requests_per_io_cycle Envoy runtime setting. The default +value when this is not set is no limit.

+
+httpMaxConcurrentStreams +
+ +uint32 + +
+(Optional) +

Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS Envoy will advertise in the +SETTINGS frame in HTTP/2 connections and the limit for concurrent streams allowed +for a peer on a single HTTP/2 connection. It is recommended to not set this lower +than 100 but this field can be used to bound resource usage by HTTP/2 connections +and mitigate attacks like CVE-2023-44487. The default value when this is not set is +unlimited.

+
+maxConnectionsPerListener +
+ +uint32 + +
+(Optional) +

Defines the limit on number of active connections to a listener. The limit is applied +per listener. The default value when this is not set is unlimited.

+
+

EnvoyLogging +

+

+(Appears on: +EnvoyConfig) +

+

+

EnvoyLogging defines how Envoy’s logs can be configured.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+accessLogFormat +
+ + +AccessLogType + + +
+(Optional) +

AccessLogFormat sets the global access log format.

+

Values: envoy (default), json.

+

Other values will produce an error.

+
+accessLogFormatString +
+ +string + +
+(Optional) +

AccessLogFormatString sets the access log format when format is set to envoy. +When empty, Envoy’s default format is used.

+
+accessLogJSONFields +
+ + +AccessLogJSONFields + + +
+(Optional) +

AccessLogJSONFields sets the fields that JSON logging will +output when AccessLogFormat is json.

+
+accessLogLevel +
+ + +AccessLogLevel + + +
+(Optional) +

AccessLogLevel sets the verbosity level of the access log.

+

Values: info (default, all requests are logged), error (all non-success requests, i.e. 300+ response code, are logged), critical (all 5xx requests are logged) and disabled.

+

Other values will produce an error.

+
+

EnvoySettings +

+

+(Appears on: +ContourDeploymentSpec) +

+

+

EnvoySettings contains settings for the Envoy part of the installation, +i.e. the xDS client/data plane and associated resources.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+workloadType +
+ + +WorkloadType + + +
+(Optional) +

WorkloadType is the type of workload to install Envoy +as. Choices are DaemonSet and Deployment. If unset, defaults +to DaemonSet.

+
+replicas +
+ +int32 + +
+(Optional) +

Deprecated: Use DeploymentSettings.Replicas instead.

+

Replicas is the desired number of Envoy replicas. If WorkloadType +is not “Deployment”, this field is ignored. Otherwise, if unset, +defaults to 2.

+

if both DeploymentSettings.Replicas and this one is set, use DeploymentSettings.Replicas.

+
+networkPublishing +
+ + +NetworkPublishing + + +
+

NetworkPublishing defines how to expose Envoy to a network.

+
+nodePlacement +
+ + +NodePlacement + + +
+(Optional) +

NodePlacement describes node scheduling configuration of Envoy pods.

+
+extraVolumes +
+ + +[]Kubernetes core/v1.Volume + + +
+(Optional) +

ExtraVolumes holds the extra volumes to add.

+
+extraVolumeMounts +
+ + +[]Kubernetes core/v1.VolumeMount + + +
+(Optional) +

ExtraVolumeMounts holds the extra volume mounts to add (normally used with extraVolumes).

+
+podAnnotations +
+ +map[string]string + +
+(Optional) +

PodAnnotations defines annotations to add to the Envoy pods. +the annotations for Prometheus will be appended or overwritten with predefined value.

+
+resources +
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Compute Resources required by envoy container. +Cannot be updated. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

+
+logLevel +
+ + +LogLevel + + +
+(Optional) +

LogLevel sets the log level for Envoy. +Allowed values are “trace”, “debug”, “info”, “warn”, “error”, “critical”, “off”.

+
+daemonSet +
+ + +DaemonSetSettings + + +
+(Optional) +

DaemonSet describes the settings for running envoy as a DaemonSet. +if WorkloadType is Deployment,it’s must be nil

+
+deployment +
+ + +DeploymentSettings + + +
+(Optional) +

Deployment describes the settings for running envoy as a Deployment. +if WorkloadType is DaemonSet,it’s must be nil

+
+baseID +
+ +int32 + +
+(Optional) +

The base ID to use when allocating shared memory regions. +if Envoy needs to be run multiple times on the same machine, each running Envoy will need a unique base ID +so that the shared memory regions do not conflict. +defaults to 0.

+
+overloadMaxHeapSize +
+ +uint64 + +
+(Optional) +

OverloadMaxHeapSize defines the maximum heap memory of the envoy controlled by the overload manager. +When the value is greater than 0, the overload manager is enabled, +and when envoy reaches 95% of the maximum heap size, it performs a shrink heap operation, +When it reaches 98% of the maximum heap size, Envoy Will stop accepting requests. +More info: https://projectcontour.io/docs/main/config/overload-manager/

+
+

EnvoyTLS +

+

+(Appears on: +ClusterParameters, +EnvoyListenerConfig) +

+

+

EnvoyTLS describes tls parameters for Envoy listneners.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+minimumProtocolVersion +
+ +string + +
+(Optional) +

MinimumProtocolVersion is the minimum TLS version this vhost should +negotiate.

+

Values: 1.2 (default), 1.3.

+

Other values will produce an error.

+
+maximumProtocolVersion +
+ +string + +
+(Optional) +

MaximumProtocolVersion is the maximum TLS version this vhost should +negotiate.

+

Values: 1.2, 1.3(default).

+

Other values will produce an error.

+
+cipherSuites +
+ +[]string + +
+(Optional) +

CipherSuites defines the TLS ciphers to be supported by Envoy TLS +listeners when negotiating TLS 1.2. Ciphers are validated against the +set that Envoy supports by default. This parameter should only be used +by advanced users. Note that these will be ignored when TLS 1.3 is in +use.

+

This field is optional; when it is undefined, a Contour-managed ciphersuite list +will be used, which may be updated to keep it secure.

+

Contour’s default 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”

+

Ciphers provided are validated against the following list: +- “[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]” +- “[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]” +- “ECDHE-ECDSA-AES128-GCM-SHA256” +- “ECDHE-RSA-AES128-GCM-SHA256” +- “ECDHE-ECDSA-AES128-SHA” +- “ECDHE-RSA-AES128-SHA” +- “AES128-GCM-SHA256” +- “AES128-SHA” +- “ECDHE-ECDSA-AES256-GCM-SHA384” +- “ECDHE-RSA-AES256-GCM-SHA384” +- “ECDHE-ECDSA-AES256-SHA” +- “ECDHE-RSA-AES256-SHA” +- “AES256-GCM-SHA384” +- “AES256-SHA”

+

Contour recommends leaving this undefined unless you are sure you must.

+

See: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlsparameters +Note: This list is a superset of what is valid for stock Envoy builds and those using BoringSSL FIPS.

+
+

ExtensionProtocolVersion +(string alias)

+

+(Appears on: +ExtensionServiceSpec) +

+

+

ExtensionProtocolVersion is the version of the GRPC protocol used +to access extension services. The only version currently supported +is “v3”.

+

+ + + + + + + + + + + + +
ValueDescription

"v2"

SupportProtocolVersion2 requests the “v2” support protocol version.

+

Deprecated: this protocol version is no longer supported and the +constant is retained for backwards compatibility only.

+

"v3"

SupportProtocolVersion3 requests the “v3” support protocol version.

+
+

ExtensionServiceSpec +

+

+(Appears on: +ExtensionService) +

+

+

ExtensionServiceSpec defines the desired state of an ExtensionService resource.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+services +
+ + +[]ExtensionServiceTarget + + +
+

Services specifies the set of Kubernetes Service resources that +receive GRPC extension API requests. +If no weights are specified for any of the entries in +this array, traffic will be spread evenly across all the +services. +Otherwise, traffic is balanced proportionally to the +Weight field in each entry.

+
+validation +
+ + +UpstreamValidation + + +
+(Optional) +

UpstreamValidation defines how to verify the backend service’s certificate

+
+protocol +
+ +string + +
+(Optional) +

Protocol may be used to specify (or override) the protocol used to reach this Service. +Values may be h2 or h2c. If omitted, protocol-selection falls back on Service annotations.

+
+loadBalancerPolicy +
+ + +LoadBalancerPolicy + + +
+(Optional) +

The policy for load balancing GRPC service requests. Note that the +Cookie and RequestHash load balancing strategies cannot be used +here.

+
+timeoutPolicy +
+ + +TimeoutPolicy + + +
+(Optional) +

The timeout policy for requests to the services.

+
+protocolVersion +
+ + +ExtensionProtocolVersion + + +
+(Optional) +

This field sets the version of the GRPC protocol that Envoy uses to +send requests to the extension service. Since Contour always uses the +v3 Envoy API, this is currently fixed at “v3”. However, other +protocol options will be available in future.

+
+circuitBreakerPolicy +
+ + +CircuitBreakers + + +
+(Optional) +

CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. +If defined this overrides the global circuit breaker budget.

+
+

ExtensionServiceStatus +

+

+(Appears on: +ExtensionService) +

+

+

ExtensionServiceStatus defines the observed state of an +ExtensionService resource.

+

+ + + + + + + + + + + + + +
FieldDescription
+conditions +
+ + +[]DetailedCondition + + +
+(Optional) +

Conditions contains the current status of the ExtensionService resource.

+

Contour will update a single condition, Valid, that is in normal-true polarity.

+

Contour will not modify any other Conditions set in this block, +in case some other controller wants to add a Condition.

+
+

ExtensionServiceTarget +

+

+(Appears on: +ExtensionServiceSpec) +

+

+

ExtensionServiceTarget defines an Kubernetes Service to target with +extension service traffic.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+

Name is the name of Kubernetes service that will accept service +traffic.

+
+port +
+ +int + +
+

Port (defined as Integer) to proxy traffic to since a service can have multiple defined.

+
+weight +
+ +uint32 + +
+(Optional) +

Weight defines proportion of traffic to balance to the Kubernetes Service.

+
+

FeatureFlags +([]string alias)

+

+(Appears on: +ContourConfigurationSpec) +

+

+

FeatureFlags defines the set of feature flags +to toggle new contour features.

+

+

GatewayConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

GatewayConfig holds the config for Gateway API controllers.

+

+ + + + + + + + + + + + + +
FieldDescription
+gatewayRef +
+ + +NamespacedName + + +
+

GatewayRef defines the specific Gateway that this Contour +instance corresponds to.

+
+

HTTPProxyConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

HTTPProxyConfig defines parameters on HTTPProxy.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+disablePermitInsecure +
+ +bool + +
+(Optional) +

DisablePermitInsecure disables the use of the +permitInsecure field in HTTPProxy.

+

Contour’s default is false.

+
+rootNamespaces +
+ +[]string + +
+(Optional) +

Restrict Contour to searching these namespaces for root ingress routes.

+
+fallbackCertificate +
+ + +NamespacedName + + +
+(Optional) +

FallbackCertificate defines the namespace/name of the Kubernetes secret to +use as fallback when a non-SNI request is received.

+
+

HTTPVersionType +(string alias)

+

+(Appears on: +EnvoyConfig) +

+

+

HTTPVersionType is the name of a supported HTTP version.

+

+ + + + + + + + + + + + +
ValueDescription

"HTTP/1.1"

HTTPVersion1 is the name of the HTTP/1.1 version.

+

"HTTP/2"

HTTPVersion2 is the name of the HTTP/2 version.

+
+

HeadersPolicy +

+

+(Appears on: +PolicyConfig) +

+

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+set +
+ +map[string]string + +
+(Optional) +
+remove +
+ +[]string + +
+(Optional) +
+

HealthConfig +

+

+(Appears on: +ContourConfigurationSpec, +EnvoyConfig) +

+

+

HealthConfig defines the endpoints to enable health checks.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines the health address interface.

+
+port +
+ +int + +
+(Optional) +

Defines the health port.

+
+

IngressConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

IngressConfig defines ingress specific config items.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+classNames +
+ +[]string + +
+(Optional) +

Ingress Class Names Contour should use.

+
+statusAddress +
+ +string + +
+(Optional) +

Address to set in Ingress object status.

+
+

LogLevel +(string alias)

+

+(Appears on: +ContourSettings, +EnvoySettings) +

+

+

LogLevel is the logging levels available.

+

+ + + + + + + + + + + + + + + + + + + + + + +
ValueDescription

"critical"

CriticalLog sets the log level for Envoy to critical.

+

"debug"

DebugLog sets the log level for Contour/Envoy to debug.

+

"error"

ErrorLog sets the log level for Envoy to error.

+

"info"

InfoLog sets the log level for Contour/Envoy to info.

+

"off"

OffLog disable logging for Envoy.

+

"trace"

TraceLog sets the log level for Envoy to trace.

+

"warn"

WarnLog sets the log level for Envoy to warn.

+
+

MetricsConfig +

+

+(Appears on: +ContourConfigurationSpec, +EnvoyConfig) +

+

+

MetricsConfig defines the metrics endpoint.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+address +
+ +string + +
+(Optional) +

Defines the metrics address interface.

+
+port +
+ +int + +
+(Optional) +

Defines the metrics port.

+
+tls +
+ + +MetricsTLS + + +
+(Optional) +

TLS holds TLS file config details. +Metrics and health endpoints cannot have same port number when metrics is served over HTTPS.

+
+

MetricsTLS +

+

+(Appears on: +MetricsConfig) +

+

+

TLS holds TLS file config details.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caFile +
+ +string + +
+(Optional) +

CA filename.

+
+certFile +
+ +string + +
+(Optional) +

Client certificate filename.

+
+keyFile +
+ +string + +
+(Optional) +

Client key filename.

+
+

NamespacedName +

+

+(Appears on: +EnvoyConfig, +GatewayConfig, +HTTPProxyConfig, +RateLimitServiceConfig, +TracingConfig) +

+

+

NamespacedName defines the namespace/name of the Kubernetes resource referred from the config file. +Used for Contour config YAML file parsing, otherwise we could use K8s types.NamespacedName.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+name +
+ +string + +
+
+namespace +
+ +string + +
+
+

NetworkParameters +

+

+(Appears on: +EnvoyConfig) +

+

+

NetworkParameters hold various configurable network values.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+numTrustedHops +
+ +uint32 + +
+(Optional) +

XffNumTrustedHops defines the number of additional ingress proxy hops from the +right side of the x-forwarded-for HTTP header to trust when determining the origin +client’s IP address.

+

See https://www.envoyproxy.io/docs/envoy/v1.17.0/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto?highlight=xff_num_trusted_hops +for more information.

+

Contour’s default is 0.

+
+adminPort +
+ +int + +
+(Optional) +

Configure the port used to access the Envoy Admin interface. +If configured to port “0” then the admin interface is disabled.

+

Contour’s default is 9001.

+
+

NetworkPublishing +

+

+(Appears on: +EnvoySettings) +

+

+

NetworkPublishing defines the schema for publishing to a network.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+type +
+ + +NetworkPublishingType + + +
+(Optional) +

NetworkPublishingType is the type of publishing strategy to use. Valid values are:

+
    +
  • LoadBalancerService
  • +
+

In this configuration, network endpoints for Envoy use container networking. +A Kubernetes LoadBalancer Service is created to publish Envoy network +endpoints.

+

See: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer

+
    +
  • NodePortService
  • +
+

Publishes Envoy network endpoints using a Kubernetes NodePort Service.

+

In this configuration, Envoy network endpoints use container networking. A Kubernetes +NodePort Service is created to publish the network endpoints.

+

See: https://kubernetes.io/docs/concepts/services-networking/service/#nodeport

+

NOTE: +When provisioning an Envoy NodePortService, use Gateway Listeners’ port numbers to populate +the Service’s node port values, there’s no way to auto-allocate them.

+

See: https://github.com/projectcontour/contour/issues/4499

+
    +
  • ClusterIPService
  • +
+

Publishes Envoy network endpoints using a Kubernetes ClusterIP Service.

+

In this configuration, Envoy network endpoints use container networking. A Kubernetes +ClusterIP Service is created to publish the network endpoints.

+

See: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

+

If unset, defaults to LoadBalancerService.

+
+externalTrafficPolicy +
+ + +Kubernetes core/v1.ServiceExternalTrafficPolicy + + +
+(Optional) +

ExternalTrafficPolicy describes how nodes distribute service traffic they +receive on one of the Service’s “externally-facing” addresses (NodePorts, ExternalIPs, +and LoadBalancer IPs).

+

If unset, defaults to “Local”.

+
+ipFamilyPolicy +
+ + +Kubernetes core/v1.IPFamilyPolicy + + +
+(Optional) +

IPFamilyPolicy represents the dual-stack-ness requested or required by +this Service. If there is no value provided, then this field will be set +to SingleStack. Services can be “SingleStack” (a single IP family), +“PreferDualStack” (two IP families on dual-stack configured clusters or +a single IP family on single-stack clusters), or “RequireDualStack” +(two IP families on dual-stack configured clusters, otherwise fail).

+
+serviceAnnotations +
+ +map[string]string + +
+(Optional) +

ServiceAnnotations is the annotations to add to +the provisioned Envoy service.

+
+

NetworkPublishingType +(string alias)

+

+(Appears on: +NetworkPublishing) +

+

+

NetworkPublishingType is a way to publish network endpoints.

+

+ + + + + + + + + + + + + + +
ValueDescription

"ClusterIPService"

ClusterIPServicePublishingType publishes a network endpoint using a Kubernetes +ClusterIP Service.

+

"LoadBalancerService"

LoadBalancerServicePublishingType publishes a network endpoint using a Kubernetes +LoadBalancer Service.

+

"NodePortService"

NodePortServicePublishingType publishes a network endpoint using a Kubernetes +NodePort Service.

+
+

NodePlacement +

+

+(Appears on: +ContourSettings, +EnvoySettings) +

+

+

NodePlacement describes node scheduling configuration for pods. +If nodeSelector and tolerations are specified, the scheduler will use both to +determine where to place the pod(s).

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+nodeSelector +
+ +map[string]string + +
+(Optional) +

NodeSelector is the simplest recommended form of node selection constraint +and specifies a map of key-value pairs. For the pod to be eligible +to run on a node, the node must have each of the indicated key-value pairs +as labels (it can have additional labels as well).

+

If unset, the pod(s) will be scheduled to any available node.

+
+tolerations +
+ + +[]Kubernetes core/v1.Toleration + + +
+(Optional) +

Tolerations work with taints to ensure that pods are not scheduled +onto inappropriate nodes. One or more taints are applied to a node; this +marks that the node should not accept any pods that do not tolerate the +taints.

+

The default is an empty list.

+

See https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +for additional details.

+
+

PolicyConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

PolicyConfig holds default policy used if not explicitly set by the user

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+requestHeaders +
+ + +HeadersPolicy + + +
+(Optional) +

RequestHeadersPolicy defines the request headers set/removed on all routes

+
+responseHeaders +
+ + +HeadersPolicy + + +
+(Optional) +

ResponseHeadersPolicy defines the response headers set/removed on all routes

+
+applyToIngress +
+ +bool + +
+(Optional) +

ApplyToIngress determines if the Policies will apply to ingress objects

+

Contour’s default is false.

+
+

RateLimitServiceConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

RateLimitServiceConfig defines properties of a global Rate Limit Service.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+extensionService +
+ + +NamespacedName + + +
+

ExtensionService identifies the extension service defining the RLS.

+
+domain +
+ +string + +
+(Optional) +

Domain is passed to the Rate Limit Service.

+
+failOpen +
+ +bool + +
+(Optional) +

FailOpen defines whether to allow requests to proceed when the +Rate Limit Service fails to respond with a valid rate limit +decision within the timeout defined on the extension service.

+
+enableXRateLimitHeaders +
+ +bool + +
+(Optional) +

EnableXRateLimitHeaders defines whether to include the X-RateLimit +headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset +(as defined by the IETF Internet-Draft linked below), on responses +to clients when the Rate Limit Service is consulted for a request.

+

ref. https://tools.ietf.org/id/draft-polli-ratelimit-headers-03.html

+
+enableResourceExhaustedCode +
+ +bool + +
+(Optional) +

EnableResourceExhaustedCode enables translating error code 429 to +grpc code RESOURCE_EXHAUSTED. When disabled it’s translated to UNAVAILABLE

+
+defaultGlobalRateLimitPolicy +
+ + +GlobalRateLimitPolicy + + +
+(Optional) +

DefaultGlobalRateLimitPolicy allows setting a default global rate limit policy for every HTTPProxy. +HTTPProxy can overwrite this configuration.

+
+

ServerHeaderTransformationType +(string alias)

+

+(Appears on: +EnvoyListenerConfig) +

+

+

ServerHeaderTransformation defines the action to be applied to the Server header on the response path

+

+ + + + + + + + + + + + + + +
ValueDescription

"append_if_absent"

If no Server header is present, set it to “envoy”. +If a Server header is present, pass it through.

+

"overwrite"

Overwrite any Server header with “envoy”. +This is the default value.

+

"pass_through"

Pass through the value of the Server header, and do not append a header +if none is present.

+
+

SocketOptions +

+

+(Appears on: +EnvoyListenerConfig) +

+

+

SocketOptions defines configurable socket options for Envoy listeners.

+

+ + + + + + + + + + + + + + + + + +
FieldDescription
+tos +
+ +int32 + +
+(Optional) +

Defines the value for IPv4 TOS field (including 6 bit DSCP field) for IP packets originating from Envoy listeners. +Single value is applied to all listeners. +If listeners are bound to IPv6-only addresses, setting this option will cause an error.

+
+trafficClass +
+ +int32 + +
+(Optional) +

Defines the value for IPv6 Traffic Class field (including 6 bit DSCP field) for IP packets originating from the Envoy listeners. +Single value is applied to all listeners. +If listeners are bound to IPv4-only addresses, setting this option will cause an error.

+
+

TLS +

+

+(Appears on: +XDSServerConfig) +

+

+

TLS holds TLS file config details.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+caFile +
+ +string + +
+(Optional) +

CA filename.

+
+certFile +
+ +string + +
+(Optional) +

Client certificate filename.

+
+keyFile +
+ +string + +
+(Optional) +

Client key filename.

+
+insecure +
+ +bool + +
+(Optional) +

Allow serving the xDS gRPC API without TLS.

+
+

TimeoutParameters +

+

+(Appears on: +EnvoyConfig) +

+

+

TimeoutParameters holds various configurable proxy timeout values.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+requestTimeout +
+ +string + +
+(Optional) +

RequestTimeout sets the client request timeout globally for Contour. Note that +this is a timeout for the entire request, not an idle timeout. Omit or set to +“infinity” to disable the timeout entirely.

+

See 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-request-timeout +for more information.

+
+connectionIdleTimeout +
+ +string + +
+(Optional) +

ConnectionIdleTimeout defines how long the proxy should wait while there are +no active requests (for HTTP/1.1) or streams (for HTTP/2) before terminating +an HTTP connection. Set to “infinity” to disable the timeout entirely.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout +for more information.

+
+streamIdleTimeout +
+ +string + +
+(Optional) +

StreamIdleTimeout defines how long the proxy should wait while there is no +request activity (for HTTP/1.1) or stream activity (for HTTP/2) before +terminating the HTTP request or stream. Set to “infinity” to disable the +timeout entirely.

+

See 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-stream-idle-timeout +for more information.

+
+maxConnectionDuration +
+ +string + +
+(Optional) +

MaxConnectionDuration defines the maximum period of time after an HTTP connection +has been established from the client to the proxy before it is closed by the proxy, +regardless of whether there has been activity or not. Omit or set to “infinity” for +no max duration.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-max-connection-duration +for more information.

+
+delayedCloseTimeout +
+ +string + +
+(Optional) +

DelayedCloseTimeout defines how long envoy will wait, once connection +close processing has been initiated, for the downstream peer to close +the connection before Envoy closes the socket associated with the connection.

+

Setting this timeout to ‘infinity’ will disable it, equivalent to setting it to ‘0’ +in Envoy. Leaving it unset will result in the Envoy default value being used.

+

See 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-delayed-close-timeout +for more information.

+
+connectionShutdownGracePeriod +
+ +string + +
+(Optional) +

ConnectionShutdownGracePeriod defines how long the proxy will wait between sending an +initial GOAWAY frame and a second, final GOAWAY frame when terminating an HTTP/2 connection. +During this grace period, the proxy will continue to respond to new streams. After the final +GOAWAY frame has been sent, the proxy will refuse new streams.

+

See 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-drain-timeout +for more information.

+
+connectTimeout +
+ +string + +
+(Optional) +

ConnectTimeout defines how long the proxy should wait when establishing connection to upstream service. +If not set, a default value of 2 seconds will be used.

+

See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-connect-timeout +for more information.

+
+

TracingConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

TracingConfig defines properties for exporting trace data to OpenTelemetry.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+includePodDetail +
+ +bool + +
+(Optional) +

IncludePodDetail defines a flag. +If it is true, contour will add the pod name and namespace to the span of the trace. +the default is true. +Note: The Envoy pods MUST have the HOSTNAME and CONTOUR_NAMESPACE environment variables set for this to work properly.

+
+serviceName +
+ +string + +
+

ServiceName defines the name for the service. +contour’s default is contour.

+
+overallSampling +
+ +string + +
+(Optional) +

OverallSampling defines the sampling rate of trace data. +contour’s default is 100.

+
+maxPathTagLength +
+ +uint32 + +
+(Optional) +

MaxPathTagLength defines maximum length of the request path +to extract and include in the HttpUrl tag. +contour’s default is 256.

+
+customTags +
+ + +[]*github.com/projectcontour/contour/apis/projectcontour/v1alpha1.CustomTag + + +
+(Optional) +

CustomTags defines a list of custom tags with unique tag name.

+
+extensionService +
+ + +NamespacedName + + +
+

ExtensionService identifies the extension service defining the otel-collector.

+
+

WorkloadType +(string alias)

+

+(Appears on: +EnvoySettings) +

+

+

WorkloadType is the type of Kubernetes workload to use for a component.

+

+

XDSServerConfig +

+

+(Appears on: +ContourConfigurationSpec) +

+

+

XDSServerConfig holds the config for the Contour xDS server.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+type +
+ + +XDSServerType + + +
+(Optional) +

Defines the XDSServer to use for contour serve.

+

Values: envoy (default), contour (deprecated).

+

Other values will produce an error.

+

Deprecated: this field will be removed in a future release when +the contour xDS server implementation is removed.

+
+address +
+ +string + +
+(Optional) +

Defines the xDS gRPC API address which Contour will serve.

+

Contour’s default is “0.0.0.0”.

+
+port +
+ +int + +
+(Optional) +

Defines the xDS gRPC API port which Contour will serve.

+

Contour’s default is 8001.

+
+tls +
+ + +TLS + + +
+(Optional) +

TLS holds TLS file config details.

+

Contour’s default is { caFile: “/certs/ca.crt”, certFile: “/certs/tls.cert”, keyFile: “/certs/tls.key”, insecure: false }.

+
+

XDSServerType +(string alias)

+

+(Appears on: +XDSServerConfig) +

+

+

XDSServerType is the type of xDS server implementation.

+

+ + + + + + + + + + + + +
ValueDescription

"contour"

Use Contour’s xDS server (deprecated).

+

"envoy"

Use the upstream go-control-plane-based xDS server.

+
+
+

+Generated with gen-crd-api-reference-docs. +

diff --git a/site/content/docs/1.30/config/api.md b/site/content/docs/1.30/config/api.md new file mode 100644 index 00000000000..99809537d11 --- /dev/null +++ b/site/content/docs/1.30/config/api.md @@ -0,0 +1,3 @@ +# Contour API Reference + +{{% include-html api-reference.html %}} diff --git a/site/content/docs/1.30/config/client-authorization.md b/site/content/docs/1.30/config/client-authorization.md new file mode 100644 index 00000000000..4db2b932eff --- /dev/null +++ b/site/content/docs/1.30/config/client-authorization.md @@ -0,0 +1,123 @@ +# Client Authorization + +Contour supports integrating external servers to authorize client requests. + +Envoy implements external authorization in the [ext_authz][1] filter. +This filter intercepts client requests and holds them while it sends a check +request to an external server. +The filter uses the check result to either allow the request to proceed, or to +deny or redirect the request. + +The diagram below shows the sequence of requests involved in the successful +authorization of a HTTP request: + +

+client authorization sequence diagram +

+ +The [external authorization][7] guides demonstrates how to deploy HTTP basic +authentication using Contour and [contour-authserver](https://github.com/projectcontour/contour-authserver). + +## Extension Services + +The starting point for external authorization in Contour is the +[ExtensionService][2] API. +This API creates a cluster which Envoy can use to send requests to an external server. +In principle, the Envoy cluster can be used for any purpose, but in this +document we are concerned only with how to use it as an authorization service. + +An authorization service is a gRPC service that implements the Envoy [CheckRequest][3] protocol. +Note that Contour requires the extension to implement the "v3" version of the protocol. +Contour is compatible with any authorization server that implements this protocol. + +The primary field of interest in the `ExtensionService` CRD is the +`.spec.services` field. +This field lists the Kubernetes Services that will receive the check requests. +The `.spec.services[].name` field contains the name of the Service, which must +exist in the same namespace as the `ExtensionService` object. +The `ExtensionService` object must exist in the same namespace as the +Services they target to ensure that both objects are under the same +administrative control. + +### Load Balancing for Extension Services + +An `ExtensionService` can be configured to send traffic to multiple Kubernetes Services. +In this case, requests are divided proportionally across the Services according +to the weight in the `.spec.services[].weight` field. +The service weight can be used to flexibly shift traffic between Services for +reasons like implementing blue-green deployments. +The `.spec.loadBalancerPolicy` field configures how Envoy will load balance +requests to the endpoints within each Service. + +### TLS Validation for Extension Services + +Since authorizing a client request may involve passing sensitive credentials +from a HTTP request to the authorization service, the connection to the +authorization server should be as secure as possible. +Contour defaults the `.spec.protocol` field to "h2", which configures +Envoy to use HTTP/2 over TLS for the authorization service connection. + +The [.spec.validation][4] field configures how Envoy should verify the TLS +identity of the authorization server. +This is a critical protection against accidentally sending credentials to an +imposter service and should be enabled for all production deployments. +The `.spec.validation` field should specify the expected server name +from the authorization server's TLS certificate, and the trusted CA bundle +that can be used to validate the TLS chain of trust. + +## Authorizing Virtual Hosts + +The [.spec.virtualhost.authorization][5] field in the Contour `HTTPProxy` +API connects a virtual host to an authorization server that is bound by an +`ExtensionService` object. +Each virtual host can use a different `ExtensionService`, but only one +`ExtensionService` can be used by a single virtual host. +Authorization servers can only be attached to `HTTPProxy` objects that have TLS +termination enabled. + +### Migrating from Application Authorization + +When applications perform their own authorization, migrating to centralized +authorization may need some planning. +The `.spec.virtualhost.authorization.failOpen` field controls how client +requests should be handled when the authorization server fails. +During a migration process, this can be set to `true`, so that if the +authorization server becomes unavailable, clients can gracefully fall back to +the existing application authorization mechanism. + +### Scoping Authorization Policy Settings + +It is common for services to contain some HTTP request paths that require +authorization and some that do not. +The HTTPProxy [authorization policy][6] allows authorization to be +disabled for both an entire virtual host and for specific routes. + +The initial authorization policy is set on the HTTPProxy virtual host +in the `.spec.virtualhost.authorization.authPolicy` field. +This configures whether authorization is enabled, and the default authorization policy context. +If authorization is disabled on the virtual host, it is also disabled by +default on all the routes for that virtual host that do not specify an authorization policy. +However, a route can configure its own authorization policy (in the +`.spec.routes[].authPolicy` field) that can configure whether authorization +is enabled, irrespective of the virtual host setting. + +The authorization policy context is a way to configure a set of key/value +pairs that will be sent to the authorization server with each request check +request. +The keys and values that should be specified here depend on which authorization +server has been configured. +This facility is intended for configuring authorization-specific information, such as +the basic authentication realm, or OIDC parameters. + +The initial context map can be set on the virtual host. +This sets the context keys that will be sent on every check request. +A route can overwrite the value for a context key by setting it in the +context field of authorization policy for the route. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter +[2]: api/#projectcontour.io/v1alpha1.ExtensionService +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto +[4]: api/#projectcontour.io/v1.UpstreamValidation +[5]: api/#projectcontour.io/v1.AuthorizationServer +[6]: api/#projectcontour.io/v1.AuthorizationPolicy +[7]: guides/external-authorization.md diff --git a/site/content/docs/1.30/config/cookie-rewriting.md b/site/content/docs/1.30/config/cookie-rewriting.md new file mode 100644 index 00000000000..480fc34125c --- /dev/null +++ b/site/content/docs/1.30/config/cookie-rewriting.md @@ -0,0 +1,109 @@ +# Cookie Rewriting + +Contour now enables users to customize attributes on HTTP `Set-Cookie` response headers. +Application specific cookies and cookies generated by Contour's ["cookie" load balancing strategy](https://projectcontour.io/docs/v1.19.0/config/request-routing/#session-affinity) can be rewritten either per HTTPProxy `Route` or `Service`. +Users can choose to rewrite the `Path`, `Domain`, `Secure`, and `SameSite` attributes of the `Set-Cookie` header currently. +These attributes may be things an application may not be able to accurately set, without prior knowledge of how the application is deployed. +For example, if Contour is in use to rewrite the path or hostname of a request before it reaches an application backend, the application may not be able to accurately set the `Path` and `Domain` attributes in a `Set-Cookie` response header. +This feature can be used to apply security settings to ensure browsers treat generated cookies appropriately. +The `SameSite` and `Secure` attributes are currently not set by Envoy when it generates the `X-Contour-Session-Affinity`, but with this feature, users can customize this cookie further. + +## Per-Route Cookie Rewriting + +In order to implement separate cookie rewriting policies per-route, we can configure an HTTPProxy as below: + +```yaml +# cookie-rewrite-route.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cookie-rewrite-route +spec: + virtualhost: + fqdn: cookie-rewrite-route.com + routes: + - conditions: + - prefix: /admin + services: + - name: admin-app + port: 80 + cookieRewritePolicies: + - name: X-Admin-Session + pathRewrite: + value: /admin + - conditions: + - prefix: /payments + services: + - name: payment-app + port: 80 + cookieRewritePolicies: + - name: X-User-Session + pathRewrite: + value: /payments + sameSite: Lax + - name: X-User-Data + sameSite: Lax +``` + +This HTTPProxy allows us to rewrite the `Path` attribute of the `X-Admin-Session` cookie on the `/admin` route. +In addition on the `/payments` route we rewrite the `Path` and `SameSite` attributes of the `X-User-Session` cookie and the `SameSite` attribute of the additional `X-User-Data` cookie. +If the backing services `payment-app` and `admin-app` return the specified cookies in `Set-Cookie` response headers, they will be rewritten with the values specified above. + +## Per-Service Cookie Rewriting + +Similar to the above, if we have more than one `Service` configured per `Route` but want to customize cookies separately between them we can: + +```yaml +# cookie-rewrite-service.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cookie-rewrite-service +spec: + virtualhost: + fqdn: cookie-rewrite-service.com + routes: + - conditions: + - prefix: / + services: + - name: backend-1 + port: 80 + cookieRewritePolicies: + - name: X-User-Data-1 + domainRewrite: + value: cookie-rewrite-service.com + - name: backend-2 + port: 80 + cookieRewritePolicies: + - name: X-User-Data-2 + domainRewrite: + value: cookie-rewrite-service.com +``` + +## Rewriting Contour Session Affinity Cookie + +As mentioned above, users can use Contour's cookie load balancing strategy to enable session affinity. +Envoy generates a pretty bare-bones cookie but Contour's cookie rewriting feature can be used to customize this cookie to add security attributes: + +```yaml +# cookie-rewrite-session-affinity.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cookie-rewrite-session-affinity +spec: + virtualhost: + fqdn: cookie-rewrite-session-affinity.com + routes: + - conditions: + - prefix: / + services: + - name: backend + port: 80 + loadBalancerPolicy: + strategy: Cookie + cookieRewritePolicies: + - name: X-Contour-Session-Affinity + sameSite: Strict + secure: true +``` diff --git a/site/content/docs/1.30/config/cors.md b/site/content/docs/1.30/config/cors.md new file mode 100644 index 00000000000..8f468aeaec7 --- /dev/null +++ b/site/content/docs/1.30/config/cors.md @@ -0,0 +1,82 @@ +# CORS + +A CORS (Cross-origin resource sharing) policy can be set for a HTTPProxy in order to allow cross-domain requests for trusted sources. +If a policy is set, it will be applied to all the routes of the virtual host. + +Contour allows configuring the headers involved in responses to cross-domain requests. +These include the `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers`, `Access-Control-Expose-Headers`, `Access-Control-Max-Age`, `Access-Control-Allow-Private-Network` and `Access-Control-Allow-Credentials` headers in responses. + +In this example, cross-domain requests will be allowed for any domain (note the `*` value), with the methods `GET`, `POST`, or `OPTIONS`. +Headers `Authorization` and `Cache-Control` will be passed to the upstream server and headers `Content-Length` and `Content-Range` will be made available to the cross-origin request client. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cors-example +spec: + virtualhost: + fqdn: www.example.com + corsPolicy: + allowCredentials: true + allowPrivateNetwork: true + allowOrigin: + - "*" # allows any origin + allowMethods: + - GET + - POST + - OPTIONS + allowHeaders: + - authorization + - cache-control + exposeHeaders: + - Content-Length + - Content-Range + maxAge: "10m" # preflight requests can be cached for 10 minutes. + routes: + - conditions: + - prefix: / + services: + - name: cors-example + port: 80 +``` + +The `allowOrigin` list may also be configured with exact origin matches or regex patterns. +In the following example, cross-domain requests must originate from the domain `https://client.example.com` or domains that match the regex `http[s]?:\/\/some-site-[a-z0-9]+\.example\.com` (e.g. request with `Origin` header `https://some-site-abc456.example.com`) + +*Note:* Patterns for matching `Origin` headers must be valid regex, simple "globbing" patterns (e.g. `*.foo.com`) will not be accepted or may produce incorrect matches. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: cors-example +spec: + virtualhost: + fqdn: www.example.com + corsPolicy: + allowCredentials: true + allowOrigin: + - https://client.example.com + - http[s]?:\/\/some-site-[a-z0-9]+\.example\.com + allowMethods: + - GET + - POST + - OPTIONS + allowHeaders: + - authorization + - cache-control + exposeHeaders: + - Content-Length + - Content-Range + maxAge: "10m" + routes: + - conditions: + - prefix: / + services: + - name: cors-example + port: 80 +``` + +`MaxAge` durations are expressed in the Go [duration format](https://godoc.org/time#ParseDuration). +Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Only positive values are allowed and 0 disables the cache requiring a preflight `OPTIONS` check for all cross-origin requests. diff --git a/site/content/docs/1.30/config/external-service-routing.md b/site/content/docs/1.30/config/external-service-routing.md new file mode 100644 index 00000000000..7da431dd06b --- /dev/null +++ b/site/content/docs/1.30/config/external-service-routing.md @@ -0,0 +1,47 @@ +# External Service Routing + +HTTPProxy supports routing traffic to `ExternalName` service types, but this is disabled by default, as it can lead +to inadvertent exposure of the Envoy Admin UI, allowing remote shutdown and restart of Envoy. +Please see [this security advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for all the details. +It can also be used to expose services in namespaces a user does not have access to, using an ExternalName of `service.namespace.svc.cluster.local`. +Please see [this Kubernetes security advisory](https://github.com/kubernetes/kubernetes/issues/103675) for more details. + +We do *not* recommend enabling ExternalName Services without a strong use case, and understanding of the security implications. + +However, To enable ExternalName processing, you must set the `enableExternalNameService` configuration file setting to `true`. +This will allow the following configuration to be valid. + +## ExternalName Support + +Contour looks at the `spec.externalName` field of the service and configures the route to use that DNS name instead of utilizing EDS. + +Note that hostnames of `localhost` or some other synonyms will be rejected (because of the aforementioned security issues). + +There's nothing specific in the HTTPProxy object that needs to be configured other than referencing a service of type `ExternalName`. +HTTPProxy supports the `requestHeadersPolicy` field to rewrite the `Host` header after first handling a request and before proxying to an upstream service. +This field can be used to ensure that the forwarded HTTP request contains the hostname that the external resource is expecting. + +_**Note:** The ports are required to be specified._ + +```yaml +# httpproxy-externalname.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + run: externaldns + name: externaldns + namespace: default +spec: + externalName: foo-basic.bar.com + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 80 + type: ExternalName +``` + +To proxy to another resource outside the cluster (e.g. A hosted object store bucket for example), configure that external resource in a service type `externalName`. +Then define a `requestHeadersPolicy` which replaces the `Host` header with the value of the external name service defined previously. +Finally, if the upstream service is served over TLS, set the `protocol` field on the service to `tls` or annotate the external name service with: `projectcontour.io/upstream-protocol.tls: 443,https`, assuming your service had a port 443 and name `https`. diff --git a/site/content/docs/1.30/config/fundamentals.md b/site/content/docs/1.30/config/fundamentals.md new file mode 100644 index 00000000000..0bdac65f77f --- /dev/null +++ b/site/content/docs/1.30/config/fundamentals.md @@ -0,0 +1,197 @@ +# HTTPProxy Fundamentals + +The [Ingress][1] object was added to Kubernetes in version 1.1 to describe properties of a cluster-wide reverse HTTP proxy. +Since that time, the Ingress API has remained relatively unchanged, and the need to express implementation-specific capabilities has inspired an [explosion of annotations][2]. + +The goal of the HTTPProxy Custom Resource Definition (CRD) is to expand upon the functionality of the Ingress API to allow for a richer user experience as well addressing the limitations of the latter's use in multi tenant environments. + +## Key HTTPProxy Benefits + +- Safely supports multi-team Kubernetes clusters, with the ability to limit which Namespaces may configure virtual hosts and TLS credentials. +- Enables including of routing configuration for a path or domain from another HTTPProxy, possibly in another Namespace. +- Accepts multiple services within a single route and load balances traffic across them. +- Natively allows defining service weighting and load balancing strategy without annotations. +- Validation of HTTPProxy objects at creation time and status reporting for post-creation validity. + +## Ingress to HTTPProxy + +A minimal Ingress object might look like: + +```yaml +# ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: basic +spec: + rules: + - host: foo-basic.bar.com + http: + paths: + - backend: + service: + name: s1 + port: + number: 80 + pathType: Prefix +``` + +This Ingress object, named `basic`, will route incoming HTTP traffic with a `Host:` header for `foo-basic.bar.com` to a Service named `s1` on port `80`. +Implementing similar behavior using an HTTPProxy looks like this: + +```yaml +# httpproxy.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: basic +spec: + virtualhost: + fqdn: foo-basic.bar.com + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +``` + +**Lines 1-5**: As with all other Kubernetes objects, an HTTPProxy needs apiVersion, kind, and metadata fields. + +**Lines 7-8**: The presence of the `virtualhost` field indicates that this is a root HTTPProxy that is the top level entry point for this domain. + + +## Interacting with HTTPProxies + +As with all Kubernetes objects, you can use `kubectl` to create, list, describe, edit, and delete HTTPProxy CRDs. + +Creating an HTTPProxy: + +```bash +$ kubectl create -f basic.httpproxy.yaml +httpproxy "basic" created +``` + +Listing HTTPProxies: + +```bash +$ kubectl get httpproxy +NAME AGE +basic 24s +``` + +Describing HTTPProxy: + +```bash +$ kubectl describe httpproxy basic +Name: basic +Namespace: default +Labels: +API Version: projectcontour.io/v1 +Kind: HTTPProxy +Metadata: + Cluster Name: + Creation Timestamp: 2019-07-05T19:26:54Z + Resource Version: 19373717 + Self Link: /apis/projectcontour.io/v1/namespaces/default/httpproxy/basic + UID: 6036a9d7-8089-11e8-ab00-f80f4182762e +Spec: + Routes: + Conditions: + Prefix: / + Services: + Name: s1 + Port: 80 + Virtualhost: + Fqdn: foo-basic.bar.com +Events: +``` + +Deleting HTTPProxies: + +```bash +$ kubectl delete httpproxy basic +httpproxy "basic" deleted +``` + +## Status Reporting + +There are many misconfigurations that could cause an HTTPProxy or delegation to be invalid. +Contour will make its best effort to process even partially valid configuration and allow traffic to be served for the valid parts. +To aid users in resolving any issues, Contour updates a `status` field in all HTTPProxy objects. + +If an HTTPProxy object is valid, it will have a status property that looks like this: + +```yaml +status: + currentStatus: valid + description: valid HTTPProxy +``` + +If the HTTPProxy is invalid, the `currentStatus` field will be `invalid` and the `description` field will provide a description of the issue. + +As an example, if an HTTPProxy object has specified a negative value for weighting, the HTTPProxy status will be: + +```yaml +status: + currentStatus: invalid + description: "route '/foo': service 'home': weight must be greater than or equal to zero" +``` + +Some examples of invalid configurations that Contour provides statuses for: + +- Negative weight provided in the route definition. +- Invalid port number provided for service. +- Prefix in parent does not match route in delegated route. +- Root HTTPProxy created in a namespace other than the allowed root namespaces. +- A given Route of an HTTPProxy both delegates to another HTTPProxy and has a list of services. +- Orphaned route. +- Delegation chain produces a cycle. +- Root HTTPProxy does not specify fqdn. +- Multiple prefixes cannot be specified on the same set of route conditions. +- Multiple header conditions of type "exact match" with the same header key. +- Contradictory header conditions on a route, e.g. a "contains" and "notcontains" condition for the same header and value. + +Invalid configuration is ignored and will be not used in the ingress routing configuration. +Envoy will respond with an error when HTTP request is received on route with invalid configuration on following cases: + +* `502 Bad Gateway` response is sent when HTTPProxy has an include that refers to an HTTPProxy that does not exist. +* `503 Service Unavailable` response is sent when HTTPProxy refers to a service that does not exist. + +### Example + +Following example has two routes: the first one is valid, the second one refers to a service that does not exist. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-routes-with-a-missing-service +spec: + virtualhost: + fqdn: www.example.com + routes: + - conditions: + - prefix: / + services: + - name: valid-service + port: 80 + - conditions: + - prefix: /subpage + services: + - name: service-that-does-not-exist + port: 80 +``` + +The `HTTPProxy` will have condition `Valid=false` with detailed error message: `Spec.Routes unresolved service reference: service "default/service-that-does-not-exist" not found`. +Requests received for `http://www.example.com/` will be forwarded to `valid-service` but requests received for `http://www.example.com/subpage` will result in error `503 Service Unavailable` response from Envoy. + +## HTTPProxy API Specification + +The full HTTPProxy specification is described in detail in the [API documentation][4]. +There are a number of working examples of HTTPProxy objects in the [`examples/example-workload`][3] directory of the Contour Github repository. + + [1]: https://kubernetes.io/docs/concepts/services-networking/ingress/ + [2]: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md + [3]: {{< param github_url>}}/tree/{{< param branch >}}/examples/example-workload/httpproxy + [4]: api.md diff --git a/site/content/docs/1.30/config/gateway-api.md b/site/content/docs/1.30/config/gateway-api.md new file mode 100644 index 00000000000..c38c2b49c04 --- /dev/null +++ b/site/content/docs/1.30/config/gateway-api.md @@ -0,0 +1,218 @@ +# Gateway API + +## Introduction + +[Gateway API][1] is an open source project managed by the SIG Network community. +It is a collection of resources that model service networking in Kubernetes. +These resources - GatewayClass, Gateway, HTTPRoute, TCPRoute, Service, etc - aim to evolve Kubernetes service networking through expressive, extensible, and role-oriented interfaces that are implemented by many vendors and have broad industry support. + +Contour implements Gateway API in addition to supporting HTTPProxy and Ingress. +In particular, Contour aims to support all [core and extended features][2] in Gateway API. + +Gateway API has a comprehensive [website and docs][1], so this document focuses primarily on unique aspects of Contour's Gateway API implementation, rather than attempting to reproduce all of the content available on the Gateway API website. +The reader is suggested to familiarize themselves with the basics of Gateway API before continuing with this doc. + +In Contour's Gateway API implementation, a Gateway corresponds 1:1 with a single deployment of Contour + Envoy. +In other words, each Gateway has its own control plane (Contour) and data plane (Envoy). + +The remainder of this document delves into more detail regarding configuration options when using Contour with Gateway API. +If you are looking for a way to get started with Gateway API and Contour, see the [Gateway API guide][12], a step-by-step tutorial on getting Contour installed with Gateway API and using it to route traffic to a service. + +## Enabling Gateway API in Contour + +There are two ways to deploy Contour with Gateway API support: **static** provisioning and **dynamic** provisioning. + +In **static** provisioning, the platform operator defines a `Gateway` resource, and then manually deploys a Contour instance corresponding to that `Gateway` resource. +It is up to the platform operator to ensure that all configuration matches between the `Gateway` and the Contour/Envoy resources. +Contour will then process that `Gateway` and its routes. + +In **dynamic** provisioning, the platform operator first deploys Contour's Gateway provisioner. Then, the platform operator defines a `Gateway` resource, and the provisioner automatically deploys a Contour instance that corresponds to the `Gateway's` configuration and will process that `Gateway` and its routes. + +Static provisioning makes sense for users who: +- prefer the traditional model of deploying Contour +- have only a single Gateway +- want to use just the standard listener ports (80/443) +- have highly customized YAML for deploying Contour. + +Dynamic provisioning makes sense for users who: +- have many Gateways +- want to use additional listener ports +- prefer a simple declarative API for provisioning Contour instances +- want a fully conformant Gateway API implementation + +### Static Provisioning + +To statically provision Contour with Gateway API enabled: + +1. Install the [Gateway API experimental channel][3]. +1. Create a GatewayClass, with a controller name of `projectcontour.io/gateway-controller`. +1. Create a Gateway using the above GatewayClass. +1. In the Contour config file, add a reference to the above Gateway via `gateway.gatewayRef` (see https://projectcontour.io/docs/1.25/configuration/#gateway-configuration) +1. Install Contour using the above config file. + +Contour provides an example manifest for this at https://projectcontour.io/quickstart/contour-gateway.yaml. + +### Dynamic Provisioning + +To dynamically provision Contour with Gateway API enabled: + +1. Install the [Contour Gateway Provisioner][9], which includes the Gateway API experimental channel. +1. Create a GatewayClass, with a controller name of `projectcontour.io/gateway-controller`. +1. Create a Gateway using the above GatewayClass. + +The Contour Gateway Provisioner will deploy an instance of Contour in the Gateway's namespace implementing the Gateway spec. + +**Note:** Gateway names must be 63 characters or shorter, to avoid issues when generating dependent resources. See [projectcontour/contour#5970][13] and [kubernetes-sigs/gateway-api#2592][14] for more information. + +## Gateway Listeners + +Each unique Gateway Listener port requires the Envoy service to expose that port, and to map it to an underlying port in the Envoy daemonset/deployment that Envoy is configured to listen on. +For example, the following Gateway Listener configuration (abridged) requires service ports of 80 and 443, mapped to underlying container ports 8080 and 8443: + +```yaml +listeners: +- name: http + protocol: HTTP + port: 80 +- name: https + protocol: HTTPS + port: 443 +``` + +In dynamic provisioning, the Contour Gateway Provisioner will continuously ensure that the Envoy service and daemonset/deployment are kept in sync with the Gateway Listener configuration. +In static provisioning, it is up to the platform operator to keep the Envoy resources in sync with the Gateway Listeners. + +To get from the Gateway Listener port to the port that Envoy will be configured to listen on, i.e. the container port: +- add 8000 to the Listener port number +- if the result is greater than 65535, subtract 65535 +- if the result is less than or equal to 1023, add 1023. + +Note that, in rare corner cases, it's possible to have port conflicts. +Check the Gateway status to ensure that Listeners have been properly provisioned. + +## Routing + +Gateway API defines multiple route types. +Each route type is appropriate for a different type of traffic being proxied to a backend service. +Contour implements `HTTPRoute`, `TLSRoute`, `GRPCRoute` and `TCPRoute`. +The details of each of these route types are covered in extensive detail on the Gateway API website; the [route resources overview][11] is a good place to start learning about them. + +### Routing with HTTPProxy or Ingress + +When Gateway API is enabled in Contour, it's still possible to use HTTPProxy or Ingress to define routes, with some limitations. +This is useful for users who: +- are in the process of migrating to Gateway API +- want to use the Contour Gateway Provisioner for dynamic provisioning, but need the advanced features of HTTPProxy + +To use HTTPProxy or Ingress with Gateway API, define a Gateway with the following Listeners: + +```yaml +listeners: +- name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +- name: https + protocol: projectcontour.io/https + port: 443 + allowedRoutes: + namespaces: + from: All +``` + +Note that for the second Listener, a Contour-specific protocol is used, and no TLS details are specified. +Instead, TLS details continue to be configured on the HTTPProxy or Ingress resource. + +This is an area of active development and further work will be done in upcoming releases to better support migrations and mixed modes of operation. + +## Contour Gateway Provisioner + +### Customizing a GatewayClass + +Gateway API [supports attaching parameters to a GatewayClass][5], which can customize the Gateways that are provisioned for that GatewayClass. + +Contour defines a CRD called `ContourDeployment`, which can be used as `GatewayClass` parameters. + +A simple example of a parameterized Contour GatewayClass that provisions Envoy as a Deployment instead of the default DaemonSet looks like: + +```yaml +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: contour-with-envoy-deployment +spec: + controllerName: projectcontour.io/gateway-controller + parametersRef: + kind: ContourDeployment + group: projectcontour.io + name: contour-with-envoy-deployment-params + namespace: projectcontour +--- +kind: ContourDeployment +apiVersion: projectcontour.io/v1alpha1 +metadata: + namespace: projectcontour + name: contour-with-envoy-deployment-params +spec: + envoy: + workloadType: Deployment +``` + +All Gateways provisioned using the `contour-with-envoy-deployment` GatewayClass would get an Envoy Deployment. + +See [the API documentation][6] for all `ContourDeployment` options. + +It's important to note that, per the [GatewayClass spec][10]: + +> It is recommended that [GatewayClass] 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 propagated down to existing Gateways. +> This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. +> If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. + +Contour follows the recommended behavior, meaning changes to a GatewayClass and its parameters are not propagated down to existing Gateways. + +### Upgrades + +When the Contour Gateway Provisioner is upgraded to a new version, it will upgrade all Gateways it controls (both the control plane and the data plane). + +## Disabling Experimental Resources + +Some users may want to use Contour with the [Gateway API standard channel][4] instead of the experimental channel, to avoid installing alpha resources into their clusters. +To do this, Contour must be told to disable informers for the experimental resources. +In the Contour (control plane) deployment, use the `--disable-feature` flag for `contour serve` to disable informers for the experimental resources: + +```yaml +containers: +- name: contour + image: ghcr.io/projectcontour/contour: + command: ["contour"] + args: + - serve + - --incluster + - --xds-address=0.0.0.0 + - --xds-port=8001 + - --contour-cafile=/certs/ca.crt + - --contour-cert-file=/certs/tls.crt + - --contour-key-file=/certs/tls.key + - --config-path=/config/contour.yaml + - --disable-feature=tlsroutes + - --disable-feature=tcproutes + ... +``` + +[1]: https://gateway-api.sigs.k8s.io/ +[2]: https://gateway-api.sigs.k8s.io/concepts/conformance/#2-support-levels +[3]: https://gateway-api.sigs.k8s.io/guides/#install-experimental-channel +[4]: https://gateway-api.sigs.k8s.io/guides/#install-standard-channel +[5]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/#gatewayclass-parameters +[6]: https://projectcontour.io/docs/main/config/api/#projectcontour.io/v1alpha1.ContourDeployment +[7]: https://projectcontour.io/docs/main/config/api/#projectcontour.io/v1alpha1.GatewayConfig +[8]: https://gateway-api.sigs.k8s.io/api-types/gatewayclass/#gatewayclass-controller-selection +[9]: https://projectcontour.io/quickstart/contour-gateway-provisioner.yaml +[10]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.GatewayClass +[11]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#route-resources +[12]: /docs/{{< param version >}}/guides/gateway-api +[13]: https://github.com/projectcontour/contour/issues/5970 +[14]: https://github.com/kubernetes-sigs/gateway-api/issues/2592 \ No newline at end of file diff --git a/site/content/docs/1.30/config/health-checks.md b/site/content/docs/1.30/config/health-checks.md new file mode 100644 index 00000000000..6dd1aac619d --- /dev/null +++ b/site/content/docs/1.30/config/health-checks.md @@ -0,0 +1,160 @@ +# Upstream Health Checks + +## HTTP Proxy Health Checking + +Active health checking can be configured on a per route basis. +Contour supports HTTP health checking and can be configured with various settings to tune the behavior. + +During HTTP health checking Envoy will send an HTTP request to the upstream Endpoints. +It expects a 200 response by default if the host is healthy (see `expectedStatuses` below for configuring the "healthy" status codes). +The upstream host can return 503 if it wants to immediately notify Envoy to no longer forward traffic to it. +It is important to note that these are health checks which Envoy implements and are separate from any other system such as those that exist in Kubernetes. + +```yaml +# httpproxy-health-checks.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + routes: + - conditions: + - prefix: / + healthCheckPolicy: + path: /healthy + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + services: + - name: s1-health + port: 80 + - name: s2-health + port: 80 +``` + +Health check configuration parameters: + +- `path`: HTTP endpoint used to perform health checks on upstream service (e.g. `/healthz`). It expects a 200 response if the host is healthy. The upstream host can return 503 if it wants to immediately notify downstream hosts to no longer forward traffic to it. +- `host`: The value of the host header in the HTTP health check request. If left empty (default value), the name "contour-envoy-healthcheck" will be used. +- `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set. +- `timeoutSeconds`: The time to wait (seconds) for a health check response. If the timeout is reached the health check attempt will be considered a failure. Defaults to 2 seconds if not set. +- `unhealthyThresholdCount`: The number of unhealthy health checks required before a host is marked unhealthy. Note that for http health checking if a host responds with 503 this threshold is ignored and the host is considered unhealthy immediately. Defaults to 3 if not defined. +- `healthyThresholdCount`: The number of healthy health checks required before a host is marked healthy. Note that during startup, only a single successful health check is required to mark a host healthy. +- `expectedStatuses`: An optional list of HTTP status ranges that are considered healthy. Ranges follow half-open semantics, meaning the start is inclusive and the end is exclusive. Statuses must be between 100 (inclusive) and 600 (exclusive). + +### Non-default expected statuses + +By default, only responses with a 200 status code will be considered healthy. +The set of response codes considered healthy can be customized by specifying ranges in `expectedStatuses`. +Ranges follow half-open semantics, meaning the start is inclusive and the end is exclusive. +Statuses must be between 100 (inclusive) and 600 (exclusive). +For example: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + routes: + - conditions: + - prefix: / + healthCheckPolicy: + path: /healthy + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + # Status codes 200 and 250-299 will be considered healthy. + expectedStatuses: + - start: 200 + end: 201 + - start: 250 + end: 300 + services: + - name: s1-health + port: 80 + - name: s2-health + port: 80 +``` + +Note that if `expectedStatuses` is specified, `200` must be explicitly included in one of the specified ranges if it is desired as a healthy status code. + +## TCP Proxy Health Checking + +Contour also supports TCP health checking and can be configured with various settings to tune the behavior. + +During TCP health checking Envoy will send a connect-only health check to the upstream Endpoints. +It is important to note that these are health checks which Envoy implements and are separate from any +other system such as those that exist in Kubernetes. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: tcp-health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + tcpproxy: + healthCheckPolicy: + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + services: + - name: s1-health + port: 80 + - name: s2-health + port: 80 +``` + +TCP Health check policy configuration parameters: + +- `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set. +- `timeoutSeconds`: The time to wait (seconds) for a health check response. If the timeout is reached the health check attempt will be considered a failure. Defaults to 2 seconds if not set. +- `unhealthyThresholdCount`: The number of unhealthy health checks required before a host is marked unhealthy. Note that for http health checking if a host responds with 503 this threshold is ignored and the host is considered unhealthy immediately. Defaults to 3 if not defined. +- `healthyThresholdCount`: The number of healthy health checks required before a host is marked healthy. Note that during startup, only a single successful health check is required to mark a host healthy. + +## Specify the service health check port + +contour supports configuring an optional health check port for services. + +By default, the service's health check port is the same as the service's routing port. +If the service's health check port and routing port are different, you can configure the health check port separately. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: health-check + namespace: default +spec: + virtualhost: + fqdn: health.bar.com + routes: + - conditions: + - prefix: / + healthCheckPolicy: + path: /healthy + intervalSeconds: 5 + timeoutSeconds: 2 + unhealthyThresholdCount: 3 + healthyThresholdCount: 5 + services: + - name: s1-health + port: 80 + healthPort: 8998 + - name: s2-health + port: 80 +``` + +In this example, envoy will send a health check request to port `8998` of the `s1-health` service and port `80` of the `s2-health` service respectively . If the host is healthy, envoy will forward traffic to the `s1-health` service on port `80` and to the `s2-health` service on port `80`. diff --git a/site/content/docs/1.30/config/inclusion-delegation.md b/site/content/docs/1.30/config/inclusion-delegation.md new file mode 100644 index 00000000000..b9364ff1fcd --- /dev/null +++ b/site/content/docs/1.30/config/inclusion-delegation.md @@ -0,0 +1,139 @@ +# HTTPProxy Inclusion + +HTTPProxy permits the splitting of a system's configuration into separate HTTPProxy instances using **inclusion**. + +Inclusion, as the name implies, allows for one HTTPProxy object to be included in another, optionally with some conditions inherited from the parent. +Contour reads the inclusion tree and merges the included routes into one big object internally before rendering Envoy config. +Importantly, the included HTTPProxy objects do not have to be in the same namespace. + +Each tree of HTTPProxy starts with a root, the top level object of the configuration for a particular virtual host. +Each root HTTPProxy defines a `virtualhost` key, which describes properties such as the fully qualified name of the virtual host, TLS configuration, etc. + +HTTPProxies included from the root must not contain a virtualhost key. +Root objects cannot include other roots either transitively or directly. +This permits the owner of an HTTPProxy root to allow the inclusion of a portion of the route space inside a virtual host, and to allow that route space to be further subdivided with inclusions. +Because the path is not necessarily used as the only key, the route space can be multi-dimensional. + +## Conditions and Inclusion + +Like Routes, Inclusion may specify a set of [conditions][1]. +These conditions are added to any conditions on the routes included. +This process is recursive. + +Conditions are sets of individual condition statements, for example `prefix: /blog` is the condition that the matching request's path must start with `/blog`. +When conditions are combined through inclusion Contour merges the conditions inherited via inclusion with any conditions specified on the route. +This may result in duplicates, for example two `prefix:` conditions, mix of both `prefix:` and `exact` or `prefix` and `regex` conditions, or two header match conditions with the same name and value. +To resolve this Contour applies the following logic. + +- `prefix:` conditions are concatenated together in the order they were applied from the root object. For example the conditions, `prefix: /api`, `prefix: /v1` becomes a single `prefix: /api/v1` conditions. Note: Multiple prefixes cannot be supplied on a single set of Route conditions. +- `exact:` conditions are also concatenated just like `prefix:` conditions, but `exact:` conditions are not allowed in include match conditions. If the child httpproxy has `exact:` condition then after concatenation, it becomes a single `exact:` condition. For example, `prefix: /static` and `exact: /main.js` become a single `exact: /static/main.js` condition. +- `regex:` conditions are also concatenated just like `prefix:` conditions, but `regex:` conditions are not allowed in include match conditions. If the child httpproxy has `regex:` condition then after concatenation, it becomes a single `regex:` condition. For example, `prefix: /static` and `regex: /.*/main.js` become a single `regex: /static/.*/main.js` condition. +- Proxies with repeated identical `header:` conditions of type "exact match" (the same header keys exactly) are marked as "Invalid" since they create an un-routable configuration. + +## Configuring Inclusion + +Inclusion is a top-level field in the HTTPProxy [spec][2] element. +It requires one field, `name`, and has two optional fields: + +- `namespace`. This will assume the included HTTPProxy is in the same namespace if it's not specified. +- a `conditions` block. + +## Inclusion Within the Same Namespace + +HTTPProxies can include other HTTPProxy objects in the namespace by specifying the name of the object and its namespace in the top-level `includes` block. +Note that `includes` is a list, and so it must use the YAML list construct. + +In this example, the HTTPProxy `include-root` has included the configuration for paths matching `/service2` from the HTTPProxy named `service2` in the same namespace as `include-root` (the `default` namespace). +It's important to note that `service2` HTTPProxy has not defined a `virtualhost` property as it is NOT a root HTTPProxy. + +```yaml +# httpproxy-inclusion-samenamespace.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: include-root + namespace: default +spec: + virtualhost: + fqdn: root.bar.com + includes: + # Includes the /service2 path from service2 in the same namespace + - name: service2 + namespace: default + conditions: + - prefix: /service2 + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: service2 + namespace: default +spec: + routes: + - services: # matches /service2 + - name: s2 + port: 80 + - conditions: + - prefix: /blog # matches /service2/blog + services: + - name: blog + port: 80 +``` + +## Inclusion Across Namespaces + +Inclusion can also happen across Namespaces by specifying a `namespace` in the `inclusion`. +This is a particularly powerful paradigm for enabling multi-team Ingress management. + +If the `--watch-namespaces` configuration flag is used, it must define all namespaces that will be referenced by the inclusion. + +In this example, the root HTTPProxy has included configuration for paths matching `/blog` to the `blog` HTTPProxy object in the `marketing` namespace. + +```yaml +# httpproxy-inclusion-across-namespaces.yaml +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: namespace-include-root + namespace: default +spec: + virtualhost: + fqdn: ns-root.bar.com + includes: + # delegate the subpath, `/blog` to the HTTPProxy object in the marketing namespace with the name `blog` + - name: blog + namespace: marketing + conditions: + - prefix: /blog + routes: + - services: + - name: s1 + port: 80 + +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: blog + namespace: marketing +spec: + routes: + - services: + - name: s2 + port: 80 +``` + +## Orphaned HTTPProxy children + +It is possible for HTTPProxy objects to exist that have not been delegated to by another HTTPProxy. +These objects are considered "orphaned" and will be ignored by Contour in determining ingress configuration. + +[1]: request-routing#conditions +[2]: api/#projectcontour.io/v1.HTTPProxySpec diff --git a/site/content/docs/1.30/config/ingress.md b/site/content/docs/1.30/config/ingress.md new file mode 100644 index 00000000000..22e65bb0255 --- /dev/null +++ b/site/content/docs/1.30/config/ingress.md @@ -0,0 +1,94 @@ +# k8s Ingress Resource Support in Contour + + + + + +This document describes Contour's implementation of specific Ingress resource fields and features. +As the Ingress specification has evolved between v1beta1 and v1, any differences between versions are highlighted to ensure clarity for Contour users. + +**Note: As of Contour version 1.16.0, Contour is not compatible with Kubernetes versions that predate Ingress v1. This means Contour 1.16.0 and above require Kubernetes 1.19 and above. The Ingress v1beta1 resource is still available in Kubernetes 1.19 (but will be removed in 1.22) and the API server will convert such resources to Ingress v1 for Contour to subscribe to.** + +## Kubernetes Versions + +Contour is [validated against Kubernetes release versions N through N-2][1] (with N being the latest release). +For Kubernetes version 1.19+, the API server translates any Ingress v1beta1 resources to Ingress v1 and Contour watches Ingress v1 resources. + +## IngressClass and IngressClass Name + +In order to support differentiating between Ingress controllers or multiple instances of a single Ingress controller, users can create an [IngressClass resource][2] and specify an IngressClass name on a Ingress to reference it. +The IngressClass resource can be used to provide configuration to an Ingress controller watching resources it governs. +Contour supports watching an IngressClass resource specified with the `--ingress-class-name` flag to the `contour serve` command. +Contour does not require an IngressClass resource with the name passed in the aforementioned flag to exist, the name can just be used as an identifier for filtering which Ingress resources Contour reconciles into actual route configuration. + +Ingresses may specify an IngressClass name via the original annotation method or via the `ingressClassName` spec field. +As the `ingressClassName` field has been introduced on Ingress v1beta1, there should be no differences in IngressClass name filtering between the two available versions of the resource. +Contour uses its configured IngressClass name to filter Ingresses. +If the `--ingress-class-name` flag is provided, Contour will only accept Ingress resources that exactly match the specified IngressClass name via annotation or spec field, with the value in the annotation taking precedence. (The `--ingress-class-name` value can be a comma-separated list of class names to match against.) +If the flag is not passed to `contour serve` Contour will accept any Ingress resource that specifies the IngressClass name `contour` in annotation or spec fields or does not specify one at all. + +## Default Backend + +Contour supports the `defaultBackend` Ingress v1 spec field and equivalent `backend` v1beta1 version of the field. +See upstream [documentation][3] on this field. +Any requests that do not match an Ingress rule will be forwarded to this backend. +As TLS secrets on Ingresses are scoped to specific hosts, this default backend cannot serve TLS as it could match an unbounded set of hosts and configuring a matching set of TLS secrets would not be possible. +As is the case on Ingress rules, Contour only supports configuring a Service as a backend and does not support any other Kubernetes resource. + +## Ingress Rules + +See upstream [documentation][4] on Ingress rules. + +As with default backends, Contour only supports configuring a Service as a backend and does not support any other Kubernetes resource. + +Contour supports [wildcard hostnames][5] as documented by the upstream API as well as precise hostnames. +Wildcard hostnames are limited to the whole first DNS label of the hostname, e.g. `*.foo.com` is valid but `*foo.com`, `foo*.com`, `foo.*.com` are not. +`*` is also not a valid hostname. +Precise hostnames in Ingress or HTTPProxy configuration take higher precedence over wildcards. +For example, given an Ingress rule with the hostname `*.foo.com` routing to `service-a` and another Ingress rule or HTTPProxy route containing a subdomain (say `bar.foo.com`) routing to `service-b`, requests to `bar.foo.com` will be routed to `service-b`. +The Ingress admission controller validation ensures valid hostnames are present when creating an Ingress resource. + +Contour supports all of the various [path matching][6] types described by the Ingress spec. +Prior to Contour 1.14.0, path match types were ignored and path matching was performed with a Contour specific implementation. +Paths specified with any regex meta-characters (any of `^+*[]%`) were implemented as regex matches. +Any other paths were programmed in Envoy as "string prefix" matches. +This behavior is preserved in the `ImplementationSpecific` match type in Contour 1.14.0+ to ensure backwards compatibility. +`Exact` path matches will now result in matching requests to the given path exactly. +The `Prefix` patch match type will now result in matching requests with a "segment prefix" rather than a "string prefix" according to the spec (e.g. the prefix `/foo/bar` will match requests with paths `/foo/bar`, `/foo/bar/`, and `/foo/bar/baz`, but not `/foo/barbaz`). + +## TLS + +See upstream [documentation][7] on TLS configuration. + +A secret specified in an Ingress TLS element will only be applied to Ingress rules with `Host` configuration that exactly matches an element of the TLS `Hosts` field. +Any secrets that do not match an Ingress rule `Host` will be ignored. + +In Ingress v1beta1, the `secretName` field could contain a string with a full `namespace/name` identifier. +When used with Contour's [TLS certificate delegation][8], this allowed Ingresses to use a TLS certificate from a different namespace. +However, Ingress v1 does not allow the `secretName` field to contain a string with a full `namespace/name` identifier, because the field validation disallows the `/` character. +Instead, Ingress v1 resources can now use the `projectcontour.io/tls-cert-namespace` annotation, to define the namespace that contains the TLS certificate (if different than the Ingress's namespace). +This enables the TLS certificate delegation functionality to continue working for Ingress v1. +For more information and an example, see the [TLS certificate delegation documentation][8]. + +## Status + +In order to inform users of the address the Services their Ingress resources can be accessed at, Contour sets status on Ingress resources. +If `contour serve` is run with the `--ingress-status-address` flag, Contour will use the provided value to set the Ingress status address accordingly. +If not provided, Contour will use the address of the Envoy service using the passed in `--envoy-service-name` and `--envoy-service-namespace` flags. + +## Header Manipulation + +The Ingress resource does not allow adding or removing HTTP headers on requests or responses. +However, Contour does allow users to set a global HTTP header [policy configuration][9] which can be optionally applied to configuration generated from Ingress resources. +Contour enables this behavior with the `applyToIngress` boolean field (set to `true` to enable). + +[0]: https://github.com/kubernetes-sigs/ingress-controller-conformance +[1]: /resources/compatibility-matrix/ +[2]: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class +[3]: https://kubernetes.io/docs/concepts/services-networking/ingress/#default-backend +[4]: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules +[5]: https://kubernetes.io/docs/concepts/services-networking/ingress/#hostname-wildcards +[6]: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types +[7]: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls +[8]: /docs/{{< param version >}}/config/tls-delegation/ +[9]: /docs/{{< param version >}}/configuration/#policy-configuration diff --git a/site/content/docs/1.30/config/ip-filtering.md b/site/content/docs/1.30/config/ip-filtering.md new file mode 100644 index 00000000000..161d39bc228 --- /dev/null +++ b/site/content/docs/1.30/config/ip-filtering.md @@ -0,0 +1,80 @@ +# IP Filtering + +Contour supports filtering requests based on the incoming ip address using Envoy's [RBAC Filter][1]. + +Requests can be either allowed or denied based on a CIDR range specified on the virtual host and/or individual routes. + +If the request's IP address is allowed, the request will be proxied to the appropriate upstream. +If the request's IP address is denied, an HTTP 403 (Forbidden) will be returned to the client. + +## Specifying Rules + +Rules are specified with the `ipAllowPolicy` and `ipDenyPolicy` fields on `virtualhost` and `route`: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: basic +spec: + virtualhost: + fqdn: foo-basic.bar.com + ipAllowPolicy: + # traffic is allowed if it came from localhost (i.e. co-located reverse proxy) + - cidr: 127.0.0.1/32 + source: Peer + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + # route-level ip filters override the virtualhost-level filters + ipAllowPolicy: + # traffic is allowed if it came from localhost (i.e. co-located reverse proxy) + - cidr: 127.0.0.1/32 + source: Peer + # and the request originated from an IP in this range + - cidr: 99.99.0.0/16 + source: Remote +``` + +### Specifying CIDR Ranges + +CIDR ranges may be ipv4 or ipv6. Bare IP addresses are interpreted as the CIDR range containing that one ip address only. + +Examples: +- `1.1.1.1/24` +- `127.0.0.1` +- `2001:db8::68/24` +- `2001:db8::68` + +### Allow vs Deny + +Filters are specified as either allow or deny: + +- `ipAllowPolicy` only allows requests that match the ip filters. +- `ipDenyPolicy` denies all requests unless they match the ip filters. + +Allow and deny policies cannot both be specified at the same time for a virtual host or route. + +### IP Source + +The `source` field controls how the ip address is selected from the request for filtering. + +- `source: Peer` filter rules will filter using Envoy's [direct_remote_ip][2], which is always the physical peer. +- `source: Remote` filter rules will filter using Envoy's [remote_ip][3], which may be inferred from the X-Forwarded-For header or proxy protocol. + +If using `source: Remote` with `X-Forwarded-For`, it may be necessary to configure Contour's `numTrustedHops` in [Network Parameters][4]. + +### Virtual Host and Route Filter Precedence + +IP filters on the virtual host apply to all routes included in the virtual host, unless the route specifies its own rules. + +Rules specified on a route override any rules defined on the virtual host, they are not additive. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rbac_filter.html +[2]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/rbac/v3/rbac.proto#envoy-v3-api-field-config-rbac-v3-principal-direct-remote-ip +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/rbac/v3/rbac.proto#envoy-v3-api-field-config-rbac-v3-principal-remote-ip +[4]: api/#projectcontour.io/v1.NetworkParameters + diff --git a/site/content/docs/1.30/config/jwt-verification.md b/site/content/docs/1.30/config/jwt-verification.md new file mode 100644 index 00000000000..3f884ad2aef --- /dev/null +++ b/site/content/docs/1.30/config/jwt-verification.md @@ -0,0 +1,182 @@ +# JWT Verification + +Contour supports verifying JSON Web Tokens (JWTs) on incoming requests, using Envoy's [jwt_authn HTTP filter][1]. +Specifically, the following properties can be checked: +- issuer field +- audiences field +- signature, using a configured JSON Web Key Store (JWKS) +- time restrictions (e.g. expiration, not before time) + +If verification succeeds, the request will be proxied to the appropriate upstream. +If verification fails, an HTTP 401 (Unauthorized) will be returned to the client. + +JWT verification is only supported on TLS-terminating virtual hosts. + +## Configuring providers and rules + +A JWT provider is configured for an HTTPProxy's virtual host, and defines how to verify JWTs: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + issuer: example.com + audiences: + - audience-1 + - audience-2 + remoteJWKS: + uri: https://example.com/jwks.json + timeout: 1s + cacheDuration: 5m + forwardJWT: true + routes: + ... +``` + +The provider above requires JWTs to have an issuer of example.com, an audience of either audience-1 or audience-2, and a signature that can be verified using the configured JWKS. +It also forwards the JWT to the backend via the `Authorization` header after successful verification. + +To apply a JWT provider as a requirement to a given route, specify a `jwtVerificationPolicy` for the route: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + ... + routes: + - conditions: + - prefix: / + jwtVerificationPolicy: + require: provider-1 + services: + - name: s1 + port: 80 + - conditions: + - prefix: /css + services: + - name: s1 + port: 80 +``` + +In the above example, the default route requires requests to carry JWTs that can be verified using provider-1. +The second route _excludes_ requests to paths starting with `/css` from JWT verification, because it does not have a JWT verification policy. + +### Configuring TLS validation for the JWKS server + +By default, the JWKS server's TLS certificate will not be validated, but validation can be requested by setting the `spec.virtualhost.jwtProviders[].remoteJWKS.validation` field. +This field has mandatory `caSecret` and `subjectName` fields, which specify the trusted root certificates with which to validate the server certificate and the expected server name. +The `caSecret` can be a namespaced name of the form `/`. +If the CA secret's namespace is not the same namespace as the `HTTPProxy` resource, [TLS Certificate Delegation][5] must be used to allow the owner of the CA certificate secret to delegate, for the purposes of referencing the CA certificate in a different namespace, permission to Contour to read the Secret object from another namespace. + +**Note:** If `spec.virtualhost.jwtProviders[].remoteJWKS.validation` is present, `spec.virtualhost.jwtProviders[].remoteJWKS.uri` must have a scheme of `https`. + +## Setting a default provider + +The previous section showed how to explicitly require JWT providers for specific routes. +An alternate approach is to define a JWT provider as the default by specifying `default: true` for it, in which case it is automatically applied to all routes unless they disable JWT verification. +The example from the previous section could alternately be configured as follows: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + default: true + ... + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - conditions: + - prefix: /css + jwtVerificationPolicy: + disabled: true + services: + - name: s1 + port: 80 +``` + +In this case, the default route automatically has provider-1 applied, while the `/css` route explicitly disables JWT verification. + +One scenario where setting a default provider can be particularly useful is when using [HTTPProxy inclusion][2]. +Setting a default provider in the root HTTPProxy allows all routes in the child HTTPProxies to automatically have JWT verification applied. +For example: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification-root + namespace: default +spec: + virtualhost: + fqdn: example.com + tls: + secretName: example-com-tls-cert + jwtProviders: + - name: provider-1 + default: true + ... + includes: + - name: jwt-verification-child + namespace: default + conditions: + - prefix: /blog +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: jwt-verification-child + namespace: default +spec: + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +``` + +In this case, all routes in the child HTTPProxy will automatically have JWT verification applied, without the owner of this HTTPProxy needing to configure it explicitly. + +## API documentation + +For more information on the HTTPProxy API for JWT verification, see: + +- [JWTProvider][3] +- [JWTVerificationPolicy][4] + + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter +[2]: /docs/{{< param version >}}/config/inclusion-delegation/ +[3]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.JWTProvider +[4]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.JWTVerificationPolicy +[5]: tls-delegation.md diff --git a/site/content/docs/1.30/config/overload-manager.md b/site/content/docs/1.30/config/overload-manager.md new file mode 100644 index 00000000000..33c96532eba --- /dev/null +++ b/site/content/docs/1.30/config/overload-manager.md @@ -0,0 +1,30 @@ +# Overload Manager + +Envoy uses heap memory when processing requests. +When the system runs out of memory or memory resource limit for the container is reached, Envoy process is terminated abruptly. +To avoid this, Envoy [overload manager][1] can be enabled. +Overload manager controls how much memory Envoy will allocate at maximum and what actions it takes when the limit is reached. + +Overload manager is disabled by default. +It can be enabled at deployment time by using `--overload-max-heap=[MAX_BYTES]` command line flag in [`contour bootstrap`][2] command. +The bootstrap command is executed in [init container of Envoy pod][3] to generate initial configuration for Envoy. +To enable overload manager, modify the deployment manifest and add for example `--overload-max-heap=2147483648` to set maximum heap size to 2 GiB. +The appropriate number of bytes can be different from system to system. + +After the feature is enabled, following two overload actions are configured to Envoy: + +* Shrink heap action is executed when 95% of the maximum heap size is reached. +* Envoy will stop accepting requests when 98% of the maximum heap size is reached. + +When requests are denied due to high memory pressure, `503 Service Unavailable` will be returned with a response body containing text `envoy overloaded`. +Shrink heap action will try to free unused heap memory, eventually allowing requests to be processed again. + +**NOTE:** +The side effect of overload is that Envoy will deny also requests `/ready` and `/stats` endpoints. +This is due to the way how Contour secures Envoy's admin API and exposes only selected admin API endpoints by proxying itself. +When readiness probe fails, the overloaded Envoy will be removed from the list of service endpoints. +If the maximum heap size is set too low, Envoy may be unable to free enough memory and never become ready again. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager +[2]: ../configuration#bootstrap-flags +[3]: https://github.com/projectcontour/contour/blob/cbec8eca9e8b639318588c5aa7ec0b5b751938c5/examples/render/contour.yaml#L5204-L5216 diff --git a/site/content/docs/1.30/config/rate-limiting.md b/site/content/docs/1.30/config/rate-limiting.md new file mode 100644 index 00000000000..7a69c22c079 --- /dev/null +++ b/site/content/docs/1.30/config/rate-limiting.md @@ -0,0 +1,366 @@ +# Rate Limiting + +- [Overview](#overview) +- [Local Rate Limiting](#local-rate-limiting) +- [Global Rate Limiting](#global-rate-limiting) + +## Overview + +Rate limiting is a means of protecting backend services against unwanted traffic. +This can be useful for a variety of different scenarios: + +- Protecting against denial-of-service (DoS) attacks by malicious actors +- Protecting against DoS incidents due to bugs in client applications/services +- Enforcing usage quotas for different classes of clients, e.g. free vs. paid tiers +- Controlling resource consumption/cost + +Envoy supports two forms of HTTP rate limiting: **local** and **global**. + +In local rate limiting, rate limits are enforced by each Envoy instance, without any communication with other Envoys or any external service. + +In global rate limiting, an external rate limit service (RLS) is queried by each Envoy via gRPC for rate limit decisions. + +Contour supports both forms of Envoy's rate limiting. + +## Local Rate Limiting + +The `HTTPProxy` API supports defining local rate limit policies that can be applied to either individual routes or entire virtual hosts. +Local rate limit policies define a maximum number of requests per unit of time that an Envoy should proxy to the upstream service. +Requests beyond the defined limit will receive a `429 (Too Many Requests)` response by default. +Local rate limit policies program Envoy's [HTTP local rate limit filter][1]. + +It's important to note that local rate limit policies apply *per Envoy pod*. +For example, a local rate limit policy of 100 requests per second for a given route will result in *each Envoy pod* allowing up to 100 requests per second for that route. + +### Defining a local rate limit + +Local rate limit policies can be defined for either routes or virtual hosts. A local rate limit policy requires a `requests` and a `units` field, defining the *number of requests per unit of time* that are allowed. `Requests` must be a positive integer, and `units` can be `second`, `minute`, or `hour`. Optionally, a `burst` parameter can also be provided, defining the number of requests above the baseline rate that are allowed in a short period of time. This would allow occasional larger bursts of traffic not to be rate limited. + +Local rate limiting for the virtual host: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-vhost +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + local: + requests: 100 + unit: hour + burst: 20 + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +Local rate limiting for the route: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-route +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + local: + requests: 20 + unit: minute + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +### Customizing the response + +#### Response code + +By default, Envoy returns a `429 (Too Many Requests)` when a request is rate limited. +A non-default response code can optionally be configured as part of the local rate limit policy, in the `responseStatusCode` field. +The value must be in the 400-599 range. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: custom-ratelimit-response +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + local: + requests: 20 + unit: minute + responseStatusCode: 503 # Service Unavailable +``` + +#### Headers + +Headers can optionally be added to rate limited responses, by configuring the `responseHeadersToAdd` field. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: custom-ratelimit-response +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + local: + requests: 20 + unit: minute + responseHeadersToAdd: + - name: x-contour-ratelimited + value: "true" +``` + +## Global Rate Limiting + +The `HTTPProxy` API also supports defining global rate limit policies on routes and virtual hosts. + +In order to use global rate limiting, you must first select and deploy an external rate limit service (RLS). +There is an [Envoy rate limit service implementation][2], but any service that implements the [RateLimitService gRPC interface][3] is supported. + +### Configuring an external RLS with Contour + +Once you have deployed your RLS, you must configure it with Contour. + +Define an extension service for it (substituting values as appropriate): +```yaml +apiVersion: projectcontour.io/v1alpha1 +kind: ExtensionService +metadata: + namespace: projectcontour + name: ratelimit +spec: + protocol: h2 + services: + - name: ratelimit + port: 8081 +``` + +Now add a reference to it in the Contour config file: +```yaml +rateLimitService: + # The namespace/name of the extension service. + extensionService: projectcontour/ratelimit + # The domain value to pass to the RLS for all rate limit + # requests. Acts as a container for a set of rate limit + # definitions within the RLS. + domain: contour + # Whether to allow requests to proceed when the rate limit + # service fails to respond with a valid rate limit decision + # within the timeout defined on the extension service. + failOpen: true +``` + +### Defining a global rate limit policy + +Global rate limit policies can be defined for either routes or virtual hosts. Unlike local rate limit policies, global rate limit policies do not directly define a rate limit. Instead, they define a set of request descriptors that will be generated and sent to the external RLS for each request. The external RLS then makes the rate limit decision based on the descriptors and returns a response to Envoy. + +A global rate limit policy for the virtual host: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-vhost +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + global: + descriptors: + # the first descriptor has a single key-value pair: + # [ remote_address= ]. + - entries: + - remoteAddress: {} + # the second descriptor has two key-value pairs: + # [ remote_address=, vhost=local.projectcontour.io ]. + - entries: + - remoteAddress: {} + - genericKey: + key: vhost + value: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +A global rate limit policy for the route: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + namespace: default + name: ratelimited-route +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: /s1 + services: + - name: s1 + port: 80 + rateLimitPolicy: + global: + descriptors: + # the first descriptor has a single key-value pair: + # [ remote_address= ]. + - entries: + - remoteAddress: {} + # the second descriptor has two key-value pairs: + # [ remote_address=, prefix=/s1 ]. + - entries: + - remoteAddress: {} + - genericKey: + key: prefix + value: /s1 + - conditions: + - prefix: /s2 + services: + - name: s2 + port: 80 +``` + +#### Descriptors & descriptor entries + +A descriptor is a list of key-value pairs, i.e. entries, that are generated for a request. The entries can be generated based on different criteria. If any entry in a descriptor cannot generate a key-value pair for a given request, then the entire descriptor is not generated (see the [Envoy documentation][8] for more information). When a global rate limit policy defines multiple descriptors, then *all* descriptors that can be generated will be generated and sent to the rate limit service for consideration. + +Below are the supported types of descriptor entries. + +##### GenericKey + +A `GenericKey` descriptor entry defines a static key-value pair. For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - genericKey: + key: virtual-host-name + value: foo.bar.com +``` + +Produces a descriptor entry of `virtual-host-name=foo.bar.com`. + +The `key` field is optional and defaults to a value of `generic_key` if not specified. + +See the [Envoy documentation][4] for more information and examples. + +##### RemoteAddress + +A `RemoteAddress` descriptor entry has a key of `remote_address` and a value of the client IP address (using the trusted address from `x-forwarded-for`). For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - remoteAddress: {} +``` + +Produces a descriptor entry of `remote_address=`. + +See the [Envoy documentation][5] for more information and examples. + +##### RequestHeader + +A `RequestHeader` descriptor entry has a static key and a value equal to the value of a specified header on the client request. If the header is not present, the descriptor entry is not generated. For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - requestHeader: + headerName: My-Header + descriptorKey: my-header-value +``` + +Produces a descriptor entry of `my-header-value=`, for a client request that has the `My-Header` header. + +See the [Envoy documentation][6] for more information and examples. + +##### RequestHeaderValueMatch + +A `RequestHeaderValueMatch` descriptor entry has a key of `header_match` and a static value. The entry is only generated if the client request's headers match a specified set of criteria. For example: + +```yaml +rateLimitPolicy: + global: + descriptors: + - entries: + - requestHeaderValueMatch: + headers: + - name: My-Header + notpresent: true + - name: My-Other-Header + contains: contour + expectMatch: true + value: foo +``` + +Produces a descriptor entry of `header_match=foo`, for a client request that does not have the `My-Header` header, and does have the `My-Other-Header` header, with a value containing the substring "contour". + +Contour supports `present`, `notpresent`, `contains`, `notcontains`, `exact`, and `notexact` header match operators. + +The `expectMatch` field defaults to true if not specified. If true, the client request's headers must positively match the specified criteria in order for the descriptor entry to be generated. If false, the client request's header must *not* match the specified criteria in order for the descriptor entry to be generated. + +See the [Envoy documentation][7] for more information and examples. + + + +[1]: https://www.envoyproxy.io/docs/envoy/v1.17.0/configuration/http/http_filters/local_rate_limit_filter#config-http-filters-local-rate-limit +[2]: https://github.com/envoyproxy/ratelimit +[3]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto +[4]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-ratelimit-action-generickey +[5]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-action-remoteaddress +[6]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-action-requestheaders +[7]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-action-headervaluematch +[8]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter#composing-actions diff --git a/site/content/docs/1.30/config/request-rewriting.md b/site/content/docs/1.30/config/request-rewriting.md new file mode 100644 index 00000000000..88fa3cc2508 --- /dev/null +++ b/site/content/docs/1.30/config/request-rewriting.md @@ -0,0 +1,337 @@ +# Request Rewriting + +## Path Rewriting + +HTTPProxy supports rewriting the HTTP request URL path prior to delivering the request to the backend service. +Rewriting is performed after a routing decision has been made, and never changes the request destination. + +The `pathRewritePolicy` field specifies how the path prefix should be rewritten. +The `replacePrefix` rewrite policy specifies a replacement string for a HTTP request path prefix match. +When this field is present, the path prefix that the request matched is replaced by the text specified in the `replacement` field. +If the HTTP request path is longer than the matched prefix, the remainder of the path is unchanged. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: rewrite-example + namespace: default +spec: + virtualhost: + fqdn: rewrite.bar.com + routes: + - services: + - name: s1 + port: 80 + pathRewritePolicy: + replacePrefix: + - replacement: /new/prefix +``` + +The `replacePrefix` field accepts an array of possible replacements. +When more than one `replacePrefix` array element is present, the `prefix` field can be used to disambiguate which replacement to apply. + +If no `prefix` field is present, the replacement is applied to all prefix matches made against the route. +If a `prefix` field is present, the replacement is applied only to routes that have an exactly matching prefix condition. +Specifying more than one `replacePrefix` entry is mainly useful when a HTTPProxy document is included into multiple parent documents. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: rewrite-example + namespace: default +spec: + virtualhost: + fqdn: rewrite.bar.com + routes: + - services: + - name: s1 + port: 80 + conditions: + - prefix: /v1/api + pathRewritePolicy: + replacePrefix: + - prefix: /v1/api + replacement: /app/api/v1 + - prefix: / + replacement: /app +``` + +## Header Rewriting + +HTTPProxy supports rewriting HTTP request and response headers. +The `Set` operation sets a HTTP header value, creating it if it doesn't already exist or overwriting it if it does. +The `Remove` operation removes a HTTP header. +The `requestHeadersPolicy` field is used to rewrite headers on a HTTP request, and the `responseHeadersPolicy` is used to rewrite headers on a HTTP response. +These fields can be specified on a route or on a specific service, depending on the rewrite granularity you need. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: header-rewrite-example +spec: + virtualhost: + fqdn: header.bar.com + routes: + - services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: Host + value: external.dev + remove: + - Some-Header + - Some-Other-Header +``` + +Manipulating headers is also supported per-Service or per-Route. Headers can be set or +removed from the request or response as follows: + +per-Service: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: header-manipulation + namespace: default +spec: + virtualhost: + fqdn: headers.bar.com + routes: + - services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: X-Foo + value: bar + remove: + - X-Baz + responseHeadersPolicy: + set: + - name: X-Service-Name + value: s1 + remove: + - X-Internal-Secret +``` + +per-Route: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: header-manipulation + namespace: default +spec: + virtualhost: + fqdn: headers.bar.com + routes: + - services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: X-Foo + value: bar + remove: + - X-Baz + responseHeadersPolicy: + set: + - name: X-Service-Name + value: s1 + remove: + - X-Internal-Secret +``` + +In these examples we are setting the header `X-Foo` with value `baz` on requests +and stripping `X-Baz`. We are then setting `X-Service-Name` on the response with +value `s1`, and removing `X-Internal-Secret`. + +### Dynamic Header Values + +It is sometimes useful to set a header value using a dynamic value such as the +hostname where the Envoy Pod is running (`%HOSTNAME%`) or the subject of the +TLS client certificate (`%DOWNSTREAM_PEER_SUBJECT%`) or based on another header +(`%REQ(header)%`). + +Examples: +``` + requestHeadersPolicy: + set: + - name: X-Envoy-Hostname + value: "%HOSTNAME%" + - name: X-Host-Protocol + value: "%REQ(Host)% - %PROTOCOL%" + responseHeadersPolicy: + set: + - name: X-Envoy-Response-Flags + value: "%RESPONSE_FLAGS%" +``` + +Contour supports most of the custom request/response header variables offered +by Envoy - see the Envoy +documentation for details of what each of these resolve to: + +* `%DOWNSTREAM_REMOTE_ADDRESS%` +* `%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%` +* `%DOWNSTREAM_LOCAL_ADDRESS%` +* `%DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT%` +* `%DOWNSTREAM_LOCAL_PORT%` +* `%DOWNSTREAM_LOCAL_URI_SAN%` +* `%DOWNSTREAM_PEER_URI_SAN%` +* `%DOWNSTREAM_LOCAL_SUBJECT%` +* `%DOWNSTREAM_PEER_SUBJECT%` +* `%DOWNSTREAM_PEER_ISSUER%` +* `%DOWNSTREAM_TLS_SESSION_ID%` +* `%DOWNSTREAM_TLS_CIPHER%` +* `%DOWNSTREAM_TLS_VERSION%` +* `%DOWNSTREAM_PEER_FINGERPRINT_256%` +* `%DOWNSTREAM_PEER_FINGERPRINT_1%` +* `%DOWNSTREAM_PEER_SERIAL%` +* `%DOWNSTREAM_PEER_CERT%` +* `%DOWNSTREAM_PEER_CERT_V_START%` +* `%DOWNSTREAM_PEER_CERT_V_END%` +* `%HOSTNAME%` +* `%REQ(header-name)%` +* `%PROTOCOL%` +* `%RESPONSE_FLAGS%` +* `%RESPONSE_CODE_DETAILS%` +* `%UPSTREAM_REMOTE_ADDRESS%` + +Note that Envoy passes variables that can't be expanded through unchanged or +skips them entirely - for example: +* `%UPSTREAM_REMOTE_ADDRESS%` as a request header remains as + `%UPSTREAM_REMOTE_ADDRESS%` because as noted in the Envoy docs: "The upstream + remote address cannot be added to request headers as the upstream host has not + been selected when custom request headers are generated." +* `%DOWNSTREAM_TLS_VERSION%` is skipped if TLS is not in use +* Envoy ignores REQ headers that refer to an non-existent header - for example + `%REQ(Host)%` works as expected but `%REQ(Missing-Header)%` is skipped + +Contour already sets the `X-Request-Start` request header to +`t=%START_TIME(%s.%3f)%` which is the Unix epoch time when the request +started. + +To enable setting header values based on the destination service Contour also supports: + +* `%CONTOUR_NAMESPACE%` +* `%CONTOUR_SERVICE_NAME%` +* `%CONTOUR_SERVICE_PORT%` + +For example, with the following HTTPProxy object that has a per-Service requestHeadersPolicy using these variables: +``` +# httpproxy.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: basic + namespace: myns +spec: + virtualhost: + fqdn: foo-basic.bar.com + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + requestHeadersPolicy: + set: + - name: l5d-dst-override + value: "%CONTOUR_SERVICE_NAME%.%CONTOUR_NAMESPACE%.svc.cluster.local:%CONTOUR_SERVICE_PORT%" +``` +the values would be: +* `CONTOUR_NAMESPACE: "myns"` +* `CONTOUR_SERVICE_NAME: "s1"` +* `CONTOUR_SERVICE_PORT: "80"` + +and the `l5-dst-override` header would be set to `s1.myns.svc.cluster.local:80`. + +For per-Route requestHeadersPolicy only `%CONTOUR_NAMESPACE%` is set and using +`%CONTOUR_SERVICE_NAME%` and `%CONTOUR_SERVICE_PORT%` will end up as the +literal values `%%CONTOUR_SERVICE_NAME%%` and `%%CONTOUR_SERVICE_PORT%%`, +respectively. + +### Manipulating the Host header + +Contour allows users to manipulate the host header in two ways, using the `requestHeadersPolicy`. + +#### Static rewrite + +You can set the host to a static value. This can be done on the route and service level. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: static-host-header-rewrite-route +spec: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - requestHeaderPolicy: + set: + - name: host + value: foo.com +``` + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: static-host-header-rewrite-service +spec: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - requestHeaderPolicy: + set: + - name: host + value: "foo.com" +``` + +#### Dynamic rewrite + +You can also set the host header dynamically with the content of an existing header. +The format has to be `"%REQ()%"`. If the header is empty, it is ignored. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: dynamic-host-header-rewrite-route +spec: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 + - requestHeaderPolicy: + set: + - name: host + value: "%REQ(x-rewrite-header)%" +``` + +Note: Only one of static or dynamic host rewrite can be specified. + +Note: Dynamic rewrite is only available at the route level and not possible on the service level. + +Note: Pay attention to the potential security implications of using this option, the provided header must come from a trusted source. + +Note: The header rewrite is only done while forwarding and has no bearing on the routing decision. diff --git a/site/content/docs/1.30/config/request-routing.md b/site/content/docs/1.30/config/request-routing.md new file mode 100644 index 00000000000..19ef5386e86 --- /dev/null +++ b/site/content/docs/1.30/config/request-routing.md @@ -0,0 +1,535 @@ +# Request Routing + +A HTTPProxy object must have at least one route or include defined. +In this example, any requests to `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` will be routed to the Service `s2` using the prefix conditions. Requests to `multi-path.bar.com/feed` will be routed to Service `s2` using exact match condition. +All other requests to the host `multi-path.bar.com` will be routed to the Service `s1`. + +```yaml +# httpproxy-multiple-paths.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-paths + namespace: default +spec: + virtualhost: + fqdn: multi-path.bar.com + routes: + - conditions: + - prefix: / # matches everything else + services: + - name: s1 + port: 80 + - conditions: + - prefix: /blog # matches `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` + services: + - name: s2 + port: 80 + - conditions: + - exact: /feed # matches `multi-path.bar.com/feed` only + services: + - name: s2 + port: 80 +``` + +In the following example, we match on headers and query parameters and send to different services, with a default route if those do not match. + +```yaml +# httpproxy-multiple-headers.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-paths + namespace: default +spec: + virtualhost: + fqdn: multi-path.bar.com + routes: + - conditions: + - header: + name: x-os + contains: ios + services: + - name: s1 + port: 80 + - conditions: + - header: + name: x-os + contains: android + services: + - name: s2 + port: 80 + - conditions: + - queryParameter: + name: os + exact: other + ignoreCase: true + services: + - name: s3 + port: 80 + - services: + - name: s4 + port: 80 +``` + +## Conditions + +Each Route entry in a HTTPProxy **may** contain one or more conditions. +These conditions are combined with an AND operator on the route passed to Envoy. +Conditions can be either a `prefix`, `exact`, `regex`, `header` or a `queryParameter` condition. At most one of `prefix`, `exact` or `regex` can be used in one condition block. + +#### Prefix conditions + +Paths defined are matched using prefix conditions. +Up to one prefix condition may be present in any condition block. + +Prefix conditions **must** start with a `/` if they are present. + +#### Exact conditions + +Paths defined are matched using exact conditions. +Up to one exact condition may be present in any condition block. Any condition block can +either have a regex condition, exact condition or prefix condition, but not multiple together. Exact conditions are +only allowed in route match conditions and not in include match conditions. + +Exact conditions **must** start with a `/` if they are present. + +#### Regex conditions + +Paths defined are matched using regex expressions. +Up to one regex condition may be present in any condition block. Any condition block can +either have a regex condition, exact condition or prefix condition, but not multiple together. Regex conditions are +only allowed in route match conditions and not in include match conditions. + +Regex conditions **must** start with a `/` if they are present. + +#### Header conditions + +For `header` conditions there is the following structure: + +1. one required field, `name` +2. six operator fields: `present`, `notpresent`, `contains`, `notcontains`, `exact`, and `notexact` +3. two optional modifiers: `ignoreCase` and `treatMissingAsEmpty` + +Operators: +- `present` is a boolean and checks that the header is present. The value will not be checked. + +- `notpresent` similarly checks that the header is *not* present. + +- `contains` is a string, and checks that the header contains the string. `notcontains` similarly checks that the header does *not* contain the string. + +- `exact` is a string, and checks that the header exactly matches the whole string. `notexact` checks that the header does *not* exactly match the whole string. + +- `regex` is a string representing a regular expression, and checks that the header value matches against the given regular expression. + +Modifiers: +- `ignoreCase`: IgnoreCase specifies that string matching should be case insensitive. It has no effect on the `Regex` parameter. +- `treatMissingAsEmpty`: specifies if the header match rule specified header does not exist, this header value will be treated as empty. Defaults to false. Unlike the underlying Envoy implementation this is **only** supported for negative matches (e.g. NotContains, NotExact). + +#### Query parameter conditions + +Similar to the `header` conditions, `queryParameter` conditions also require the +`name` field to be specified, which represents the name of the query parameter +e.g. `search` when the query string looks like `/?search=term` and `term` +representing the value. + +There are six operator fields: `exact`, `prefix`, `suffix`, `regex`, `contains` +and `present` and a modifier `ignoreCase` which can be used together with all of +the operator fields except `regex` and `present`. + +- `exact` is a string, and checks that the query parameter value exactly matches + the whole string. + +- `prefix` is a string, and checks that the query parameter value is prefixed by + the given value. + +- `suffix` is a string, and checks that the query parameter value is suffixed by + the given value. + +- `regex` is a string representing a regular expression, and checks that the + query parameter value matches against the given regular expression. + +- `contains` is a string, and checks that the query parameter value contains + the given string. + +- `present` is a boolean, and checks that the query parameter is present. The + value will not be checked. + +- `ignoreCase` is a boolean, and if set to `true` it will enable case + insensitive matching for any of the string operator matching methods. + +## Request Redirection + +HTTP redirects can be implemented in HTTPProxy using `requestRedirectPolicy` on a route. +In the following basic example, requests to `example.com` are redirected to `www.example.com`. +We configure a root HTTPProxy for `example.com` that contains redirect configuration. +We also configure a root HTTPProxy for `www.example.com` that represents the destination of the redirect. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example-com +spec: + virtualhost: + fqdn: example.com + routes: + - conditions: + - prefix: / + requestRedirectPolicy: + hostname: www.example.com +``` + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: www-example-com +spec: + virtualhost: + fqdn: www.example.com + routes: + - conditions: + - prefix: / + services: + - name: s1 + port: 80 +``` + +In addition to specifying the hostname to set in the `location` header, the scheme, port, and returned status code of the redirect response can be configured. +Configuration of the path or a path prefix replacement to modify the path of the returned `location` can be included as well. +See [the API specification][3] for more detail. + +## Multiple Upstreams + +One of the key HTTPProxy features is the ability to support multiple services for a given path: + +```yaml +# httpproxy-multiple-upstreams.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-upstreams + namespace: default +spec: + virtualhost: + fqdn: multi.bar.com + routes: + - services: + - name: s1 + port: 80 + - name: s2 + port: 80 +``` + +In this example, requests for `multi.bar.com/` will be load balanced across two Kubernetes Services, `s1`, and `s2`. +This is helpful when you need to split traffic for a given URL across two different versions of an application. + +### Upstream Weighting + +Building on multiple upstreams is the ability to define relative weights for upstream Services. +This is commonly used for canary testing of new versions of an application when you want to send a small fraction of traffic to a specific Service. + +```yaml +# httpproxy-weight-shifting.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: weight-shifting + namespace: default +spec: + virtualhost: + fqdn: weights.bar.com + routes: + - services: + - name: s1 + port: 80 + weight: 10 + - name: s2 + port: 80 + weight: 90 +``` + +In this example, we are sending 10% of the traffic to Service `s1`, while Service `s2` receives the remaining 90% of traffic. + +HTTPProxy weighting follows some specific rules: + +- If no weights are specified for a given route, it's assumed even distribution across the Services. +- Weights are relative and do not need to add up to 100. If all weights for a route are specified, then the "total" weight is the sum of those specified. As an example, if weights are 20, 30, 20 for three upstreams, the total weight would be 70. In this example, a weight of 30 would receive approximately 42.9% of traffic (30/70 = .4285). +- If some weights are specified but others are not, then it's assumed that upstreams without weights have an implicit weight of zero, and thus will not receive traffic. + +### Traffic mirroring + +Per route, a service can be nominated as a mirror. +The mirror service will receive a copy of the read traffic sent to any non mirror service. +The mirror traffic is considered _read only_, any response by the mirror will be discarded. + +This service can be useful for recording traffic for later replay or for smoke testing new deployments. + +`weight` can be optionally set (in the space of integers 1-100) to mirror the corresponding percent of traffic (ie. `weight: 5` mirrors 5% of traffic). Omitting the `weight` field results in 100% traffic mirroring. There is unexpected behavior if `weight` is explicitly set to 0, 100% traffic will be mirrored. This occurs because we cannot distinguish undefined variables from explicitly setting them to default values, and omission of a `weight` must mirror full traffic. +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: traffic-mirror + namespace: default +spec: + virtualhost: + fqdn: www.example.com + routes: + - conditions: + - prefix: / + services: + - name: www + port: 80 + - name: www-mirror + port: 80 + mirror: true +``` + +## Response Timeouts + +Each Route can be configured to have a timeout policy and a retry policy as shown: + +```yaml +# httpproxy-response-timeout.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: response-timeout + namespace: default +spec: + virtualhost: + fqdn: timeout.bar.com + routes: + - timeoutPolicy: + response: 1s + idle: 10s + idleConnection: 60s + retryPolicy: + count: 3 + perTryTimeout: 150ms + services: + - name: s1 + port: 80 +``` + +In this example, requests to `timeout.bar.com/` will have a response timeout policy of 1s. +This refers to the time that spans between the point at which complete client request has been processed by the proxy, and when the response from the server has been completely processed. + +- `timeoutPolicy.response` Timeout for receiving a response from the server after processing a request from client. +If not supplied, Envoy's default value of 15s applies. +More information can be found in [Envoy's documentation][4]. +- `timeoutPolicy.idle` Timeout for how long the proxy should wait while there is no activity during single request/response (for HTTP/1.1) or stream (for HTTP/2). +Timeout will not trigger while HTTP/1.1 connection is idle between two consecutive requests. +If not specified, there is no per-route idle timeout, though a connection manager-wide stream idle timeout default of 5m still applies. +More information can be found in [Envoy's documentation][6]. +- `timeoutPolicy.idleConnection` Timeout for how long connection from the proxy to the upstream service is kept when there are no active requests. +If not supplied, Envoy’s default value of 1h applies. +More information can be found in [Envoy's documentation][8]. + +TimeoutPolicy durations are expressed in the Go [Duration format][5]. +Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". +The string "infinity" is also a valid input and specifies no timeout. +A value of "0s" will be treated as if the field were not set, i.e. by using Envoy's default behavior. +Example input values: "300ms", "5s", "1m". + +- `retryPolicy`: A retry will be attempted if the server returns an error code in the 5xx range, or if the server takes more than `retryPolicy.perTryTimeout` to process a request. + +- `retryPolicy.count` specifies the maximum number of retries allowed. This parameter is optional and defaults to 1. Set to -1 to disable. If set to 0, the Envoy default of 1 is used. + +- `retryPolicy.perTryTimeout` specifies the timeout per retry. If this field is greater than the request timeout, it is ignored. This parameter is optional. + If left unspecified, `timeoutPolicy.request` will be used. + +## Load Balancing Strategy + +Each route can have a load balancing strategy applied to determine which of its Endpoints is selected for the request. +The following list are the options available to choose from: + +- `RoundRobin`: Each healthy upstream Endpoint is selected in round-robin order (Default strategy if none selected). +- `WeightedLeastRequest`: The least request load balancer uses different algorithms depending on whether hosts have the same or different weights in an attempt to route traffic based upon the number of active requests or the load at the time of selection. +- `Random`: The random strategy selects a random healthy Endpoints. +- `RequestHash`: The request hashing strategy allows for load balancing based on request attributes. An upstream Endpoint is selected based on the hash of an element of a request. For example, requests that contain a consistent value in an HTTP request header will be routed to the same upstream Endpoint. Currently, only hashing of HTTP request headers, query parameters and the source IP of a request is supported. +- `Cookie`: The cookie load balancing strategy is similar to the request hash strategy and is a convenience feature to implement session affinity, as described below. + +More information on the load balancing strategy can be found in [Envoy's documentation][7]. + +The following example defines the strategy for the route `/` as `WeightedLeastRequest`. + +```yaml +# httpproxy-lb-strategy.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-strategy + namespace: default +spec: + virtualhost: + fqdn: strategy.bar.com + routes: + - conditions: + - prefix: / + services: + - name: s1-strategy + port: 80 + - name: s2-strategy + port: 80 + loadBalancerPolicy: + strategy: WeightedLeastRequest +``` + +The below example demonstrates how request hash load balancing policies can be configured: + +Request hash headers +```yaml +# httpproxy-lb-request-hash.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-request-hash + namespace: default +spec: + virtualhost: + fqdn: request-hash.bar.com + routes: + - conditions: + - prefix: / + services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: RequestHash + requestHashPolicies: + - headerHashOptions: + headerName: X-Some-Header + terminal: true + - headerHashOptions: + headerName: User-Agent + - hashSourceIP: true +``` +In this example, if a client request contains the `X-Some-Header` header, the value of the header will be hashed and used to route to an upstream Endpoint. This could be used to implement a similar workflow to cookie-based session affinity by passing a consistent value for this header. If it is present, because it is set as a `terminal` hash option, Envoy will not continue on to process to `User-Agent` header or source IP to calculate a hash. If `X-Some-Header` is not present, Envoy will use the `User-Agent` header value to make a routing decision along with the source IP of the client making the request. These policies can be used alone or as shown for an advanced routing decision. + + +Request hash source ip +```yaml +# httpproxy-lb-request-hash-ip.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-request-hash + namespace: default +spec: + virtualhost: + fqdn: request-hash.bar.com + routes: + - conditions: + - prefix: / + services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: RequestHash + requestHashPolicies: + - hashSourceIP: true +``` + +Request hash query parameters +```yaml +# httpproxy-lb-request-hash.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: lb-request-hash + namespace: default +spec: + virtualhost: + fqdn: request-hash.bar.com + routes: + - conditions: + - prefix: / + services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: RequestHash + requestHashPolicies: + - queryParameterHashOptions: + prameterName: param1 + terminal: true + - queryParameterHashOptions: + parameterName: param2 +``` + +## Session Affinity + +Session affinity, also known as _sticky sessions_, is a load balancing strategy whereby a sequence of requests from a single client are consistently routed to the same application backend. +Contour supports session affinity on a per-route basis with `loadBalancerPolicy` `strategy: Cookie`. + +```yaml +# httpproxy-sticky-sessions.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: httpbin + namespace: default +spec: + virtualhost: + fqdn: httpbin.davecheney.com + routes: + - services: + - name: httpbin + port: 8080 + loadBalancerPolicy: + strategy: Cookie +``` + +Session affinity is based on the premise that the backend servers are robust, do not change ordering, or grow and shrink according to load. +None of these properties are guaranteed by a Kubernetes cluster and will be visible to applications that rely heavily on session affinity. + +Any perturbation in the set of pods backing a service risks redistributing backends around the hash ring. + +## Internal Redirects + +HTTPProxy supports handling 3xx redirects internally, that is capturing a configurable 3xx redirect response, synthesizing a new request, sending it to the upstream specified by the new route match, and returning the redirected response as the response to the original request. + +Internal redirects can be enabled in HTTPProxy by defining an `internalRedirectPolicy` on a route. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: myservice + namespace: prod +spec: + virtualhost: + fqdn: foo.com + routes: + - conditions: + - prefix: /download + services: + - name: foo + port: 8080 + internalRedirectPolicy: + maxInternalRedirects: 5 + redirectResponseCodes: [ 302 ] + allowCrossSchemeRedirect: SafeOnly + denyRepeatedRouteRedirect: true +``` + +In this example, a sample redirect flow might look like this: + +1. Client sends a `GET` request for http://foo.com/download. +2. Upstream `foo` returns a `302` response with `location: http://foo.com/myfile`. +3. Envoy lookups a route for http://foo.com/myfile and sends a new `GET` request to the corresponding upstream with the additional request header `x-envoy-original-url: http://foo.com/download`. +4. Envoy proxies the response data for http://foo.com/myfile to the client as the response to the original request. + +See [the API specification][9] and [Envoy's documentation][10] for more detail. + +[3]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.HTTPRequestRedirectPolicy +[4]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-timeout +[5]: https://godoc.org/time#ParseDuration +[6]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-idle-timeout +[7]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/overview +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout +[9] /docs/{{< param version >}}/config/api/#projectcontour.io/v1.HTTPInternalRedirectPolicy +[10] https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/http_connection_management.html#internal-redirects diff --git a/site/content/docs/1.30/config/slow-start.md b/site/content/docs/1.30/config/slow-start.md new file mode 100644 index 00000000000..b44cc18fdc3 --- /dev/null +++ b/site/content/docs/1.30/config/slow-start.md @@ -0,0 +1,39 @@ +# Slow Start Mode + +Slow start mode is a configuration setting that is used to gradually increase the amount of traffic targeted to a newly added upstream endpoint. +By default, the amount of traffic will increase linearly for the duration of time window set by `window` field, starting from 10% of the target load balancing weight and increasing to 100% gradually. +The easing function for the traffic increase can be adjusted by setting optional field `aggression`. +A value above 1.0 results in a more aggressive increase initially, slowing down when nearing the end of the time window. +Value below 1.0 results in slow initial increase, picking up speed when nearing the end of the time window. +Optional field `minWeightPercent` can be set to change the minimum percent of target weight. +It is used to avoid too small new weight, which may cause endpoint to receive no traffic in beginning of the slow start window. + +Slow start mode can be useful for example with JVM based applications, that might otherwise get overwhelmed during JIT warm-up period. +Such applications may respond to requests slowly or return errors immediately after pod start or after container restarts. +User impact of this behavior can be mitigated by using slow start configuration to gradually increase traffic to recently started service endpoints. + +The following example configures slow start mode for a service: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: slow-start +spec: + virtualhost: + fqdn: www.example.com + routes: + - services: + - name: java-app + port: 80 + slowStartPolicy: + window: 3s + aggression: "1.0" + minWeightPercent: 10 +``` + +Slow start mode works only with `RoundRobin` and `WeightedLeastRequest` [load balancing strategies][2]. +For more details see [Envoy documentation][1]. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/slow_start +[2]: api/#projectcontour.io/v1.LoadBalancerPolicy diff --git a/site/content/docs/1.30/config/tls-delegation.md b/site/content/docs/1.30/config/tls-delegation.md new file mode 100644 index 00000000000..155796fe7eb --- /dev/null +++ b/site/content/docs/1.30/config/tls-delegation.md @@ -0,0 +1,79 @@ +# TLS Certificate Delegation + +In order to support wildcard certificates, TLS certificates for a `*.somedomain.com`, which are stored in a namespace controlled by the cluster administrator, Contour supports a facility known as TLS Certificate Delegation. +This facility allows the owner of a TLS certificate to delegate, for the purposes of referencing the TLS certificate, permission to Contour to read the Secret object from another namespace. +Delegation works for both HTTPProxy and Ingress resources, however it needs an annotation to work with Ingress v1. + +If the `--watch-namespaces` configuration flag is used, it must define all namespaces that will be referenced by the delegation. + +The [`TLSCertificateDelegation`][1] resource defines a set of `delegations` in the `spec`. +Each delegation references a `secretName` from the namespace where the `TLSCertificateDelegation` is created as well as describing a set of `targetNamespaces` in which the certificate can be referenced. +If all namespaces should be able to reference the secret, then set `"*"` as the value of `targetNamespaces` (see example below). + +```yaml +apiVersion: projectcontour.io/v1 +kind: TLSCertificateDelegation +metadata: + name: example-com-wildcard + namespace: www-admin +spec: + delegations: + - secretName: example-com-wildcard + targetNamespaces: + - example-com + - secretName: another-com-wildcard + targetNamespaces: + - "*" +``` + +In this example, the permission for Contour to reference the Secret `example-com-wildcard` in the `www-admin` namespace has been delegated to HTTPProxy and Ingress objects in the `example-com` namespace. +Also, the permission for Contour to reference the Secret `another-com-wildcard` from all namespaces has been delegated to all HTTPProxy and Ingress objects in the cluster. + +To reference the secret from an HTTPProxy or Ingress v1beta1 you must use the slash syntax in the `secretName`: +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: www + namespace: example-com +spec: + virtualhost: + fqdn: foo2.bar.com + tls: + secretName: www-admin/example-com-wildcard + routes: + - services: + - name: s1 + port: 80 +``` + +To reference the secret from an Ingress v1 you must use the `projectcontour.io/tls-cert-namespace` annotation: +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + projectcontour.io/tls-cert-namespace: www-admin + name: www + namespace: example-com +spec: + rules: + - host: foo2.bar.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: s1 + port: + number: 80 + tls: + - hosts: + - foo2.bar.com + secretName: example-com-wildcard +``` + + +[0]: https://github.com/projectcontour/contour/issues/3544 +[1]: /docs/{{< param version >}}/config/api/#projectcontour.io/v1.TLSCertificateDelegation diff --git a/site/content/docs/1.30/config/tls-termination.md b/site/content/docs/1.30/config/tls-termination.md new file mode 100644 index 00000000000..d1b26dc2f4e --- /dev/null +++ b/site/content/docs/1.30/config/tls-termination.md @@ -0,0 +1,353 @@ +# TLS Termination + +HTTPProxy follows a similar pattern to Ingress for configuring TLS credentials. + +You can secure a HTTPProxy by specifying a Secret that contains TLS private key and certificate information. +If multiple HTTPProxies utilize the same Secret, the certificate must include the necessary Subject Authority Name (SAN) for each fqdn. + +Contour (via Envoy) requires that clients send the Server Name Indication (SNI) TLS extension so that requests can be routed to the correct virtual host. +Virtual hosts are strongly bound to SNI names. +This means that the Host header in HTTP requests must match the SNI name that was sent at the start of the TLS session. + +Contour also follows a "secure first" approach. +When TLS is enabled for a virtual host, any request to the insecure port is redirected to the secure interface with a 301 redirect. +Specific routes can be configured to override this behavior and handle insecure requests by enabling the `spec.routes.permitInsecure` parameter on a Route. + +The TLS secret must: +- be a Secret of type `kubernetes.io/tls`. This means that it must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS, in PEM format. + +The TLS secret may also: +- add any chain CA certificates required for validation into the `tls.crt` PEM bundle. If this is the case, the serving certificate must be the first certificate in the bundle and the intermediate CA certificates must be appended in issuing order. + +```yaml +# ingress-tls.secret.yaml +apiVersion: v1 +data: + tls.crt: base64 encoded cert + tls.key: base64 encoded key +kind: Secret +metadata: + name: testsecret + namespace: default +type: kubernetes.io/tls +``` + +The HTTPProxy can be configured to use this secret using `tls.secretName` property: + +```yaml +# httpproxy-tls.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: tls-example + namespace: default +spec: + virtualhost: + fqdn: foo2.bar.com + tls: + secretName: testsecret + routes: + - services: + - name: s1 + port: 80 +``` + +If the `tls.secretName` property contains a slash, eg. `somenamespace/somesecret` then, subject to TLS Certificate Delegation, the TLS certificate will be read from `somesecret` in `somenamespace`. +See TLS Certificate Delegation below for more information. + +The TLS **Minimum Protocol Version** a virtual host should negotiate can be specified by setting the `spec.virtualhost.tls.minimumProtocolVersion`: + +- 1.3 +- 1.2 (Default) + +## Fallback Certificate + +Contour provides virtual host based routing, so that any TLS request is routed to the appropriate service based on both the server name requested by the TLS client and the HOST header in the HTTP request. + +Since the HOST Header is encrypted during TLS handshake, it can’t be used for virtual host based routing unless the client sends HTTPS requests specifying hostname using the TLS server name, or the request is first decrypted using a default TLS certificate. + +Some legacy TLS clients do not send the server name, so Envoy does not know how to select the right certificate. A fallback certificate is needed for these clients. + +_**Note:** +The minimum TLS protocol version for any fallback request is defined by the `minimum TLS protocol version` set in the Contour configuration file. +Enabling the fallback certificate is not compatible with TLS client authentication._ + +### Fallback Certificate Configuration + +First define the `namespace/name` in the [Contour configuration file][1] of a Kubernetes secret which will be used as the fallback certificate. +Any HTTPProxy which enables fallback certificate delegation must have the fallback certificate delegated to the namespace in which the HTTPProxy object resides. + +To do that, configure `TLSCertificateDelegation` to delegate the fallback certificate to specific or all namespaces (e.g. `*`) which should be allowed to enable the fallback certificate. +Finally, for each root HTTPProxy, set the `Spec.TLS.enableFallbackCertificate` parameter to allow that HTTPProxy to opt-in to the fallback certificate routing. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: fallback-tls-example + namespace: defaultub +spec: + virtualhost: + fqdn: fallback.bar.com + tls: + secretName: testsecret + enableFallbackCertificate: true + routes: + - services: + - name: s1 + port: 80 +--- +apiVersion: projectcontour.io/v1 +kind: TLSCertificateDelegation +metadata: + name: fallback-delegation + namespace: www-admin +spec: + delegations: + - secretName: fallback-secret-name + targetNamespaces: + - "*" +``` + +## Permitting Insecure Requests + +A HTTPProxy can be configured to permit insecure requests to specific Routes. +In this example, any request to `foo2.bar.com/blog` will not receive a 301 redirect to HTTPS, but the `/` route will: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: tls-example-insecure + namespace: default +spec: + virtualhost: + fqdn: foo2.bar.com + tls: + secretName: testsecret + routes: + - services: + - name: s1 + port: 80 + - conditions: + - prefix: /blog + permitInsecure: true + services: + - name: s2 + port: 80 +``` + +## Client Certificate Validation + +It is possible to protect the backend service from unauthorized external clients by requiring the client to present a valid TLS certificate. +Envoy will validate the client certificate by verifying that it is not expired and that a chain of trust can be established to the configured trusted root CA certificate. +Only those requests with a valid client certificate will be accepted and forwarded to the backend service. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + routes: + - services: + - name: s1 + port: 80 +``` + +The preceding example enables validation by setting the optional `clientValidation` attribute. +Its mandatory attribute `caSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have only a data key named `ca.crt`. +The data value of the key `ca.crt` must be a PEM-encoded certificate bundle and it must contain all the trusted CA certificates that are to be used for validating the client certificate. +If the Opaque Secret also contains one of either `tls.crt` or `tls.key` keys, it will be ignored. + +By default, client certificates are required but some applications might support different authentication schemes. In that case you can set the `optionalClientCertificate` field to `true`. A client certificate will be requested, but the connection is allowed to continue if the client does not provide one. If a client certificate is sent, it will be verified according to the other properties, which includes disabling validations if `skipClientCertValidation` is set. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-optional-client-auth +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + optionalClientCertificate: true + routes: + - services: + - name: s1 + port: 80 +``` + +When using external authorization, it may be desirable to use an external authorization server to validate client certificates on requests, rather than the Envoy proxy. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth-and-ext-authz +spec: + virtualhost: + fqdn: www.example.com + authorization: + # external authorization server configuration + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + skipClientCertValidation: true + routes: + - services: + - name: s1 + port: 80 +``` + +In the above example, setting the `skipClientCertValidation` field to `true` will configure Envoy to require client certificates on requests and pass them along to a configured authorization server. +Failed validation of client certificates by Envoy will be ignored and the `fail_verify_error` [Listener statistic][2] incremented. +If the `caSecret` field is omitted, Envoy will request but not require client certificates to be present on requests. + +Optionally, you can enable certificate revocation check by providing one or more Certificate Revocation Lists (CRLs). +Attribute `crlSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have a data key named `crl.pem`. +The data value of the key `crl.pem` must be one or more PEM-encoded CRLs concatenated together. +Large CRL lists are not supported since individual Secrets are limited to 1MiB in size. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth-and-crl-check +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + crlSecret: client-crl + routes: + - services: + - name: s1 + port: 80 +``` + +CRLs must be available from all relevant CAs, including intermediate CAs. +Otherwise clients will be denied access, since the revocation status cannot be checked for the full certificate chain. +This behavior can be controlled by `crlOnlyVerifyLeafCert` field. +If the option is set to `true`, only the certificate at the end of the certificate chain will be subject to validation by CRL. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth-and-crl-check-only-leaf +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + crlSecret: client-crl + crlOnlyVerifyLeafCert: true + routes: + - services: + - name: s1 + port: 80 +``` + +## Client Certificate Details Forwarding + +HTTPProxy supports passing certificate data through the `x-forwarded-client-cert` header to let applications use details from client certificates (e.g. Subject, SAN...). Since the certificate (or the certificate chain) could exceed the web server header size limit, you have the ability to select what specific part of the certificate to expose in the header through the `forwardClientCertificate` field. Read more about the supported values in the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert). + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: with-client-auth +spec: + virtualhost: + fqdn: www.example.com + tls: + secretName: secret + clientValidation: + caSecret: client-root-ca + forwardClientCertificate: + subject: true + cert: true + chain: true + dns: true + uri: true + routes: + - services: + - name: s1 + port: 80 +``` + +## TLS Session Proxying + +HTTPProxy supports proxying of TLS encapsulated TCP sessions. + +_Note_: The TCP session must be encrypted with TLS. +This is necessary so that Envoy can use SNI to route the incoming request to the correct service. + +If `spec.virtualhost.tls.secretName` is present then that secret will be used to decrypt the TCP traffic at the edge. + +```yaml +# httpproxy-tls-termination.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example + namespace: default +spec: + virtualhost: + fqdn: tcp.example.com + tls: + secretName: secret + tcpproxy: + services: + - name: tcpservice + port: 8080 + - name: otherservice + port: 9999 + weight: 20 +``` + +The `spec.tcpproxy` key indicates that this _root_ HTTPProxy will forward the de-encrypted TCP traffic to the backend service. + +### TLS Session Passthrough + +If you wish to handle the TLS handshake at the backend service set `spec.virtualhost.tls.passthrough: true` indicates that once SNI demuxing is performed, the encrypted connection will be forwarded to the backend service. +The backend service is expected to have a key which matches the SNI header received at the edge, and be capable of completing the TLS handshake. This is called SSL/TLS Passthrough. + +```yaml +# httpproxy-tls-passthrough.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example + namespace: default +spec: + virtualhost: + fqdn: tcp.example.com + tls: + passthrough: true + tcpproxy: + services: + - name: tcpservice + port: 8080 + - name: otherservice + port: 9999 + weight: 20 +``` + +[1]: ../configuration#fallback-certificate +[2]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/stats#tls-statistics diff --git a/site/content/docs/1.30/config/tracing.md b/site/content/docs/1.30/config/tracing.md new file mode 100644 index 00000000000..5500c26d547 --- /dev/null +++ b/site/content/docs/1.30/config/tracing.md @@ -0,0 +1,117 @@ +# Tracing Support + +- [Overview](#overview) +- [Tracing-config](#tracing-config) + +## Overview + +Envoy has rich support for [distributed tracing][1],and supports exporting data to third-party providers (Zipkin, Jaeger, Datadog, etc.) + +[OpenTelemetry][2] is a CNCF project which is working to become a standard in the space. It was formed as a merger of the OpenTracing and OpenCensus projects. + +Contour supports configuring envoy to export data to OpenTelemetry, and allows users to customize some configurations. + +- Custom service name, the default is `contour`. +- Custom sampling rate, the default is `100`. +- Custom the maximum length of the request path, the default is `256`. +- Customize span tags from literal or request headers. +- Customize whether to include the pod's hostname and namespace. + +## Tracing-config + +In order to use this feature, you must first select and deploy an opentelemetry-collector to receive the tracing data exported by envoy. + +First we should deploy an opentelemetry-collector to receive the tracing data exported by envoy +```bash +# install operator +kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml +``` + +Install an otel collector instance, with verbose logging exporter enabled: +```shell +kubectl apply -f - </`. If the CA secret's namespace is not the same namespace as the `HTTPProxy` resource, [TLS Certificate Delegation][4] must be used to allow the owner of the CA certificate secret to delegate, for the purposes of referencing the CA certificate in a different namespace, permission to Contour to read the Secret object from another namespace. + +_**Note:** +If `spec.routes.services[].validation` is present, `spec.routes.services[].{name,port}` must point to a Service with a matching `projectcontour.io/upstream-protocol.tls` Service annotation._ + +In the example below, the upstream service is named `secure-backend` and uses port `8443`: + +```yaml +# httpproxy-example.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: example +spec: + virtualhost: + fqdn: www.example.com + routes: + - services: + - name: secure-backend + port: 8443 + validation: + caSecret: my-certificate-authority + subjectName: backend.example.com +``` + +```yaml +# service-secure-backend.yaml +apiVersion: v1 +kind: Service +metadata: + name: secure-backend + annotations: + projectcontour.io/upstream-protocol.tls: "8443" +spec: + ports: + - name: https + port: 8443 + selector: + app: secure-backend + +``` + +If the `validation` spec is defined on a service, but the secret which it references does not exist, Contour will reject the update and set the status of the HTTPProxy object accordingly. +This helps prevent the case of proxying to an upstream where validation is requested, but not yet available. + +```yaml +Status: + Current Status: invalid + Description: route "/": service "tls-nginx": upstreamValidation requested but secret not found or misconfigured +``` + +## Upstream Validation + +When defining upstream services on a route, it's possible to configure the connection from Envoy to the backend endpoint to communicate over TLS. + +A CA certificate and a Subject Name must be provided, which are both used to verify the backend endpoint's identity. + +If specifying multiple Subject Names, `SubjectNames` and `SubjectName` must be configured such that `SubjectNames[0] == SubjectName`. + +The CA certificate bundle for the backend service should be supplied in a Kubernetes Secret. +The referenced Secret must be of type "Opaque" and have a data key named `ca.crt`. +This data value must be a PEM-encoded certificate bundle. + +In addition to the CA certificate and the subject name, the Kubernetes service must also be annotated with a Contour specific annotation: `projectcontour.io/upstream-protocol.tls: ` ([see annotations section][1]). + +_**Note:** This annotation is applied to the Service not the Ingress or HTTPProxy object._ + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: blog + namespace: marketing +spec: + routes: + - services: + - name: s2 + port: 80 + validation: + caSecret: foo-ca-cert + subjectName: foo.marketing + subjectNames: + - foo.marketing + - bar.marketing +``` + +## Envoy Client Certificate + +Contour can be configured with a `namespace/name` in the [Contour configuration file][3] of a Kubernetes secret which Envoy uses as a client certificate when upstream TLS is configured for the backend. +Envoy will send the certificate during TLS handshake when the backend applications request the client to present its certificate. +Backend applications can validate the certificate to ensure that the connection is coming from Envoy. + +[1]: annotations.md +[2]: api/#projectcontour.io/v1.Service +[3]: ../configuration#fallback-certificate +[4]: tls-delegation.md diff --git a/site/content/docs/1.30/config/virtual-hosts.md b/site/content/docs/1.30/config/virtual-hosts.md new file mode 100644 index 00000000000..b7a138dde6b --- /dev/null +++ b/site/content/docs/1.30/config/virtual-hosts.md @@ -0,0 +1,138 @@ +# Virtual Hosts + + +Similar to Ingress, HTTPProxy support name-based virtual hosting. +Name-based virtual hosts use multiple host names with the same IP address. + +``` +foo.bar.com --| |-> foo.bar.com s1:80 + | 178.91.123.132 | +bar.foo.com --| |-> bar.foo.com s2:80 +``` + +Unlike Ingress however, HTTPProxy only support a single root domain per HTTPProxy object. +As an example, this Ingress object: + +```yaml +# ingress-name.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: name-example +spec: + rules: + - host: foo1.bar.com + http: + paths: + - backend: + service: + name: s1 + port: + number: 80 + pathType: Prefix + - host: bar1.bar.com + http: + paths: + - backend: + service: + name: s2 + port: + number: 80 + pathType: Prefix +``` + +must be represented by two different HTTPProxy objects: + +```yaml +# httpproxy-name.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: name-example-foo + namespace: default +spec: + virtualhost: + fqdn: foo1.bar.com + routes: + - services: + - name: s1 + port: 80 +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: name-example-bar + namespace: default +spec: + virtualhost: + fqdn: bar1.bar.com + routes: + - services: + - name: s2 + port: 80 +``` + +A HTTPProxy object that contains a [`virtualhost`][2] field is known as a "root proxy". + +## Virtualhost aliases + +To present the same set of routes under multiple DNS entries (e.g. `www.example.com` and `example.com`), including a service with a `prefix` condition of `/` can be used. + +```yaml +# httpproxy-inclusion-multipleroots.yaml +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-root + namespace: default +spec: + virtualhost: + fqdn: bar.com + includes: + - name: main + namespace: default +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: multiple-root-www + namespace: default +spec: + virtualhost: + fqdn: www.bar.com + includes: + - name: main + namespace: default +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: main + namespace: default +spec: + routes: + - services: + - name: s2 + port: 80 +``` + +## Restricted root namespaces + +HTTPProxy inclusion allows Administrators to limit which users/namespaces may configure routes for a given domain, but it does not restrict where root HTTPProxies may be created. +Contour has an enforcing mode which accepts a list of namespaces where root HTTPProxy are valid. +Only users permitted to operate in those namespaces can therefore create HTTPProxy with the [`virtualhost`] field ([see API docs][2]). + +This restricted mode is enabled in Contour by specifying a command line flag, `--root-namespaces`, which will restrict Contour to only searching the defined namespaces for root HTTPProxy. This CLI flag accepts a comma separated list of namespaces where HTTPProxy are valid (e.g. `--root-namespaces=default,kube-system,my-admin-namespace`). + +HTTPProxy with a defined [virtualhost][2] field that are not in one of the allowed root namespaces will be flagged as `invalid` and will be ignored by Contour. + +Additionally, when defined, Contour will only watch for Kubernetes secrets in these namespaces ignoring changes in all other namespaces. +Proper RBAC rules should also be created to restrict what namespaces Contour has access matching the namespaces passed to the command line flag. +An example of this is included in the [examples directory][1] and shows how you might create a namespace called `root-httproxy`. + +_**Note:** The restricted root namespace feature is only supported for HTTPProxy CRDs. +`--root-namespaces` does not affect the operation of Ingress objects. In order to limit other resources, see the `--watch-namespaces` configuration flag._ + +[1]: {{< param github_url>}}/tree/{{< param branch >}}/examples/root-rbac +[2]: api/#projectcontour.io/v1.VirtualHost diff --git a/site/content/docs/1.30/config/websockets.md b/site/content/docs/1.30/config/websockets.md new file mode 100644 index 00000000000..136c0468378 --- /dev/null +++ b/site/content/docs/1.30/config/websockets.md @@ -0,0 +1,27 @@ +# Websockets + +WebSocket support can be enabled on specific routes using the `enableWebsockets` field: + +```yaml +# httpproxy-websockets.yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: chat + namespace: default +spec: + virtualhost: + fqdn: chat.example.com + routes: + - services: + - name: chat-app + port: 80 + - conditions: + - prefix: /websocket + enableWebsockets: true # Setting this to true enables websocket for all paths that match /websocket + services: + - name: chat-app + port: 80 +``` + +If you are using Gateway API, websockets are enabled by default at the Listener level. diff --git a/site/content/docs/1.30/configuration.md b/site/content/docs/1.30/configuration.md new file mode 100644 index 00000000000..5277ab79e38 --- /dev/null +++ b/site/content/docs/1.30/configuration.md @@ -0,0 +1,541 @@ +# Contour Configuration Reference + +- [Serve Flags](#serve-flags) +- [Configuration File](#configuration-file) +- [Environment Variables](#environment-variables) +- [Bootstrap Config File](#bootstrap-config-file) + +## Overview + +There are various ways to configure Contour, flags, the configuration file, as well as environment variables. +Contour has a precedence of configuration for contour serve, meaning anything configured in the config file is overridden by environment vars which are overridden by cli flags. + +## Serve Flags + +The `contour serve` command is the main command which is used to watch for Kubernetes resource and process them into Envoy configuration which is then streamed to any Envoy via its xDS gRPC connection. +There are a number of flags that can be passed to this command which further configures how Contour operates. +Many of these flags are mirrored in the [Contour Configuration File](#configuration-file). + +| Flag Name | Description | +| --------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| `--config-path` | Path to base configuration | +| `--contour-config-name` | Name of the ContourConfiguration resource to use | +| `--incluster` | Use in cluster configuration | +| `--kubeconfig=` | Path to kubeconfig (if not in running inside a cluster) | +| `--xds-address=` | xDS gRPC API address | +| `--xds-port=` | xDS gRPC API port | +| `--stats-address=` | Envoy /stats interface address | +| `--stats-port=` | Envoy /stats interface port | +| `--debug-http-address=
` | Address the debug http endpoint will bind to. | +| `--debug-http-port=` | Port the debug http endpoint will bind to | +| `--http-address=` | Address the metrics HTTP endpoint will bind to | +| `--http-port=` | Port the metrics HTTP endpoint will bind to. | +| `--health-address=` | Address the health HTTP endpoint will bind to | +| `--health-port=` | Port the health HTTP endpoint will bind to | +| `--contour-cafile=` | CA bundle file name for serving gRPC with TLS | +| `--contour-cert-file=` | Contour certificate file name for serving gRPC over TLS | +| `--contour-key-file=` | Contour key file name for serving gRPC over TLS | +| `--insecure` | Allow serving without TLS secured gRPC | +| `--root-namespaces=` | Restrict contour to searching these namespaces for root ingress routes | +| `--watch-namespaces=` | Restrict contour to searching these namespaces for all resources | +| `--ingress-class-name=` | Contour IngressClass name (comma-separated list allowed) | +| `--ingress-status-address=
` | Address to set in Ingress object status | +| `--envoy-http-access-log=` | Envoy HTTP access log | +| `--envoy-https-access-log=` | Envoy HTTPS access log | +| `--envoy-service-http-address=` | Kubernetes Service address for HTTP requests | +| `--envoy-service-https-address=` | Kubernetes Service address for HTTPS requests | +| `--envoy-service-http-port=` | Kubernetes Service port for HTTP requests | +| `--envoy-service-https-port=` | Kubernetes Service port for HTTPS requests | +| `--envoy-service-name=` | Name of the Envoy service to inspect for Ingress status details. | +| `--envoy-service-namespace=` | Envoy Service Namespace | +| `--use-proxy-protocol` | Use PROXY protocol for all listeners | +| `--accesslog-format=` | Format for Envoy access logs | +| `--disable-leader-election` | Disable leader election mechanism | +| `--disable-feature=` | Do not start an informer for the specified resources. Flag can be given multiple times. | +| `--leader-election-lease-duration` | The duration of the leadership lease. | +| `--leader-election-renew-deadline` | The duration leader will retry refreshing leadership before giving up. | +| `--leader-election-retry-period` | The interval which Contour will attempt to acquire leadership lease. | +| `--leader-election-resource-name` | The name of the resource (Lease) leader election will lease. | +| `--leader-election-resource-namespace` | The namespace of the resource (Lease) leader election will lease. | +| `-d, --debug` | Enable debug logging | +| `--kubernetes-debug=` | Enable Kubernetes client debug logging | +| `--log-format=` | Log output format for Contour. Either text (default) or json. | +| `--kubernetes-client-qps=` | QPS allowed for the Kubernetes client. | +| `--kubernetes-client-burst=` | Burst allowed for the Kubernetes client. | + +## Configuration File + +A configuration file can be passed to the `--config-path` argument of the `contour serve` command to specify additional configuration to Contour. +In most deployments, this file is passed to Contour via a ConfigMap which is mounted as a volume to the Contour pod. + +The Contour configuration file is optional. +In its absence, Contour will operate with reasonable defaults. +Where Contour settings can also be specified with command-line flags, the command-line value takes precedence over the configuration file. + +| Field Name | Type | Default | Description | +|---------------------------| ---------------------- |------------------------------------------------------------------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. | +| accesslog-format-string | string | None | If present, this specifies custom access log format for Envoy. See [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage) for more information about the syntax. This field only has effect if `accesslog-format` is `envoy` | +| accesslog-level | string | `info` | This field specifies the verbosity level of the access log. Valid options are `info` (default, all requests are logged), `error` (all non-success, i.e. 300+ response code, requests are logged), `critical` (all server error, i.e. 500+ response code, requests are logged) and `disabled`. | +| debug | boolean | `false` | Enables debug logging. | +| default-http-versions | string array | HTTP/1.1
HTTP/2 | This array specifies the HTTP versions that Contour should program Envoy to serve. HTTP versions are specified as strings of the form "HTTP/x", where "x" represents the version number. | +| disableAllowChunkedLength | boolean | `false` | If this field is true, Contour will disable the RFC-compliant Envoy behavior to strip the `Content-Length` header if `Transfer-Encoding: chunked` is also set. This is an emergency off-switch to revert back to Envoy's default behavior in case of failures. +| disableMergeSlashes | boolean | `false` | This field disables Envoy's non-standard merge_slashes path transformation behavior that strips duplicate slashes from request URL paths. +| serverHeaderTransformation | string | `overwrite` | This field defines the action to be applied to the Server header on the response path. Values: `overwrite` (default), `append_if_absent`, `pass_through` +| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. | +| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. | +| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. If the `CONTOUR_NAMESPACE` environment variable is present, Contour will populate this field with its value. | +| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`. | +| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. | +| json-fields | string array | [fields][5] | This is the list the field names to include in the JSON [access log format][2]. This field only has effect if `accesslog-format` is `json`. | +| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. | +| kubernetesClientQPS | float32 | | QPS allowed for the Kubernetes client. | +| kubernetesClientBurst | int | | Burst allowed for the Kubernetes client. | +| policy | PolicyConfig | | The default [policy configuration](#policy-configuration). | +| tls | TLS | | The default [TLS configuration](#tls-configuration). | +| timeouts | TimeoutConfig | | The [timeout configuration](#timeout-configuration). | +| cluster | ClusterConfig | | The [cluster configuration](#cluster-configuration). | +| network | NetworkConfig | | The [network configuration](#network-configuration). | +| listener | ListenerConfig | | The [listener configuration](#listener-configuration). | +| server | ServerConfig | | The [server configuration](#server-configuration) for `contour serve` command. | +| gateway | GatewayConfig | | The [gateway-api Gateway configuration](#gateway-configuration). | +| rateLimitService | RateLimitServiceConfig | | The [rate limit service configuration](#rate-limit-service-configuration). | +| enableExternalNameService | boolean | `false` | Enable ExternalName Service processing. Enabling this has security implications. Please see the [advisory](https://github.com/projectcontour/contour/security/advisories/GHSA-5ph6-qq5x-7jwc) for more details. | +| metrics | MetricsParameters | | The [metrics configuration](#metrics-configuration) | +| featureFlags | string array | `[]` | Defines the toggle to enable new contour features. Available toggles are:
1. `useEndpointSlices` - configures contour to fetch endpoint data from k8s endpoint slices. | + +### TLS Configuration + +The TLS configuration block can be used to configure default values for how +Contour should provision TLS hosts. + +| Field Name | Type | Default | Description | +| ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| minimum-protocol-version | string | `1.2` | This field specifies the minimum TLS protocol version that is allowed. Valid options are `1.2` (default) and `1.3`. Any other value defaults to TLS 1.2. +| maximum-protocol-version | string | `1.3` | This field specifies the maximum TLS protocol version that is allowed. Valid options are `1.2` and `1.3`. Any other value defaults to TLS 1.3. | +| fallback-certificate | | | [Fallback certificate configuration](#fallback-certificate). | +| envoy-client-certificate | | | [Client certificate configuration for Envoy](#envoy-client-certificate). | +| cipher-suites | []string | See [config package documentation](https://pkg.go.dev/github.com/projectcontour/contour/pkg/config#pkg-variables) | This field specifies the TLS ciphers to be supported by TLS listeners when negotiating TLS 1.2. This parameter should only be used by advanced users. Note that this is ignored when TLS 1.3 is in use. The set of ciphers that are allowed is a superset of those supported by default in stock, non-FIPS Envoy builds and FIPS builds as specified [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlsparameters-cipher-suites). Custom ciphers not accepted by Envoy in a standard build are not supported. | + +### Upstream TLS Configuration + +The Upstream TLS configuration block can be used to configure default values for how Contour establishes TLS for upstream connections. + +| Field Name | Type | Default | Description | +| ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| minimum-protocol-version | string | `1.2` | This field specifies the minimum TLS protocol version that is allowed. Valid options are `1.2` (default) and `1.3`. Any other value defaults to TLS 1.2. | +| maximum-protocol-version | string | `1.3` | This field specifies the maximum TLS protocol version that is allowed. Valid options are `1.2` and `1.3`. Any other value defaults to TLS 1.3. | +| cipher-suites | []string | See [config package documentation](https://pkg.go.dev/github.com/projectcontour/contour/pkg/config#pkg-variables) | This field specifies the TLS ciphers to be supported by TLS listeners when negotiating TLS 1.2. This parameter should only be used by advanced users. Note that this is ignored when TLS 1.3 is in use. The set of ciphers that are allowed is a superset of those supported by default in stock, non-FIPS Envoy builds and FIPS builds as specified [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlsparameters-cipher-suites). Custom ciphers not accepted by Envoy in a standard build are not supported. | + +### Fallback Certificate + +| Field Name | Type | Default | Description | +| ---------- | ------ | ------- | ----------------------------------------------------------------------------------------------- | +| name | string | `""` | This field specifies the name of the Kubernetes secret to use as the fallback certificate. | +| namespace | string | `""` | This field specifies the namespace of the Kubernetes secret to use as the fallback certificate. | + + +### Envoy Client Certificate + +| Field Name | Type | Default | Description | +| ---------- | ------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| name | string | `""` | This field specifies the name of the Kubernetes secret to use as the client certificate and private key when establishing TLS connections to the backend service. | +| namespace | string | `""` | This field specifies the namespace of the Kubernetes secret to use as the client certificate and private key when establishing TLS connections to the backend service. | + + +### Timeout Configuration + +The timeout configuration block can be used to configure various timeouts for the proxies. All fields are optional; Contour/Envoy defaults apply if a field is not specified. + +| Field Name | Type | Default | Description | +| -------------------------------- | ------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| request-timeout | string | none* | This field specifies the default request timeout. Note that this is a timeout for the entire request, not an idle timeout. Must be a [valid Go duration string][4], or omitted or set to `infinity` to disable the timeout entirely. See [the Envoy documentation][12] for more information.

_Note: A value of `0s` previously disabled this timeout entirely. This is no longer the case. Use `infinity` or omit this field to disable the timeout._ | +| connection-idle-timeout | string | `60s` | This field defines how long the proxy should wait while there are no active requests (for HTTP/1.1) or streams (for HTTP/2) before terminating an HTTP connection. The timeout applies to downstream connections only. Must be a [valid Go duration string][4], or `infinity` to disable the timeout entirely. See [the Envoy documentation][8] for more information. | +| stream-idle-timeout | string | `5m`* | This field defines how long the proxy should wait while there is no activity during single request/response (for HTTP/1.1) or stream (for HTTP/2). Timeout will not trigger while HTTP/1.1 connection is idle between two consecutive requests. Must be a [valid Go duration string][4], or `infinity` to disable the timeout entirely. See [the Envoy documentation][9] for more information. | +| max-connection-duration | string | none* | This field defines the maximum period of time after an HTTP connection has been established from the client to the proxy before it is closed by the proxy, regardless of whether there has been activity or not. Must be a [valid Go duration string][4], or omitted or set to `infinity` for no max duration. See [the Envoy documentation][10] for more information. | +| delayed-close-timeout | string | `1s`* | *Note: this is an advanced setting that should not normally need to be tuned.*

This field defines how long envoy will wait, once connection close processing has been initiated, for the downstream peer to close the connection before Envoy closes the socket associated with the connection. Setting this timeout to 'infinity' will disable it. See [the Envoy documentation][13] for more information. | +| connection-shutdown-grace-period | string | `5s`* | This field defines how long the proxy will wait between sending an initial GOAWAY frame and a second, final GOAWAY frame when terminating an HTTP/2 connection. During this grace period, the proxy will continue to respond to new streams. After the final GOAWAY frame has been sent, the proxy will refuse new streams. Must be a [valid Go duration string][4]. See [the Envoy documentation][11] for more information. | +| connect-timeout | string | `2s` | This field defines how long the proxy will wait for the upstream connection to be established. + +_This is Envoy's default setting value and is not explicitly configured by Contour._ + +### Cluster Configuration + +The cluster configuration block can be used to configure various parameters for Envoy clusters. + +| Field Name | Type | Default | Description | +|-----------------------------------|--------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| dns-lookup-family | string | auto | This field specifies the dns-lookup-family to use for upstream requests to externalName type Kubernetes services from an HTTPProxy route. Values are: `auto`, `v4`, `v6`, `all` | +| max-requests-per-connection | int | none | This field specifies the maximum requests for upstream connections. If not specified, there is no limit | +| circuit-breakers | [CircuitBreakers](#circuit-breakers) | none | This field specifies the default value for [circuit-breaker-annotations](https://projectcontour.io/docs/main/config/annotations/) for services that don't specify them. | +| per-connection-buffer-limit-bytes | int | 1MiB* | This field specifies the soft limit on size of the cluster’s new connection read and write buffer. If not specified, Envoy defaults of 1MiB apply | +| upstream-tls | UpstreamTLS | | [Upstream TLS configuration](#upstream-tls) | + +_This is Envoy's default setting value and is not explicitly configured by Contour._ + + + + +### Network Configuration + +The network configuration block can be used to configure various parameters network connections. + +| Field Name | Type | Default | Description | +| ---------------- | ---- | ------- | ----------------------------------------------------------------------------------------------------------------------- | +| num-trusted-hops | int | 0 | Configures the number of additional ingress proxy hops from the right side of the x-forwarded-for HTTP header to trust. | +| admin-port | int | 9001 | Configures the Envoy Admin read-only listener on Envoy. Set to `0` to disable. | + +### Listener Configuration + +The listener configuration block can be used to configure various parameters for Envoy listener. + +| Field Name | Type | Default | Description | +|-----------------------------------|--------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| connection-balancer | string | `""` | This field specifies the listener connection balancer. If the value is `exact`, the listener will use the exact connection balancer to balance connections between threads in a single Envoy process. See [the Envoy documentation][14] for more information. | +| max-requests-per-connection | int | none | This field specifies the maximum requests for downstream connections. If not specified, there is no limit | +| per-connection-buffer-limit-bytes | int | 1MiB* | This field specifies the soft limit on size of the listener’s new connection read and write buffer. If not specified, Envoy defaults of 1MiB apply | +| socket-options | SocketOptions | | The [Socket Options](#socket-options) for Envoy listeners. | +| max-requests-per-io-cycle | int | none | Defines the limit on number of HTTP requests that Envoy will process from a single connection in a single I/O cycle. Requests over this limit are processed in subsequent I/O cycles. Can be used as a mitigation for CVE-2023-44487 when abusive traffic is detected. Configures the `http.max_requests_per_io_cycle` Envoy runtime setting. The default value when this is not set is no limit. | +| http2-max-concurrent-streams | int | none | Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS Envoy will advertise in the SETTINGS frame in HTTP/2 connections and the limit for concurrent streams allowed for a peer on a single HTTP/2 connection. It is recommended to not set this lower than 100 but this field can be used to bound resource usage by HTTP/2 connections and mitigate attacks like CVE-2023-44487. The default value when this is not set is unlimited. | + +_This is Envoy's default setting value and is not explicitly configured by Contour._ + +### Server Configuration + +The server configuration block can be used to configure various settings for the `contour serve` command. + +| Field Name | Type | Default | Description | +| --------------- | ------ | ------- | ----------------------------------------------------------------------------- | +| xds-server-type | string | envoy | This field specifies the xDS Server to use. Options are `envoy` or `contour` (deprecated). **This field is deprecated** and will be removed in a future release when the `contour` xDS server implementation is removed. | + +### Gateway Configuration + +The gateway configuration block is used to configure which gateway-api Gateway Contour should configure: + +| Field Name | Type | Default | Description | +| -------------- | -------------- | ------- | ------------------------------------------------------------------------------ | +| gatewayRef | NamespacedName | | [Gateway namespace and name](#gateway-ref). | + +### Gateway Ref + +| Field Name | Type | Default | Description | +| ---------- | ------ | ------- | ----------------------------------------------------------------------------------------------- | +| name | string | `""` | This field specifies the name of the specific Gateway to reconcile. | +| namespace | string | `""` | This field specifies the namespace of the specific Gateway to reconcile. | + +### Policy Configuration + +The Policy configuration block can be used to configure default policy values +that are set if not overridden by the user. + +The `request-headers` field is used to rewrite headers on a HTTP request, and +the `response-headers` field is used to rewrite headers on a HTTP response. + +| Field Name | Type | Default | Description | +| ---------------- | ------------ | ------- | ------------------------------------------------------------------------------------------------- | +| request-headers | HeaderPolicy | none | The default request headers set or removed on all service routes if not overridden in the object | +| response-headers | HeaderPolicy | none | The default response headers set or removed on all service routes if not overridden in the object | +| applyToIngress | Boolean | false | Whether the global policy should apply to Ingress objects | + +#### HeaderPolicy + +The `set` field sets an HTTP header value, creating it if it doesn't already exist but not overwriting it if it does. +The `remove` field removes an HTTP header. + +| Field Name | Type | Default | Description | +| ---------- | ----------------- | ------- | ------------------------------------------------------------------------------- | +| set | map[string]string | none | Map of headers to set on all service routes if not overridden in the object | +| remove | []string | none | List of headers to remove on all service routes if not overridden in the object | + +Note: the values of entries in the `set` and `remove` fields can be overridden in HTTPProxy objects but it is not possible to remove these entries. + +### Rate Limit Service Configuration + +The rate limit service configuration block is used to configure an optional global rate limit service: + +| Field Name | Type | Default | Description | +|-----------------------------| ------ | ------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| extensionService | string | | This field identifies the extension service defining the rate limit service, formatted as /. | +| domain | string | contour | This field defines the rate limit domain value to pass to the rate limit service. Acts as a container for a set of rate limit definitions within the RLS. | +| failOpen | bool | false | This field defines whether to allow requests to proceed when the rate limit service fails to respond with a valid rate limit decision within the timeout defined on the extension service. | +| enableXRateLimitHeaders | bool | false | This field defines whether to include the X-RateLimit headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (as defined by the IETF Internet-Draft https://tools.ietf.org/id/draft-polli-ratelimit-headers-03.html), on responses to clients when the Rate Limit Service is consulted for a request. | +| enableResourceExhaustedCode | bool | false | This field defines whether to translate status code 429 to gRPC RESOURCE_EXHAUSTED instead of UNAVAILABLE. | + +### Metrics Configuration + +MetricsParameters holds configurable parameters for Contour and Envoy metrics. + +| Field Name | Type | Default | Description | +| ----------- | ----------------------- | ------- | -------------------------------------------------------------------- | +| contour | MetricsServerParameters | | [Metrics Server Parameters](#metrics-server-parameters) for Contour. | +| envoy | MetricsServerParameters | | [Metrics Server Parameters](#metrics-server-parameters) for Envoy. | + +### Metrics Server Parameters + +MetricsServerParameters holds configurable parameters for Contour and Envoy metrics. +Metrics are served over HTTPS if `server-certificate-path` and `server-key-path` are set. +Metrics and health endpoints cannot have the same port number when metrics are served over HTTPS. + +| Field Name | Type | Default | Description | +| ----------------------- | ------ | ---------------------------- | -----------------------------------------------------------------------------| +| address | string | 0.0.0.0 | Address that metrics server will bind to. | +| port | int | 8000 (Contour), 8002 (Envoy) | Port that metrics server will bind to. | +| server-certificate-path | string | none | Optional path to the server certificate file. | +| server-key-path | string | none | Optional path to the server private key file. | +| ca-certificate-path | string | none | Optional path to the CA certificate file used to verify client certificates. | + +### Socket Options + +| Field Name | Type | Default | Description | +| --------------- | ------ | ------- | ----------------------------------------------------------------------------- | +| tos | int | 0 | Defines the value for IPv4 TOS field (including 6 bit DSCP field) for IP packets originating from Envoy listeners. Single value is applied to all listeners. The value must be in the range 0-255, 0 means socket option is not set. If listeners are bound to IPv6-only addresses, setting this option will cause an error. | +| traffic-class | int | 0 | Defines the value for IPv6 Traffic Class field (including 6 bit DSCP field) for IP packets originating from the Envoy listeners. Single value is applied to all listeners. The value must be in the range 0-255, 0 means socket option is not set. If listeners are bound to IPv4-only addresses, setting this option will cause an error. | + + +### Circuit Breakers + +| Field Name | Type | Default | Description | +| --------------- | ------ | ------- | ----------------------------------------------------------------------------- | +| max-connections | int | 0 | The maximum number of connections that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. | +| max-pending-requests | int | 0 | The maximum number of pending requests that a single Envoy instance allows to the Kubernetes Service; defaults to 1024. | +| max-requests | int | 0 | The maximum parallel requests a single Envoy instance allows to the Kubernetes Service; defaults to 1024 | +| max-retries | int | 0 | The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3. This setting only makes sense if the cluster is configured to do retries.| + +### Configuration Example + +The following is an example ConfigMap with configuration file included: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: contour + namespace: projectcontour +data: + contour.yaml: | + # + # server: + # determine which XDS Server implementation to utilize in Contour. + # xds-server-type: envoy + # + # specify the gateway-api Gateway Contour should configure + # gateway: + # namespace: projectcontour + # name: contour + # + # should contour expect to be running inside a k8s cluster + # incluster: true + # + # path to kubeconfig (if not running inside a k8s cluster) + # kubeconfig: /path/to/.kube/config + # + # Disable RFC-compliant behavior to strip "Content-Length" header if + # "Tranfer-Encoding: chunked" is also set. + # disableAllowChunkedLength: false + # Disable HTTPProxy permitInsecure field + disablePermitInsecure: false + tls: + # minimum TLS version that Contour will negotiate + # minimum-protocol-version: "1.2" + # TLS ciphers to be supported by Envoy TLS listeners when negotiating + # TLS 1.2. + # cipher-suites: + # - '[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' + # Defines the Kubernetes name/namespace matching a secret to use + # as the fallback certificate when requests which don't match the + # SNI defined for a vhost. + fallback-certificate: + # name: fallback-secret-name + # namespace: projectcontour + envoy-client-certificate: + # name: envoy-client-cert-secret-name + # namespace: projectcontour + ### Logging options + # Default setting + accesslog-format: envoy + # The default access log format is defined by Envoy but it can be customized by setting following variable. + # accesslog-format-string: "...\n" + # To enable JSON logging in Envoy + # accesslog-format: json + # accesslog-level: info + # The default fields that will be logged are specified below. + # To customise this list, just add or remove entries. + # The canonical list is available at + # https://godoc.org/github.com/projectcontour/contour/internal/envoy#JSONFields + # json-fields: + # - "@timestamp" + # - "authority" + # - "bytes_received" + # - "bytes_sent" + # - "downstream_local_address" + # - "downstream_remote_address" + # - "duration" + # - "method" + # - "path" + # - "protocol" + # - "request_id" + # - "requested_server_name" + # - "response_code" + # - "response_flags" + # - "uber_trace_id" + # - "upstream_cluster" + # - "upstream_host" + # - "upstream_local_address" + # - "upstream_service_time" + # - "user_agent" + # - "x_forwarded_for" + # + # default-http-versions: + # - "HTTP/2" + # - "HTTP/1.1" + # + # The following shows the default proxy timeout settings. + # timeouts: + # request-timeout: infinity + # connection-idle-timeout: 60s + # stream-idle-timeout: 5m + # max-connection-duration: infinity + # connection-shutdown-grace-period: 5s + # + # Envoy cluster settings. + # cluster: + # configure the cluster dns lookup family + # valid options are: auto (default), v4, v6, all + # dns-lookup-family: auto + # the maximum requests for upstream connections. + # If not specified, there is no limit. + # Setting this parameter to 1 will effectively disable keep alive + # max-requests-per-connection: 0 + # the soft limit on size of the cluster’s new connection read and write buffers + # per-connection-buffer-limit-bytes: 32768 + # + # network: + # Configure the number of additional ingress proxy hops from the + # right side of the x-forwarded-for HTTP header to trust. + # num-trusted-hops: 0 + # Configure the port used to access the Envoy Admin interface. + # admin-port: 9001 + # + # Configure an optional global rate limit service. + # rateLimitService: + # Identifies the extension service defining the rate limit service, + # formatted as /. + # extensionService: projectcontour/ratelimit + # Defines the rate limit domain to pass to the rate limit service. + # Acts as a container for a set of rate limit definitions within + # the RLS. + # domain: contour + # Defines whether to allow requests to proceed when the rate limit + # service fails to respond with a valid rate limit decision within + # the timeout defined on the extension service. + # failOpen: false + # Defines whether to include the X-RateLimit headers X-RateLimit-Limit, + # X-RateLimit-Remaining, and X-RateLimit-Reset (as defined by the IETF + # Internet-Draft linked below), on responses to clients when the Rate + # Limit Service is consulted for a request. + # ref. https://tools.ietf.org/id/draft-polli-ratelimit-headers-03.html + # enableXRateLimitHeaders: false + # Defines whether to translate status code 429 to grpc code RESOURCE_EXHAUSTED + # instead of the default UNAVAILABLE + # enableResourceExhaustedCode: false + # + # Global Policy settings. + # policy: + # # Default headers to set on all requests (unless set/removed on the HTTPProxy object itself) + # request-headers: + # set: + # # example: the hostname of the Envoy instance that proxied the request + # X-Envoy-Hostname: %HOSTNAME% + # # example: add a l5d-dst-override header to instruct Linkerd what service the request is destined for + # l5d-dst-override: %CONTOUR_SERVICE_NAME%.%CONTOUR_NAMESPACE%.svc.cluster.local:%CONTOUR_SERVICE_PORT% + # # default headers to set on all responses (unless set/removed on the HTTPProxy object itself) + # response-headers: + # set: + # # example: Envoy flags that provide additional details about the response or connection + # X-Envoy-Response-Flags: %RESPONSE_FLAGS% + # Whether or not the policy settings should apply to ingress objects + # applyToIngress: true + # + # metrics: + # contour: + # address: 0.0.0.0 + # port: 8000 + # server-certificate-path: /path/to/server-cert.pem + # server-key-path: /path/to/server-private-key.pem + # ca-certificate-path: /path/to/root-ca-for-client-validation.pem + # envoy: + # address: 0.0.0.0 + # port: 8002 + # server-certificate-path: /path/to/server-cert.pem + # server-key-path: /path/to/server-private-key.pem + # ca-certificate-path: /path/to/root-ca-for-client-validation.pem + # + # listener: + # connection-balancer: exact + # socket-options: + # tos: 64 + # traffic-class: 64 +``` + +_Note:_ The default example `contour` includes this [file][1] for easy deployment of Contour. + +## Environment Variables + +### CONTOUR_NAMESPACE + +If present, the value of the `CONTOUR_NAMESPACE` environment variable is used as: + +1. The value for the `contour bootstrap --namespace` flag unless otherwise specified. +1. The value for the `contour certgen --namespace` flag unless otherwise specified. +1. The value for the `contour serve --envoy-service-namespace` flag unless otherwise specified. +1. The value for the `contour serve --leader-election-resource-namespace` flag unless otherwise specified. + +The `CONTOUR_NAMESPACE` environment variable is set via the [Downward API][6] in the Contour [example manifests][7]. + +## Bootstrap Config File + +The bootstrap configuration file is generated by an initContainer in the Envoy daemonset which runs the `contour bootstrap` command to generate the file. +This configuration file configures the Envoy container to connect to Contour and receive configuration via xDS. + +The next section outlines all the available flags that can be passed to the `contour bootstrap` command which are used to customize +the configuration file to match the environment in which Envoy is deployed. + +### Bootstrap Flags + +There are flags that can be passed to `contour bootstrap` that help configure how Envoy +connects to Contour: + +| Flag | Default | Description | +| -------------------------------------- |-------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| --resources-dir | "" | Directory where resource files will be written. | +| --admin-address | /admin/admin.sock | Path to Envoy admin unix domain socket. | +| --admin-port (Deprecated) | 9001 | Deprecated: Port is now configured as a Contour flag. | +| --xds-address | 127.0.0.1 | Address to connect to Contour xDS server on. | +| --xds-port | 8001 | Port to connect to Contour xDS server on. | +| --envoy-cafile | "" | CA filename for Envoy secure xDS gRPC communication. | +| --envoy-cert-file | "" | Client certificate filename for Envoy secure xDS gRPC communication. | +| --envoy-key-file | "" | Client key filename for Envoy secure xDS gRPC communication. | +| --namespace | projectcontour | Namespace the Envoy container will run, also configured via ENV variable "CONTOUR_NAMESPACE". Namespace is used as part of the metric names on static resources defined in the bootstrap configuration file. | +| --xds-resource-version | v3 | Currently, the only valid xDS API resource version is `v3`. | +| --dns-lookup-family | auto | Defines what DNS Resolution Policy to use for Envoy -> Contour cluster name lookup. Either v4, v6, auto or all. | +| --log-format | text | Log output format for Contour. Either text or json. | +| --overload-max-heap | 0 | Defines the maximum heap memory of the envoy controlled by the overload manager. When the value is greater than 0, the overload manager is enabled, and when envoy reaches 95% of the maximum heap size, it performs a shrink heap operation. When it reaches 98% of the maximum heap size, Envoy Will stop accepting requests. | + + +[1]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour/01-contour-config.yaml +[2]: config/access-logging +[3]: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/ +[4]: https://golang.org/pkg/time/#ParseDuration +[5]: https://godoc.org/github.com/projectcontour/contour/internal/envoy#DefaultFields +[6]: https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/ +[7]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour +[8]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout +[9]: 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-stream-idle-timeout +[10]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-max-connection-duration +[11]: 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-drain-timeout +[12]: 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-request-timeout +[13]: 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-delayed-close-timeout +[14]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener-connectionbalanceconfig diff --git a/site/content/docs/1.30/deploy-options.md b/site/content/docs/1.30/deploy-options.md new file mode 100644 index 00000000000..0ae74a53bd9 --- /dev/null +++ b/site/content/docs/1.30/deploy-options.md @@ -0,0 +1,383 @@ +# Deployment Options + +The [Getting Started][8] guide shows you a simple way to get started with Contour on your cluster. +This topic explains the details and shows you additional options. +Most of this covers running Contour using a Kubernetes Service of `Type: LoadBalancer`. +If you don't have a cluster with that capability see the [Running without a Kubernetes LoadBalancer][1] section. + +## Installation + +Contour requires a secret containing TLS certificates that are used to secure the gRPC communication between Contour<>Envoy. +This secret can be auto-generated by the Contour `certgen` job or provided by an administrator. +Traffic must be forwarded to Envoy, typically via a Service of `type: LoadBalancer`. +All other requirements such as RBAC permissions, configuration details, are provided or have good defaults for most installations. + +### Setting resource requests and limits + +It is recommended that resource requests and limits be set on all Contour and Envoy containers. +The example YAML manifests used in the [Getting Started][8] guide do not include these, because the appropriate values can vary widely from user to user. +The table below summarizes the Contour and Envoy containers, and provides some reasonable resource requests to start with (note that these should be adjusted based on observed usage and expected load): + +| Workload | Container | Request (mem) | Request (cpu) | +| ------------------- | ---------------- | ------------- | ------------- | +| deployment/contour | contour | 128Mi | 250m | +| daemonset/envoy | envoy | 256Mi | 500m | +| daemonset/envoy | shutdown-manager | 50Mi | 25m | + + +### Envoy as Daemonset + +The recommended installation is for Contour to run as a Deployment and Envoy to run as a Daemonset. +The example Damonset places a single instance of Envoy per node in the cluster as well as attaches to `hostPorts` on each node. +This model allows for simple scaling of Envoy instances as well as ensuring even distribution of instances across the cluster. + +The [example daemonset manifest][2] or [Contour Gateway Provisioner][12] will create an installation based on these recommendations. + +_Note: If the size of the cluster is scaled down, connections can be lost since Kubernetes Damonsets do not follow proper `preStop` hooks._ + +### Envoy as Deployment + +An alternative Envoy deployment model is utilizing a Kubernetes Deployment with a configured `podAntiAffinity` which attempts to mirror the Daemonset deployment model. +A benefit of this model compared to the Daemonset version is when a node is removed from the cluster, the proper shutdown events are available so connections can be cleanly drained from Envoy before terminating. + +The [example deployment manifest][14] will create an installation based on these recommendations. + +## Testing your installation + +### Get your hostname or IP address + +To retrieve the IP address or DNS name assigned to your Contour deployment, run: + +```bash +$ kubectl get -n projectcontour service envoy -o wide +``` + +On AWS, for example, the response looks like: + +``` +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR +contour 10.106.53.14 a47761ccbb9ce11e7b27f023b7e83d33-2036788482.ap-southeast-2.elb.amazonaws.com 80:30274/TCP 3h app=contour +``` + +Depending on your cloud provider, the `EXTERNAL-IP` value is an IP address, or, in the case of Amazon AWS, the DNS name of the ELB created for Contour. Keep a record of this value. + +Note that if you are running an Elastic Load Balancer (ELB) on AWS, you must add more details to your configuration to get the remote address of your incoming connections. +See the [instructions for enabling the PROXY protocol.][4] + +#### Minikube + +On Minikube, to get the IP address of the Contour service run: + +```bash +$ minikube service -n projectcontour envoy --url +``` + +The response is always an IP address, for example `http://192.168.99.100:30588`. This is used as CONTOUR_IP in the rest of the documentation. + +#### kind + +When creating the cluster on Kind, pass a custom configuration to allow Kind to expose port 80/443 to your local host: + +```yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: worker + extraPortMappings: + - containerPort: 80 + hostPort: 80 + listenAddress: "0.0.0.0" + - containerPort: 443 + hostPort: 443 + listenAddress: "0.0.0.0" +``` + +Then run the create cluster command passing the config file as a parameter. +This file is in the `examples/kind` directory: + +```bash +$ kind create cluster --config examples/kind/kind-expose-port.yaml +``` + +Then, your CONTOUR_IP (as used below) will just be `localhost:80`. + +_Note: We've created a public DNS record (`local.projectcontour.io`) which is configured to resolve to `127.0.0.1``. This allows you to use a real domain name in your kind cluster._ + +### Test with Ingress + +The Contour repository contains an example deployment of the Kubernetes Up and Running demo application, [kuard][5]. +To test your Contour deployment, deploy `kuard` with the following command: + +```bash +$ kubectl apply -f https://projectcontour.io/examples/kuard.yaml +``` + +Then monitor the progress of the deployment with: + +```bash +$ kubectl get po,svc,ing -l app=kuard +``` + +You should see something like: + +``` +NAME READY STATUS RESTARTS AGE +po/kuard-370091993-ps2gf 1/1 Running 0 4m +po/kuard-370091993-r63cm 1/1 Running 0 4m +po/kuard-370091993-t4dqk 1/1 Running 0 4m + +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc/kuard 10.110.67.121 80/TCP 4m + +NAME HOSTS ADDRESS PORTS AGE +ing/kuard * 10.0.0.47 80 4m +``` + +... showing that there are three Pods, one Service, and one Ingress that is bound to all virtual hosts (`*`). + +In your browser, navigate your browser to the IP or DNS address of the Contour Service to interact with the demo application. + +### Test with HTTPProxy + +To test your Contour deployment with [HTTPProxy][9], run the following command: + +```sh +$ kubectl apply -f https://projectcontour.io/examples/kuard-httpproxy.yaml +``` + +Then monitor the progress of the deployment with: + +```sh +$ kubectl get po,svc,httpproxy -l app=kuard +``` + +You should see something like: + +```sh +NAME READY STATUS RESTARTS AGE +pod/kuard-bcc7bf7df-9hj8d 1/1 Running 0 1h +pod/kuard-bcc7bf7df-bkbr5 1/1 Running 0 1h +pod/kuard-bcc7bf7df-vkbtl 1/1 Running 0 1h + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/kuard ClusterIP 10.102.239.168 80/TCP 1h + +NAME FQDN TLS SECRET FIRST ROUTE STATUS STATUS DESCRIPT +httpproxy.projectcontour.io/kuard kuard.local valid valid HTTPProxy +``` + +... showing that there are three Pods, one Service, and one HTTPProxy . + +In your terminal, use curl with the IP or DNS address of the Contour Service to send a request to the demo application: + +```sh +$ curl -H 'Host: kuard.local' ${CONTOUR_IP} +``` + +## Running without a Kubernetes LoadBalancer + +If you can't or don't want to use a Service of `type: LoadBalancer` there are other ways to run Contour. + +### NodePort Service + +If your cluster doesn't have the capability to configure a Kubernetes LoadBalancer, +or if you want to configure the load balancer outside Kubernetes, +you can change the Envoy Service in the [`02-service-envoy.yaml`][7] file and set `type` to `NodePort`. + +This will have every node in your cluster listen on the resultant port and forward traffic to Contour. +That port can be discovered by taking the second number listed in the `PORT` column when listing the service, for example `30274` in `80:30274/TCP`. + +Now you can point your browser at the specified port on any node in your cluster to communicate with Contour. + +### Host Networking + +You can run Contour without a Kubernetes Service at all. +This is done by having the Envoy pod run with host networking. +Contour's examples utilize this model in the `/examples` directory. +To configure, set: `hostNetwork: true` and `dnsPolicy: ClusterFirstWithHostNet` on your Envoy pod definition. +Next, pass `--envoy-service-http-port=80 --envoy-service-https-port=443` to the contour `serve` command which instructs Envoy to listen directly on port 80/443 on each host that it is running. +This is best paired with a DaemonSet (perhaps paired with Node affinity) to ensure that a single instance of Contour runs on each Node. +See the [AWS NLB tutorial][10] as an example. + +## Disabling Features + +You can run Contour with certain features disabled by passing `--disable-feature` flag to the Contour `serve` command. +The flag is used to disable the informer for a custom resource, effectively making the corresponding CRD optional in the cluster. +You can provide the flag multiple times. + +For example, to disable ExtensionService CRD, use the flag as follows: `--disable-feature=extensionservices`. + +See the [configuration section entry][19] for all options. + +## Upgrading Contour/Envoy + +At times, it's needed to upgrade Contour, the version of Envoy, or both. +The included `shutdown-manager` can assist with watching Envoy for open connections while draining and give signal back to Kubernetes as to when it's fine to delete Envoy pods during this process. + +See the [redeploy envoy][11] docs for more information about how to not drop active connections to Envoy. +Also see the [upgrade guides][15] on steps to roll out a new version of Contour. + +## Running Multiple Instances of Contour + +It's possible to run multiple instances of Contour within a single Kubernetes cluster. +This can be useful for separating external vs. internal ingress, for having separate ingress controllers for different ingress classes, and more. +Each Contour instance can also be configured via the `--watch-namespaces` flag to handle their own namespaces. This allows the Kubernetes RBAC objects +to be restricted further. + +The recommended way to deploy multiple Contour instances is to put each instance in its own namespace. +This avoids most naming conflicts that would otherwise occur, and provides better logical separation between the instances. +However, it is also possible to deploy multiple instances in a single namespace if needed; this approach requires more modifications to the example manifests to function properly. +Each approach is described in detail below, using the [examples/contour][17] directory's manifests for reference. + +### In Separate Namespaces (recommended) + +In general, this approach requires updating the `namespace` of all resources, as well as giving unique names to cluster-scoped resources to avoid conflicts. + +- `00-common.yaml`: + - update the name of the `Namespace` + - update the namespace of both `ServiceAccounts` +- `01-contour-config.yaml`: + - update the namespace of the `ConfigMap` + - if you have any namespaced references within the ConfigMap contents (e.g. `fallback-certificate`, `envoy-client-certificate`), ensure those point to the correct namespace as well. +- `01-crds.yaml` will be shared between the two instances; no changes are needed. +- `02-job-certgen.yaml`: + - update the namespace of all resources + - update the namespace of the `ServiceAccount` subject within the `RoleBinding` +- `02-role-contour.yaml`: + - update the name of the `ClusterRole` to be unique + - update the namespace of the `Role` +- `02-rbac.yaml`: + - update the name of the `ClusterRoleBinding` to be unique + - update the namespace of the `RoleBinding` + - update the namespaces of the `ServiceAccount` subject within both resources + - update the name of the ClusterRole within the ClusterRoleBinding's roleRef to match the unique name used in `02-role-contour.yaml` +- `02-service-contour.yaml`: + - update the namespace of the `Service` +- `02-service-envoy.yaml`: + - update the namespace of the `Service` +- `03-contour.yaml`: + - update the namespace of the `Deployment` + - add an argument to the container, `--ingress-class-name=`, so this instance only processes Ingresses/HTTPProxies with the given ingress class. +- `03-envoy.yaml`: + - update the namespace of the `DaemonSet` + - remove the two `hostPort` definitions from the container (otherwise, these would conflict between the two instances) + + +### In The Same Namespace + +This approach requires giving unique names to all resources to avoid conflicts, and updating all resource references to use the correct names. + +- `00-common.yaml`: + - update the names of both `ServiceAccounts` to be unique +- `01-contour-config.yaml`: + - update the name of the `ConfigMap` to be unique +- `01-crds.yaml` will be shared between the two instances; no changes are needed. +- `02-job-certgen.yaml`: + - update the names of all resources to be unique + - update the name of the `Role` within the `RoleBinding`'s roleRef to match the unique name used for the `Role` + - update the name of the `ServiceAccount` within the `RoleBinding`'s subjects to match the unique name used for the `ServiceAccount` + - update the serviceAccountName of the `Job` + - add an argument to the container, `--secrets-name-suffix=`, so the generated TLS secrets have unique names + - update the spec.template.metadata.labels on the `Job` to be unique +- `02-role-contour.yaml`: + - update the names of the `ClusterRole` and `Role` to be unique +- `02-rbac.yaml`: + - update the names of the `ClusterRoleBinding` and `RoleBinding` to be unique + - update the roleRefs within both resources to reference the unique `Role` and `ClusterRole` names used in `02-role-contour.yaml` + - update the subjects within both resources to reference the unique `ServiceAccount` name used in `00-common.yaml` +- `02-service-contour.yaml`: + - update the name of the `Service` to be unique + - update the selector to be unique (this must match the labels used in `03-contour.yaml`, below) +- `02-service-envoy.yaml`: + - update the name of the `Service` to be unique + - update the selector to be unique (this must match the labels used in `03-envoy.yaml`, below) +- `03-contour.yaml`: + - update the name of the `Deployment` to be unique + - update the metadata.labels, the spec.selector.matchLabels, the spec.template.metadata.labels, and the spec.template.spec.affinity.podAntiAffinity labels to match the labels used in `02-service-contour.yaml` + - update the serviceAccountName to match the unique name used in `00-common.yaml` + - update the `contourcert` volume to reference the unique `Secret` name generated from `02-certgen.yaml` (e.g. `contourcert`) + - update the `contour-config` volume to reference the unique `ConfigMap` name used in `01-contour-config.yaml` + - add an argument to the container, `--leader-election-resource-name=`, so this Contour instance uses a separate leader election `Lease` + - add an argument to the container, `--envoy-service-name=`, referencing the unique name used in `02-service-envoy.yaml` + - add an argument to the container, `--ingress-class-name=`, so this instance only processes Ingresses/HTTPProxies with the given ingress class. +- `03-envoy.yaml`: + - update the name of the `DaemonSet` to be unique + - update the metadata.labels, the spec.selector.matchLabels, and the spec.template.metadata.labels to match the unique labels used in `02-service-envoy.yaml` + - update the `--xds-address` argument to the initContainer to use the unique name of the contour Service from `02-service-contour.yaml` + - update the serviceAccountName to match the unique name used in `00-common.yaml` + - update the `envoycert` volume to reference the unique `Secret` name generated from `02-certgen.yaml` (e.g. `envoycert`) + - remove the two `hostPort` definitions from the container (otherwise, these would conflict between the two instances) + +### Using the Gateway provisioner + +The Contour Gateway provisioner also supports deploying multiple instances of Contour, either in the same namespace or different namespaces. +See [Getting Started with the Gateway provisioner][16] for more information on getting started with the Gateway provisioner. +To deploy multiple Contour instances, you create multiple `Gateways`, either in the same namespace or in different namespaces. + +Note that although the provisioning request itself is made via a Gateway API resource (`Gateway`), this method of installation still allows you to use *any* of the supported APIs for defining virtual hosts and routes: `Ingress`, `HTTPProxy`, or Gateway API's `HTTPRoute` and `TLSRoute`. + +If you are using `Ingress` or `HTTPProxy`, you will likely want to assign each Contour instance a different ingress class, so they each handle different subsets of `Ingress`/`HTTPProxy` resources. +To do this, [create two separate GatewayClasses][18], each with a different `ContourDeployment` parametersRef. +The `ContourDeployment` specs should look like: + +```yaml +kind: ContourDeployment +apiVersion: projectcontour.io/v1alpha1 +metadata: + namespace: projectcontour + name: ingress-class-1 +spec: + runtimeSettings: + ingress: + classNames: + - ingress-class-1 +--- +kind: ContourDeployment +apiVersion: projectcontour.io/v1alpha1 +metadata: + namespace: projectcontour + name: ingress-class-2 +spec: + runtimeSettings: + ingress: + classNames: + - ingress-class-2 +``` + +Then create each `Gateway` with the appropriate `spec.gatewayClassName`. + +## Running Contour in tandem with another ingress controller + +If you're running multiple ingress controllers, or running on a cloudprovider that natively handles ingress, +you can specify the annotation `kubernetes.io/ingress.class: "contour"` on all ingresses that you would like Contour to claim. +You can customize the class name with the `--ingress-class-name` flag at runtime. (A comma-separated list of class names is allowed.) +If the `kubernetes.io/ingress.class` annotation is present with a value other than `"contour"`, Contour will ignore that ingress. + +## Uninstall Contour + +To remove Contour or the Contour Gateway Provisioner from your cluster, delete the namespace: + +```bash +$ kubectl delete ns projectcontour +``` +**Note**: Your namespace may differ from above. + +[1]: #running-without-a-kubernetes-loadbalancer +[2]: {{< param github_url>}}/tree/{{< param branch >}}/examples/render/contour.yaml +[3]: #host-networking +[4]: guides/proxy-proto.md +[5]: https://github.com/kubernetes-up-and-running/kuard +[7]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour/02-service-envoy.yaml +[8]: /getting-started +[9]: config/fundamentals.md +[10]: guides/deploy-aws-nlb.md +[11]: redeploy-envoy.md +[12]: {{< param github_url>}}/tree/{{< param branch >}}/examples/render/contour-gateway-provisioner.yaml +[13]: https://projectcontour.io/resources/deprecation-policy/ +[14]: {{< param github_url>}}/tree/{{< param branch >}}/examples/render/contour-deployment.yaml +[15]: /resources/upgrading/ +[16]: https://projectcontour.io/getting-started/#option-3-contour-gateway-provisioner-alpha +[17]: {{< param github_url>}}/tree/{{< param branch >}}/examples/contour +[18]: guides/gateway-api/#next-steps +[19]: configuration.md \ No newline at end of file diff --git a/site/content/docs/1.30/github.md b/site/content/docs/1.30/github.md new file mode 100644 index 00000000000..8a0f36b4f4d --- /dev/null +++ b/site/content/docs/1.30/github.md @@ -0,0 +1,80 @@ +This document outlines how we use GitHub. + +## Milestones + +Contour attempts to ship on a quarterly basis. +These releases are tracked with a milestone. +The _current_ release is the milestone with the closest delivery date. + +Issues which are not assigned to the current milestone _should not be worked on_. + +## Priorities + +This project has three levels of priority: + +- p0 - Must fix immediately. +This is reserved for bugs and security issues. A milestone cannot ship with open p0 issues. +- p1 - Should be done. +p1 issues assigned to a milestone _should_ be completed during that milestone. +- p2 - May be done. +p2 issues assigned to a milestone _may_ be completed during that milestone if time permits. + +Issues without a priority are _unprioritised_. Priority will be assigned by a PM or release manager during issue triage. + +## Questions + +We encourage support questions via issues. +Questions will be tagged `question` and are not assigned a milestone or a priority. + +## Waiting for information + +Any issue which lacks sufficient information for triage will be tagged `waiting-for-info`. +Issues with this tag may be closed after a reasonable length of time if further information is not forthcoming. + +## Issue tagging + +Issues without tags have not be triaged. + +During issue triage, usually by a project member, release manager, or pm, one or more tags will be assigned. + +- `Needs-Product` indicates the issue needs attention by a product owner or PM. +- `Needs-design-doc` indicates the issue requires a design document to be circulated. + +These are blocking states, these labels must be resolved, either by PM or agreeing on a design. + +## Assigning an issue + +Issues within a milestone _should_ be assigned to an owner when work commences on them. +Assigning an issue indicates that you are working on it. + +Before you start to work on an issue you should assign yourself. +From that point onward you are responsible for the issue and you are expected to report timely status on the issue to anyone that asks. + +If you cease work on an issue, even if incomplete, you should leave a comment to that effect on the issue and remove yourself as the assignee. +From that point onward you are no longer responsible for the issue, however you may be approached as a subject matter expert--as the last person to touch the issue--by future assignees. + +For infrequent contributors who are not members of the Contour project, assign yourself by leaving a comment to that effect on the issue. + +*Do not hoard issues, you won't enjoy it* + +## Requesting a review + +PRs which are related to issues in the current milestone should be assigned to the current milestone. +This is an indicator to reviewers that the PR is ready for review and should be reviewed in the current milestone. +Occasionally PRs may be assigned to the next milestone indicating they are for review at the start of the next development cycle. + +All PRs should reference the issue they relate to either by one of the following; + +- `Fixes #NNNN` indicating that merging this issue will fix issue #NNNN +- `Updates #NNNN` indicating that merging this issue will progress issue #NNNN to some degree. + +If there is no `Updates` or `Fixes` line in the PR the review will, with the exception of trivial or self evident fixes, be deferred. + +[Further reading][1] + +## Help wanted and good first issues + +The `help wanted` and `good first issue` tags _may_ be assigned to issues _in the current milestone_. +To limit the amount of work in progress, `help wanted` and `good first issue` should not be used for issues outside the current milestone. + +[1]: https://dave.cheney.net/2019/02/18/talk-then-code \ No newline at end of file diff --git a/site/content/docs/1.30/grpc-tls-howto.md b/site/content/docs/1.30/grpc-tls-howto.md new file mode 100644 index 00000000000..51770de950d --- /dev/null +++ b/site/content/docs/1.30/grpc-tls-howto.md @@ -0,0 +1,169 @@ +# Enabling TLS between Envoy and Contour + +This document describes the steps required to secure communication between Envoy and Contour. +The outcome of this is that we will have two Secrets available in the `projectcontour` namespace: + +- **contourcert:** contains Contour's keypair which is used for serving TLS secured gRPC, and the CA's public certificate bundle which is used for validating Envoy's client certificate. +Contour's certificate must be a valid certificate for the name `contour` in order for this to work. +This is currently hardcoded by Contour. +- **envoycert:** contains Envoy's keypair which used as a client for connecting to Contour, and the CA's public certificate bundle which is used for validating Contour's server certificate. + +Note that both Secrets contain a copy of the CA certificate bundle under the `ca.crt` data key. + +## Ways you can get the certificates into your cluster + +- Deploy the Job from [certgen.yaml][1]. +This will run `contour certgen --kube --secrets-format=compact` for you. +- Run `contour certgen --kube` locally. +- Run the manual procedure below. + +## Caveats and warnings + +**Be very careful with your production certificates!** + +This is intended as an example to help you get started. +For any real deployment, you should **carefully** manage all the certificates and control who has access to them. +Make sure you don't commit them to any git repositories either. + +## Manual TLS certificate generation process + +### Generating a CA keypair + +First, we need to generate a keypair: + +``` +$ openssl req -x509 -new -nodes \ + -keyout certs/cakey.pem -sha256 \ + -days 1825 -out certs/cacert.pem \ + -subj "/O=Project Contour/CN=Contour CA" +``` + +Then, the new CA key will be stored in `certs/cakey.pem` and the cert in `certs/cacert.pem`. + +### Generating Contour's keypair + +Next, we need to generate a keypair for Contour. +First, we make a new private key: + +``` +$ openssl genrsa -out certs/contourkey.pem 2048 +``` + +Then, we create a CSR and have our CA sign the CSR and issue a certificate. +This uses the file [certs/cert-contour.ext][2], which ensures that at least one of the valid names of the certificate is the bareword `contour`. +This is required for the handshake to succeed, as `contour bootstrap` configures Envoy to pass this as the SNI server name for the connection. + +``` +$ openssl req -new -key certs/contourkey.pem \ + -out certs/contour.csr \ + -subj "/O=Project Contour/CN=contour" + +$ openssl x509 -req -in certs/contour.csr \ + -CA certs/cacert.pem \ + -CAkey certs/cakey.pem \ + -CAcreateserial \ + -out certs/contourcert.pem \ + -days 1825 -sha256 \ + -extfile certs/cert-contour.ext +``` + +At this point, the contour certificate and key are in the files `certs/contourcert.pem` and `certs/contourkey.pem` respectively. + +### Generating Envoy's keypair + +Next, we generate a keypair for Envoy: + +``` +$ openssl genrsa -out certs/envoykey.pem 2048 +``` + +Then, we generate a CSR and have the CA sign it: + +``` +$ openssl req -new -key certs/envoykey.pem \ + -out certs/envoy.csr \ + -subj "/O=Project Contour/CN=envoy" + +$ openssl x509 -req -in certs/envoy.csr \ + -CA certs/cacert.pem \ + -CAkey certs/cakey.pem \ + -CAcreateserial \ + -out certs/envoycert.pem \ + -days 1825 -sha256 \ + -extfile certs/cert-envoy.ext +``` + +Like the Contour certificate, this CSR uses the file [certs/cert-envoy.ext][3]. +However, in this case, there are no special names required. + +### Putting the certificates in the cluster + +Next, we create the required Secrets in the target Kubernetes cluster: + +```bash +$ kubectl create secret -n projectcontour generic contourcert \ + --from-file=tls.key=./certs/contourkey.pem \ + --from-file=tls.crt=./certs/contourcert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --save-config + +$ kubectl create secret -n projectcontour generic envoycert \ + --from-file=tls.key=./certs/envoykey.pem \ + --from-file=tls.crt=./certs/envoycert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --save-config +``` + +Note that we don't put the CA **key** into the cluster, there's no reason for that to be there, and that would create a security problem. + +## Rotating Certificates + +Eventually the certificates that Contour and Envoy use will need to be rotated. +The following steps can be taken to replace the certificates that Contour and Envoy are using: + +1. Generate a new keypair for both Contour and Envoy (optionally also for the CA) +2. Update the Secrets that hold the gRPC TLS keypairs +3. Contour and Envoy will automatically rotate their certificates after mounted secrets have been updated by the kubelet + +The secrets can be updated in-place by running: + +```bash +$ kubectl create secret -n projectcontour generic contourcert \ + --from-file=tls.key=./certs/contourkey.pem \ + --from-file=tls.crt=./certs/contourcert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --dry-run -o json \ + | kubectl apply -f - + +$ kubectl create secret -n projectcontour generic envoycert \ + --from-file=tls.key=./certs/envoykey.pem \ + --from-file=tls.crt=./certs/envoycert.pem \ + --from-file=ca.crt=./certs/cacert.pem \ + --dry-run -o json \ + | kubectl apply -f - +``` + +There are few preconditions that need to be met before Envoy can automatically reload certificate and key files: + +- Envoy must be version v1.14.1 or later +- The bootstrap configuration must be generated with `contour bootstrap` using the `--resources-dir` argument, see [examples/contour/03-envoy.yaml][4] + +### Rotate using the contour-certgen job + +When using the built-in Contour certificate generation, the following steps can be used: + +1. Delete the contour-certgen job + - `kubectl delete job contour-certgen -n projectcontour` +2. Reapply the contour-certgen job from [certgen.yaml][1] + +## Conclusion + +Once this process is done, the certificates will be present as Secrets in the `projectcontour` namespace, as required by +[examples/contour][5]. + +[1]: {{< param github_url >}}/tree/{{< param branch >}}/examples/contour/02-job-certgen.yaml +[2]: {{< param github_url >}}/tree/{{< param branch >}}/certs/cert-contour.ext +[3]: {{< param github_url >}}/tree/{{< param branch >}}/certs/cert-envoy.ext +[4]: {{< param github_url >}}/tree/{{< param branch >}}/examples/contour/03-envoy.yaml +[5]: {{< param github_url >}}/tree/{{< param branch >}}/examples/contour + diff --git a/site/content/docs/1.30/guides/_index.md b/site/content/docs/1.30/guides/_index.md new file mode 100644 index 00000000000..8981b8fbd79 --- /dev/null +++ b/site/content/docs/1.30/guides/_index.md @@ -0,0 +1,9 @@ +--- +title: Guides +description: Contour Resources +id: guides +--- +## Getting things done with Contour + +This page contains links to articles on configuring specific Contour features. + diff --git a/site/content/docs/1.30/guides/cert-manager.md b/site/content/docs/1.30/guides/cert-manager.md new file mode 100644 index 00000000000..0f926946eda --- /dev/null +++ b/site/content/docs/1.30/guides/cert-manager.md @@ -0,0 +1,670 @@ +--- +title: Deploying HTTPS services with Contour and cert-manager +--- + +This tutorial shows you how to securely deploy an HTTPS web application on a Kubernetes cluster, using: + +- Kubernetes +- Contour, as the Ingress controller +- [JetStack's cert-manager][1] to provision TLS certificates from [the Let's Encrypt project][6] + +## Prerequisites + +- A Kubernetes cluster deployed in either a data center or a cloud provider with a Kubernetes as a service offering. This tutorial was last tested on a GKE cluster running Kubernetes 1.22 +- RBAC enabled on your cluster +- Your cluster must be able to request a public IP address from your cloud provider, using a load balancer. If you're on AWS or GKE this is automatic if you deploy a Kubernetes service object of type: LoadBalancer. If you're on your own datacenter you must set it up yourself +- A DNS domain that you control, where you host your web application +- Administrator permissions for all deployment steps + +**NOTE:** To use a local cluster like `minikube` or `kind`, see the instructions in [the deployment guide][7]. + +## Summary + +This tutorial walks you through deploying: + +1. [Contour][0] +2. [Jetstack cert-manager][1] +3. A sample web application using HTTPProxy + +**NOTE:** If you encounter failures related to permissions, make sure the user you are operating as has administrator permissions. + +After you've been through the steps the first time, you don't need to repeat deploying Contour and cert-manager for subsequent application deployments. Instead, you can skip to step 3. + +## 1. Deploy Contour + +Run: + +```bash +$ kubectl apply -f {{< param base_url >}}/quickstart/contour.yaml +``` + +to set up Contour as a deployment in its own namespace, `projectcontour`, and tell the cloud provider to provision an external IP that is forwarded to the Contour pods. + +Check the progress of the deployment with this command: + +```bash +$ kubectl -n projectcontour get po +NAME READY STATUS RESTARTS AGE +contour-5475898957-jh9fm 1/1 Running 0 39s +contour-5475898957-qlbs2 1/1 Running 0 39s +contour-certgen-v1.19.0-5xthf 0/1 Completed 0 39s +envoy-hqbkm 2/2 Running 0 39s +``` + +After all the `contour` & `envoy` pods reach `Running` status and fully `Ready`, move on to the next step. + +### Access your cluster + +Retrieve the external address of the load balancer assigned to Contour's Envoys by your cloud provider: + +```bash +$ kubectl get -n projectcontour service envoy -o wide +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR +envoy LoadBalancer 10.51.245.99 35.189.26.87 80:30111/TCP,443:30933/TCP 38d app=envoy +``` + +The value of `EXTERNAL-IP` varies by cloud provider. In this example GKE gives a bare IP address; AWS gives you a long DNS name. + +To make it easier to work with the external load balancer, the tutorial adds a DNS record to a domain we control that points to this load balancer's IP address: + +```bash +$ host gke.davecheney.com +gke.davecheney.com has address 35.189.26.87 +``` + +On AWS, you specify a `CNAME`, not an `A` record, and it would look something like this: + +```bash +$ host aws.davecheney.com +aws.davecheney.com is an alias for a4d1766f6ce1611e7b27f023b7e83d33–1465548734.ap-southeast-2.elb.amazonaws.com. +a4d1766f6ce1611e7b27f023b7e83d33–1465548734.ap-southeast-2.elb.amazonaws.com has address 52.63.20.117 +a4d1766f6ce1611e7b27f023b7e83d33–1465548734.ap-southeast-2.elb.amazonaws.com has address 52.64.233.204 +``` + +In your own data center, you need to arrange for traffic from a public IP address to be forwarded to the cluster IP of the Contour service. This is beyond the scope of the tutorial. + +### Testing connectivity + +You must deploy at least one Ingress object before Contour can configure Envoy to serve traffic. +Note that as a security feature, Contour does not configure Envoy to expose a port to the internet unless there's a reason it should. +For this tutorial we deploy a version of Kenneth Reitz's [httpbin.org service][3]. + +To deploy httpbin to your cluster, run this command: + +```bash +$ kubectl apply -f {{< param base_url >}}/examples/httpbin.yaml +``` + +Check that the pods are running: + +```bash +$ kubectl get po -l app=httpbin +NAME READY STATUS RESTARTS AGE +httpbin-85777b684b-8sqw5 1/1 Running 0 24s +httpbin-85777b684b-pb26w 1/1 Running 0 24s +httpbin-85777b684b-vpgwl 1/1 Running 0 24s +``` + +Then type the DNS name you set up in the previous step into a web browser, for example `http://gke.davecheney.com/`. You should see something like: + +![httpbin screenshot][8] + +You can delete the httpbin service now, or at any time, by running: + +```bash +$ kubectl delete -f {{< param base_url >}}/examples/httpbin.yaml +``` + +## 2. Deploy jetstack/cert-manager + +**NOTE:** cert-manager is a powerful product that provides more functionality than this tutorial demonstrates. +There are plenty of [other ways to deploy cert-manager][4], but they are out of scope. + +### Fetch the source manager deployment manifest + +To keep things simple, we skip cert-manager's Helm installation, and use the [supplied YAML manifests][5]. + +```bash +$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml +``` + +When cert-manager is up and running you should see something like: + +```bash +$ kubectl -n cert-manager get all +NAME READY STATUS RESTARTS AGE +pod/cert-manager-cainjector-74bb68d67c-8lb2f 1/1 Running 0 40s +pod/cert-manager-f7f8bf74d-65ld9 1/1 Running 0 40s +pod/cert-manager-webhook-645b8bdb7-2h5t6 1/1 Running 0 40s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/cert-manager ClusterIP 10.48.13.252 9402/TCP 40s +service/cert-manager-webhook ClusterIP 10.48.7.220 443/TCP 40s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/cert-manager 1/1 1 1 40s +deployment.apps/cert-manager-cainjector 1/1 1 1 40s +deployment.apps/cert-manager-webhook 1/1 1 1 40s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/cert-manager-cainjector-74bb68d67c 1 1 1 40s +replicaset.apps/cert-manager-f7f8bf74d 1 1 1 40s +replicaset.apps/cert-manager-webhook-645b8bdb7 1 1 1 40s +``` + +### Deploy the Let's Encrypt cluster issuer + +cert-manager supports two different CRDs for configuration, an `Issuer`, which is scoped to a single namespace, +and a `ClusterIssuer`, which is cluster-wide. + +For Contour to be able to serve HTTPS traffic for an Ingress in any namespace, use `ClusterIssuer`. +Create a file called `letsencrypt-staging.yaml` with the following contents: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging + namespace: cert-manager +spec: + acme: + email: user@example.com + privateKeySecretRef: + name: letsencrypt-staging + server: https://acme-staging-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: contour +``` + +replacing `user@example.com` with your email address. +This is the email address that Let's Encrypt uses to communicate with you about certificates you request. + +The staging Let's Encrypt server is not bound by [the API rate limits of the production server][2]. +This approach lets you set up and test your environment without worrying about rate limits. +You can then repeat this step for a production Let's Encrypt certificate issuer. + +After you edit and save the file, deploy it: + +```bash +$ kubectl apply -f letsencrypt-staging.yaml +clusterissuer.cert-manager.io/letsencrypt-staging created +``` + +Wait for the `ClusterIssuer` to be ready: + +```bash +$ kubectl get clusterissuer letsencrypt-staging +NAME READY AGE +letsencrypt-staging True 54s +``` + +## 3. Deploy your first HTTPS site using Ingress + +For this tutorial we deploy a version of Kenneth Reitz's [httpbin.org service][3]. +We start with the deployment. +Copy the following to a file called `deployment.yaml`: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: httpbin + name: httpbin +spec: + replicas: 1 + selector: + matchLabels: + app: httpbin + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: httpbin + spec: + containers: + - image: docker.io/kennethreitz/httpbin + name: httpbin + ports: + - containerPort: 8080 + name: http + command: ["gunicorn"] + args: ["-b", "0.0.0.0:8080", "httpbin:app"] + dnsPolicy: ClusterFirst +``` + +Deploy to your cluster: + +```bash +$ kubectl apply -f deployment.yaml +deployment.apps/httpbin created +$ kubectl get pod -l app=httpbin +NAME READY STATUS RESTARTS AGE +httpbin-67fd96d97c-8j2rr 1/1 Running 0 56m +``` + +Expose the deployment to the world with a Service. Create a file called `service.yaml` with +the following contents: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: httpbin +spec: + ports: + - port: 8080 + protocol: TCP + targetPort: 8080 + selector: + app: httpbin +``` + +and deploy: + +```bash +$ kubectl apply -f service.yaml +service/httpbin created +$ kubectl get service httpbin +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +httpbin ClusterIP 10.48.6.155 8080/TCP 57m +``` + +Expose the Service to the world with Contour and an Ingress object. Create a file called `ingress.yaml` with +the following contents: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: httpbin +spec: + rules: + - host: httpbin.davecheney.com + http: + paths: + - pathType: Prefix + path: / + backend: + service: + name: httpbin + port: + number: 8080 +``` + +The host name, `httpbin.davecheney.com` is a `CNAME` to the `gke.davecheney.com` record that was created in the first section, and must be created in the same place as the `gke.davecheney.com` record was. +That is, in your cloud provider. +This lets requests to `httpbin.davecheney.com` resolve to the external IP address of the Contour service. +They are then forwarded to the Contour pods running in the cluster: + +```bash +$ host httpbin.davecheney.com +httpbin.davecheney.com is an alias for gke.davecheney.com. +gke.davecheney.com has address 35.189.26.87 +``` + +Change the value of `spec.rules.host` to something that you control, and deploy the Ingress to your cluster: + +```bash +$ kubectl apply -f ingress.yaml +ingress.networking.k8s.io/httpbin created +$ kubectl get ingress httpbin +NAME CLASS HOSTS ADDRESS PORTS AGE +httpbin httpbin.davecheney.com 80 12s +``` + +Now you can type the host name of the service into a browser, or use curl, to verify it's deployed and everything is working: + +```bash +$ curl http://httpbin.davecheney.com/get +{ + "args": {}, + "headers": { + "Accept": "*/*", + "Content-Length": "0", + "Host": "htpbin.davecheney.com", + "User-Agent": "curl/7.58.0", + "X-Envoy-Expected-Rq-Timeout-Ms": "15000", + "X-Envoy-Internal": "true" + }, + "origin": "10.152.0.2", + "url": "http://httpbin.davecheney.com/get" +} +``` + +Excellent, it looks like everything is up and running serving traffic over HTTP. + +### Request a TLS certificate from Let's Encrypt + +Now it's time to use cert-manager to request a TLS certificate from Let's Encrypt. +Do this by adding some annotations and a `tls:` section to the Ingress spec. + +We need to add the following annotations: + +- `cert-manager.io/cluster-issuer: letsencrypt-staging`: tells cert-manager to use the `letsencrypt-staging` cluster issuer you just created. +- `kubernetes.io/tls-acme: "true"`: Tells cert-manager to do ACME TLS (what Let's Encrypt uses). +- `ingress.kubernetes.io/force-ssl-redirect: "true"`: tells Contour to redirect HTTP requests to the HTTPS site. +- `kubernetes.io/ingress.class: contour`: Tells Contour that it should handle this Ingress object. + +Using `kubectl edit ingress httpbin`: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: httpbin + annotations: + cert-manager.io/cluster-issuer: letsencrypt-staging + ingress.kubernetes.io/force-ssl-redirect: "true" + kubernetes.io/ingress.class: contour + kubernetes.io/tls-acme: "true" +spec: + tls: + - secretName: httpbin + hosts: + - httpbin.davecheney.com + rules: + - host: httpbin.davecheney.com + http: + paths: + - pathType: Prefix + path: / + backend: + service: + name: httpbin + port: + number: 8080 +``` + +The certificate is issued in the name of the hosts listed in the `tls:` section, `httpbin.davecheney.com` and stored in the secret `httpbin`. +Behind the scenes, cert-manager creates a certificate CRD to manage the lifecycle of the certificate, and then a series of other CRDs to handle the challenge process. + +You can watch the progress of the certificate as it's issued: + +```bash +$ kubectl describe certificate httpbin | tail -n 12 +Status: + Conditions: + Last Transition Time: 2019-11-07T00:37:55Z + Message: Waiting for CertificateRequest "httpbinproxy-1925286939" to complete + Reason: InProgress + Status: False + Type: Ready +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal GeneratedKey 26s cert-manager Generated a new private key + Normal Requested 26s cert-manager Created new CertificateRequest resource "httpbinproxy-1925286939" +``` + +Wait for the certificate to be issued: + +```bash +$ kubectl describe certificate httpbin | grep -C3 "Certificate is up to date" +Status: + Conditions: + Last Transition Time: 2019-11-06T23:47:50Z + Message: Certificate is up to date and has not expired + Reason: Ready + Status: True + Type: Ready +``` + +A `kubernetes.io/tls` secret is created with the `secretName` specified in the `tls:` field of the Ingress. + +```bash +$ kubectl get secret httpbin +NAME TYPE DATA AGE +httpbin kubernetes.io/tls 2 3m +``` + +cert-manager manages the contents of the secret as long as the Ingress is present in your cluster. + +You can now visit your site, replacing `http://` with `https://` — and you get a huge security warning! +This is because the certificate was issued by the Let's Encrypt staging servers and has a fake CA. +This is so you can't accidentally use the staging servers to serve real certificates. + +```bash +$ curl https://httpbin.davecheney.com/get +curl: (60) SSL certificate problem: unable to get local issuer certificate +More details here: https://curl.haxx.se/docs/sslcerts.html + +curl failed to verify the legitimacy of the server and therefore could not +establish a secure connection to it. To learn more about this situation and +how to fix it, please visit the web page mentioned above. +``` + +### Switch to Let's Encrypt Production + +To request a properly signed certificate from the Let's Encrypt production servers, we create a new `ClusterIssuer`, as before but with some modifications. + +Create a file called `letsencrypt-prod.yaml` with the following contents: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod + namespace: cert-manager +spec: + acme: + email: user@example.com + privateKeySecretRef: + name: letsencrypt-prod + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - http01: + ingress: + class: contour +``` + +again replacing `user@example.com` with your email address. + +Deploy: + +```bash +$ kubectl apply -f letsencrypt-prod.yaml +clusterissuer.cert-manager.io/letsencrypt-prod created +``` + +Now we use `kubectl edit ingress httpbin` to edit our Ingress to ask for a real certificate from `letsencrypt-prod`: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: httpbin + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod +spec: + ... +``` + +The certificate resource will transition to `Ready: False` while it's re-provisioned from the Let's Encrypt production servers, and then back to `Ready: True` once it's been provisioned: + +```bash +$ kubectl describe certificate httpbin +... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + ... + Normal Issuing 21s cert-manager Issuing certificate as Secret was previously issued by ClusterIssuer.cert-manager.io/letsencrypt-staging + Normal Reused 21s cert-manager Reusing private key stored in existing Secret resource "httpbin" + Normal Requested 21s cert-manager Created new CertificateRequest resource "httpbin-sjqbt" + Normal Issuing 18s (x2 over 48s) cert-manager The certificate has been successfully issued +``` + +Followed by: + +```bash +$ kubectl get certificate httpbin -o wide +NAME READY SECRET ISSUER STATUS AGE +httpbin True httpbin letsencrypt-prod Certificate is up to date and has not expired 3m35s +``` + +Now revisiting our `https://httpbin.davecheney.com` site should show a valid, trusted, HTTPS certificate. + +```bash +$ curl https://httpbin.davecheney.com/get +{ + "args": {}, + "headers": { + "Accept": "*/*", + "Content-Length": "0", + "Host": "httpbin.davecheney.com", + "User-Agent": "curl/7.58.0", + "X-Envoy-Expected-Rq-Timeout-Ms": "15000", + "X-Envoy-Internal": "true" + }, + "origin": "10.152.0.2", + "url": "https://httpbin.davecheney.com/get" +} +``` + +![httpbin.davecheney.com screenshot][9] + +## Making cert-manager work with HTTPProxy + +cert-manager currently does not have a way to interact directly with HTTPProxy objects in order to respond to the HTTP01 challenge (See [#950][10] and [#951][11] for details). +cert-manager, however, can be configured to request certificates automatically using a `Certificate` object. + +When cert-manager finds a `Certificate` object, it will implement the HTTP01 challenge by creating a new, temporary Ingress object that will direct requests from Let's Encrypt to temporary pods called 'solver pods'. +These pods know how to respond to Let's Encrypt's challenge process for verifying you control the domain you're issuing certificates for. +The Ingress resource as well as the solver pods are short lived and will only be available during the certificate request or renewal process. + +The result of the work steps described previously is a TLS secret, which can be referenced by a HTTPProxy. + +## Details + +To do this, we first need to create our HTTPProxy and Certificate objects. + +This example uses the hostname `httpbinproxy.davecheney.com`, remember to create that name before starting. + +Firstly, the HTTPProxy: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: httpbinproxy +spec: + virtualhost: + fqdn: httpbinproxy.davecheney.com + tls: + secretName: httpbinproxy + routes: + - services: + - name: httpbin + port: 8080 +``` + +This object will be marked as Invalid by Contour, since the TLS secret doesn't exist yet. +Once that's done, create the Certificate object: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: httpbinproxy +spec: + commonName: httpbinproxy.davecheney.com + dnsNames: + - httpbinproxy.davecheney.com + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + secretName: httpbinproxy +``` + +Wait for the Certificate to be provisioned: + +```bash +$ kubectl get certificate httpbinproxy -o wide +NAME READY SECRET ISSUER STATUS AGE +httpbinproxy True httpbinproxy letsencrypt-prod Certificate is up to date and has not expired 39s +``` + +Once cert-manager has fulfilled the HTTP01 challenge, you will have a `httpbinproxy` secret, that will contain the keypair. +Contour will detect that the Secret exists and generate the HTTPProxy config. + +After that, you should be able to curl the new site: + +```bash +$ curl https://httpbinproxy.davecheney.com/get +{ + "args": {}, + "headers": { + "Accept": "*/*", + "Content-Length": "0", + "Host": "httpbinproxy.davecheney.com", + "User-Agent": "curl/7.54.0", + "X-Envoy-Expected-Rq-Timeout-Ms": "15000", + "X-Envoy-External-Address": "122.106.57.183" + }, + "origin": "122.106.57.183", + "url": "https://httpbinproxy.davecheney.com/get" +} +``` + +## Wrapping up + +Now that you've deployed your first HTTPS site using Contour and Let's Encrypt, deploying additional TLS enabled services is much simpler. +Remember that for each HTTPS website you deploy, cert-manager will create a Certificate CRD that provides the domain name and the name of the target Secret. +The TLS functionality will be enabled when the HTTPProxy contains the `tls:` stanza, and the referenced secret contains a valid keypair. + +See the [cert-manager docs][12] for more information. + +## Bonus points + +For bonus points, you can use a feature of Contour to automatically upgrade any HTTP request to the corresponding HTTPS site so you are no longer serving any traffic over insecure HTTP. + +To enable the automatic redirect from HTTP to HTTPS, add this annotation to your Ingress object. + +``` +metadata: + annotations: + ingress.kubernetes.io/force-ssl-redirect: "true" +``` +Now any requests to the insecure HTTP version of your site get an unconditional 301 redirect to the HTTPS version: + +``` +$ curl -v http://httpbin.davecheney.com/get +* Trying 35.189.26.87… +* TCP_NODELAY set +* Connected to httpbin.davecheney.com (35.189.26.87) port 80 (#0) +> GET /get HTTP/1.1 +> Host: httpbin.davecheney.com +> User-Agent: curl/7.58.0 +> Accept: */* +> +< HTTP/1.1 301 Moved Permanently +< location: https://httpbin.davecheney.com/get +< date: Tue, 20 Feb 2018 04:11:46 GMT +< server: envoy +< content-length: 0 +< +* Connection #0 to host httpbin.davecheney.com left intact +``` + +__Note:__ For HTTPProxy resources this happens automatically without the need for an annotation. + +[0]: {{< param github_url >}} +[1]: https://github.com/jetstack/cert-manager +[2]: https://letsencrypt.org/docs/rate-limits/ +[3]: http://httpbin.org/ +[4]: https://docs.cert-manager.io/en/latest/getting-started/install/kubernetes.html +[5]: https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml +[6]: https://letsencrypt.org/getting-started/ +[7]: ../deploy-options/#get-your-hostname-or-ip-address +[8]: /img/cert-manager/httpbinhomepage.png +[9]: /img/cert-manager/httpbin.png +[10]: {{< param github_url >}}/issues/950 +[11]: {{< param github_url >}}/issues/951 +[12]: https://cert-manager.io/docs/usage/ingress/ diff --git a/site/content/docs/1.30/guides/deploy-aws-nlb.md b/site/content/docs/1.30/guides/deploy-aws-nlb.md new file mode 100644 index 00000000000..af3f8df1019 --- /dev/null +++ b/site/content/docs/1.30/guides/deploy-aws-nlb.md @@ -0,0 +1,47 @@ +--- +title: Deploying Contour on AWS with NLB +--- + +This is an advanced deployment guide to configure Contour on AWS with the [Network Load Balancer (NLB)][1]. +This configuration has several advantages: + +1. NLBs are often cheaper. This is especially true for development. Idle LBs do not cost money. +2. There are no extra network hops. Traffic goes to the NLB, to the node hosting Contour, and then to the target pod. +3. Source IP addresses are retained. Envoy (running as part of Contour) sees the native source IP address and records this with an `X-Forwarded-For` header. + +## Moving parts + +- We run Envoy as a DaemonSet across the cluster and Contour as a deployment +- The Envoy pod runs on host ports 80 and 443 on the node +- Host networking means that traffic hits Envoy without transitioning through any other fancy networking hops +- Contour also binds to 8001 for Envoy->Contour config traffic. + +## Deploying Contour + +1. [Clone the Contour repository][4] and cd into the repo +2. Edit the Envoy service (`02-service-envoy.yaml`) in the `examples/contour` directory: + - Remove the existing annotation: `service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp` + - Add the following annotation: `service.beta.kubernetes.io/aws-load-balancer-type: nlb` +3. Run `kubectl apply -f examples/contour` + +This creates the `projectcontour` Namespace along with a ServiceAccount, RBAC rules, Contour Deployment and an Envoy DaemonSet. +It also creates the NLB based loadbalancer for you. + +You can get the address of your NLB via: + +``` +$ kubectl get service envoy --namespace=projectcontour -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' +``` + +## Test + +You can now test your NLB. + +1. Install a workload (see the kuard example in the [main deployment guide][2]). +2. Look up the address for your NLB in the AWS console and enter it in your browser. + - Notice that Envoy fills out `X-Forwarded-For`, because it was the first to see the traffic directly from the browser. + +[1]: https://aws.amazon.com/blogs/aws/new-network-load-balancer-effortless-scaling-to-millions-of-requests-per-second/ +[2]: ../deploy-options/#testing-your-installation +[3]: https://github.com/kubernetes/kubernetes/issues/52173 +[4]: {{< param github_url >}}/tree/{{< param branch >}} diff --git a/site/content/docs/1.30/guides/deploy-aws-tls-nlb.md b/site/content/docs/1.30/guides/deploy-aws-tls-nlb.md new file mode 100644 index 00000000000..7f4f83f685e --- /dev/null +++ b/site/content/docs/1.30/guides/deploy-aws-tls-nlb.md @@ -0,0 +1,135 @@ +--- +title: AWS Network Load Balancer TLS Termination with Contour +--- + +## Motivation + +![diagram illustrating connection between network load balancer and contour](/img/aws-nlb-tls/fig.jpg){:class="img-fluid"} + +Managing TLS certificates (and related configuration) for production cluster workloads is both time consuming, and high risk. For example, storing multiple copies of a certificate secret key in the cluster may increases the chances of it being compromised. Additionally, TLS can be complicated to configure and implement properly. + +Traditionally, TLS termination at the load balancer step required using more expensive application load balancers (ALBs). AWS introduced TLS termination for network load balancers (NLBs) for enhanced security and cost effectiveness. + +The TLS implementation used by the AWS NLB is formally verified and maintained. Additionally, AWS Certificate Manager (ACM) is used, fully isolating your cluster from access to the private key. + +## Solution Overview + +An external client transmits a request to the NLB. The request is encrypted with TLS using the production (e.g., client facing) certificate, and on port 443. + +The NLB decrypts the request, and transmits it on to Envoy running in your cluster on port 8080. It follows the standard request routing configured within the cluster. Notably, the request received within the cluster includes the actual origin IP address of the external client. + +Alternate ports may be configured. End-to-end encryption technically requires the segment between the NLB and cluster pods be encrypted also. A follow-up post will describe the NLB originating TLS based on a cluster certificate. + +## Steps + +### Prerequisites + +1. Access to DNS records for domain name. + +[Review the docs on registering domains with AWS's Route 53.](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/registrar.html) + +An alternate DNS provider may be used, such as Google Domains or Namecheap. + +Later, a subdomain (e.g., demo-service.gcline.us) will be created, pointing to the NLB. Additionally, access to the DNS records is required to generate a TLS certificate for use by the NLB. + +3. Verify [Contour is installed in the cluster.](https://projectcontour.io/getting-started/) + +4. Install [AWS Load Balancer Controller.]( https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/deploy/installation/) + +Generally, setting up the Load Balancer Controller has two steps: enabling IAM roles for service accounts, and adding the controller to the cluster. The IAM role allows the controller in the Kubernetes cluster to manage AWS resources. [Learn more about IAM roles for service accounts.](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) + +### Configure + +1. Generate TLS Certificate + +Create a public TLS certificate for the domain using AWS Certificate Manager (ACM). This is streamlined when the domain is managed by Route 53. Review the [AWS Certificate Manager Docs.](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html#request-public-console) + +The domain name on the TLS certificate must correspond to the planned domain name for the kubernetes service. The domain name may be specified explicitly (e.g., tls-demo.gcline.us), or a wildcard certificate can be used (e.g., *.gcline.us). + +If the domain is registered with Route53, the TLS certificate request will automatically be approved. Otherwise, follow ACM console the instructions to create a DNS record to validate the domain. + +After validation, the certificate will be available for use in your AWS account. + +Note the ARN of the certificate, which uniquely identifies it in kubernetes config files. + +![screenshot indicating location of ARN value in web console](/img/aws-nlb-tls/acm-arn.png){:class="img-fluid"} + +2. Create Envoy Service with new NLB + +Contour expects a kubernetes service pointing to Envoy. Add annotations to the service to enable NLB TLS termination, before the traffic reaches Envoy. The annotations are actioned by the load balancer controller. [Review all the NLB annotations on GitHub.](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/) + +| annotation name | value | meaning | +| ----- | --- | ----- | +| service.beta.kubernetes.io/aws-load-balancer-type | external | explicitly requires an NLB, instead of an ALB | +| service.beta.kubernetes.io/aws-load-balancer-nlb-target-type | ip | route traffic directly to the pod IP | +| service.beta.kubernetes.io/aws-load-balancer-scheme | internet-facing | An internet-facing load balancer has a publicly resolvable DNS name | +| service.beta.kubernetes.io/aws-load-balancer-ssl-cert | "arn:aws:acm:..." | identifies the TLS certificate used by the NLB | +| service.beta.kubernetes.io/aws-load-balancer-ssl-ports | 443 | determines the port the NLB should listen for TLS traffic on| + +Example: + +``` +apiVersion: v1 +kind: Service +metadata: + name: envoy + namespace: projectcontour + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: external + service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip + service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-east-2:185309785115:certificate/7610ed7d-5a81-4ea2-a18a-7ba1606cca3e" + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" +spec: + externalTrafficPolicy: Local + ports: + - port: 443 + targetPort: 8080 + name: http + protocol: TCP + selector: + app: envoy + type: LoadBalancer +``` + +*Note:* Don't modify an existing service to add NLB TLS termination. This may result in unexpected behavior, such as duplicate NLB resources or incorrect NLB configuration. + +3. Configure DNS + +**Get domain name using kubectl.** + +The service name and namespace were defined above. + +``` +kubectl get svc envoy --namespace projectcontour +``` + +``` +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +envoy LoadBalancer 10.100.24.154 a7ea2bbde8a164036a7e4c1ed5700cdf-154fb911d990bb1f.elb.us-east-2.amazonaws.com 443:31606/TCP 40d +``` + +Note the last 4 digits of the domain name for the NLB. For example, "bb1f". + +**Setup DNS alias for NLB** + +Create a DNS record pointing from a friendly name (e.g., tls-demo.gcline.us) to the NLB domain (e.g., bb1f.elb.us-east-2.amazonaws.com). + +For AWS's Route 53, follow the instructions below. If you use a different DNS provider, follow their instructions for [creating a CNAME record](https://docs.digitalocean.com/products/networking/dns/how-to/manage-records/#cname-records). + +First, create a new record in Route 53. + +Use the "A" record type, and enable the ["alias" option.](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-alias.html) This option attaches the DNS record to the AWS resource, without requiring an extra lookup step for clients. + +Select the NLB resource. Double check the region, and use the last 4 digits (noted earlier) to select the proper resource. + +![screenshot of Route 53 New Record Console](/img/aws-nlb-tls/record.png){:class="img-fluid"} + +### Verify + +Attempt to access the NLB domain at port 443 with HTTPS/TLS. Is the connection successful? What certificate is used? Does it reach the expected endpoint within the cluster? + +### Next Steps + +Create a second TLS certificate within the cluster, for securing connections between the NLB and pods. A guide on this topic is forthcoming. + diff --git a/site/content/docs/1.30/guides/external-authorization.md b/site/content/docs/1.30/guides/external-authorization.md new file mode 100644 index 00000000000..74076ede518 --- /dev/null +++ b/site/content/docs/1.30/guides/external-authorization.md @@ -0,0 +1,538 @@ +--- +title: External Authorization Support +--- + +Starting in version 1.9, Contour supports routing client requests to an +external authorization server. This feature can be used to centralize +client authorization so that applications don't have to implement their +own authorization mechanisms. + +## Authorization Architecture + +An external authorization server is a server that implements the Envoy +external authorization [GRPC protocol][3]. Contour supports any server +that implements this protocol. + +You can bind an authorization server to Contour by creating a +[`ExtensionService`][4] resource. +This resource tells Contour the service exists, and that it should +program Envoy with an upstream cluster directing traffic to it. +Note that the `ExtensionService` resource just binds the server; at this +point Contour doesn't assume that the server is an authorization server. + +Once you have created `ExtensionService` resource, you can bind it to a +particular application by referencing it in a [`HTTPProxy`][5] resource. +In the `virtualhost` field, a new `authorization` field specifies the name +of an `ExtensionService` to bind for the virtual host. +When you specify a resource name here, Contour will program Envoy to +send authorization checks to the extension service cluster before routing +the request to the upstream application. + +## Authorization Request Flow + +It is helpful to have a mental model of how requests flow through the various +servers involved in authorizing HTTP requests. +The flow diagram below shows the actors that participate in the successful +authorization of an HTTP request. +Note that in some cases, these actors can be combined into a single +application server. +For example, there is no requirement for the external authorization server to +be a separate application from the authorization provider. + + +

+client authorization sequence diagram +

+ +A HTTP Client generates an HTTP request and sends it to +an Envoy instance that Contour has programmed with an external +authorization configuration. +Envoy holds the HTTP request and sends an authorization check request +to the Authorization server that Contour has bound to the virtual host. +The Authorization server may be able to verify the request locally, but in +many cases it will need to make additional requests to an Authorization +Provider server to verify or obtain an authorization token. + +In this flow, the ExtAuth server is able to authorize the request, and sends an +authorization response back to the Proxy. +The response includes the authorization status, and a set of HTTP headers +modifications to make to the HTTP request. +Since this authorization was successful, the Proxy modifies the request and +forwards it to the application. +If the authorization was not successful, the Proxy would have immediately +responded to the client with an HTTP error. + +## Using the Contour Authorization Server + +The Contour project has built a simple authorization server named +[`contour-authserver`][1]. `contour-authserver` supports an authorization +testing server, and an HTTP basic authorization server that accesses +credentials stored in [htpasswd][2] format. + +To get started, ensure that Contour is deployed and that you have +[cert-manager][6] installed in your cluster so that you can easily issue +self-signed TLS certificates. + +At this point, we should also create a cluster-wide self-signed certificate +issuer, just to make it easier to provision TLS certificates later: + +```bash +$ kubectl apply -f - <` with the appropriate version of Go and BoringCrypto, see [here][10] for version specifics): + +```bash +make container BUILD_CGO_ENABLED=1 BUILD_BASE_IMAGE=goboring/golang: BUILD_EXTRA_GO_LDFLAGS="-linkmode=external -extldflags=-static" +``` + +The command above can be broken down as follows: +- `make container` invokes the container image build target +- `BUILD_CGO_ENABLED=1` ensures `cgo` is enabled in the Contour compilation process +- `BUILD_BASE_IMAGE=goboring/golang:` ensures we use the BoringCrypto flavor of Go +- `BUILD_EXTRA_GO_LDFLAGS` contains the additional linker flags we need to perform a static build + - `-linkmode=external` tells the Go linker to use an external linker + - `-extldflags=-static"` passes the `-static` flag to the external link to ensure a statically linked executable is produced + +The container image build process should fail before export of the `contour` binary to the final image if the compiled binary is not statically linked. + +### Validation + +To be fully sure the produced `contour` binary has been compiled with BoringCrypto you must remove the `-s` flag from the base Contour `Makefile` to stop stripping symbols and run through the build process above. +Then you will be able to inspect the `contour` binary with `go tool nm` to check for symbols containing the string `_Cfunc__goboringcrypto_`. +Also, you can use the program [rsc.io/goversion][21]. It will report the crypto implementation used by a given binary when invoked with the `-crypto` flag. + +Once you have a `projectcontour/contour` image built, you can re-tag it if needed, push the image to a registry, and reference it in a Contour deployment to use it! + +## Building Envoy + +Envoy has support for building in a FIPS compliant mode as [documented here][11]. +The upstream project does not distribute a FIPS compliant Envoy container image, but combining the documented process with the processes for building the Envoy executable and container image, we can produce one. + +Again we will need the Envoy source code checked out to the version to build and Docker installed on your computer. +The simplest way to build Envoy without having to learn [Bazel][12] and set up a C++ toolchain on your computer is to build using the Envoy build container image which contains the necessary tools pre-installed. +Note that if you do build with FIPS mode outside of the build container, you can only do so on a Linux-amd64 architecture. + +We can first compile the Envoy binary by running the following in a `bash` shell from the Envoy source directory: + +```bash +BAZEL_BUILD_EXTRA_OPTIONS="--define boringssl=fips" ENVOY_DOCKER_BUILD_DIR= ./ci/run_envoy_docker.sh './ci/do_ci.sh bazel.release //test/exe:envoy_static_test' +``` + +*This command mimics the Envoy release CI process with the target `bazel.release` but differs in only running a single test for brevity. You may omit the `//test/exe:envoy_static_test` test entirely to run the full suite of Envoy tests.* + +Replace `` with a directory you would like the build output to be placed on your host computer. + +Once that build completes, you should have a file named `release.tar.zst` in your specified output directory. +This file is a [Zstandard](https://github.com/facebook/zstd) compressed archive containing the compiled Envoy release and debug binaries. +If you would like to build an image with Envoy according to your own specifications, you can unpack the resulting archive and you will find a stripped Envoy binary in the root and an unstripped Envoy binary with debug info in the `dbg` directory. + +To build an image matching the canonical Envoy upstream release image ([`envoyproxy/envoy`][13]), run the following: + +*Note: You will need a recent version of Docker/BuildKit that supports Zstandard decompression.* + +```bash +# Make ./linux/amd64 directories. +mkdir -p ./linux/amd64 +# Copy Zstandard archive from build step. +cp -a /envoy/x64/bin/release.tar.zst ./linux/amd64/release.tar.zst +# Run the Docker image build. +docker build -f ./ci/Dockerfile-envoy --target envoy . +``` + +Once you have an image built, you can tag it as needed, push the image to a registry, and use it in an Envoy deployment. + +## Configuring TLS Ciphers + +Now that we have Contour and Envoy compiled with BoringCrypto, we can turn our attention to ensuring encrypted communication paths in Contour are configured to use FIPS approved cryptographic algorithms. +Using a FIPS flavor of Envoy will do most of the heavy lifting here without any user configuration needed. + +The critical communication paths and how they are set up to be FIPS compliant are enumerated below: +- Contour -> k8s API + - Contour uses [`client-go`][14] to communicate with the k8s API + - `client-go` uses the default Golang cipher suites configuration + - When compiled with BoringCrypto Go, this set of ciphers is FIPS compliant and not configurable by users +- Envoy -> Contour xDS Server, extension services, upstream services + - A FIPS compliant build of Envoy will choose FIPS approved TLS ciphers when negotiating TLS 1.2 as documented [here][15] + - The set of ciphers is not configurable +- TLS client -> Envoy + - As of [Contour 1.13.0][16], the ciphers Envoy will accept as a server when negotiating TLS 1.2 are configurable + - The [default set of ciphers Contour configures][17] includes some ciphers that are not FIPS approved + - Users must configure FIPS approved ciphers from the list [here][15] + +[0]: https://csrc.nist.gov/publications/detail/fips/140/2/final +[1]: https://csrc.nist.gov/projects/testing-laboratories +[2]: https://boringssl.googlesource.com/boringssl/ +[3]: https://boringssl.googlesource.com/boringssl/+/master/crypto/fipsmodule/FIPS.md +[4]: https://go.googlesource.com/go/+/dev.boringcrypto/README.boringcrypto.md +[5]: https://hub.docker.com/r/projectcontour/contour +[6]: https://www.gnu.org/software/make/ +[7]: https://www.docker.com/ +[8]: {{< param github_url >}}/blob/main/Dockerfile +[9]: https://hub.docker.com/r/goboring/golang/ +[10]: https://go.googlesource.com/go/+/dev.boringcrypto/misc/boring/README.md#version-strings +[11]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/ssl.html#fips-140-2 +[12]: https://bazel.build/ +[13]: https://hub.docker.com/r/envoyproxy/envoy +[14]: https://github.com/kubernetes/client-go +[15]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlsparameters-cipher-suites +[16]: https://github.com/projectcontour/contour/releases/tag/v1.13.0 +[17]: https://pkg.go.dev/github.com/projectcontour/contour/pkg/config#pkg-variables +[18]: https://pkg.go.dev/internal/goexperiment@go1.19 +[19]: https://go-boringcrypto.storage.googleapis.com/ +[20]: https://go.googlesource.com/go/+/dev.boringcrypto/misc/boring/README.md#releases +[21]: https://godoc.org/rsc.io/goversion \ No newline at end of file diff --git a/site/content/docs/1.30/guides/gatekeeper.md b/site/content/docs/1.30/guides/gatekeeper.md new file mode 100644 index 00000000000..fa6d01cab41 --- /dev/null +++ b/site/content/docs/1.30/guides/gatekeeper.md @@ -0,0 +1,456 @@ +--- +title: Using Gatekeeper as a validating admission controller with Contour +--- + +This tutorial demonstrates how to use [Gatekeeper](https://github.com/open-policy-agent/gatekeeper) as a validating admission controller for Contour. + +Gatekeeper is a project that enables users to define flexible policies for Kubernetes resources using [Open Policy Agent (OPA)](https://www.openpolicyagent.org/) that are enforced when those resources are created/updated via the Kubernetes API. + +The benefits of using Gatekeeper with Contour are: +- Immediate feedback for the user when they try to create an `HTTPProxy` with an invalid spec. Instead of having to check the `HTTPProxy`'s status after creation for a possible error message, the create is rejected and the user is immediately provided with a reason for the rejection. +- User-defined policies for `HTTPProxy` specs. For example, the Contour admin can define policies to enforce maximum limits on timeouts and retries, disallow certain FQDNs, etc. + +## Prerequisites + +- A Kubernetes cluster with a minimum version of 1.14 (to enable webhook timeouts for Gatekeeper). +- Cluster-admin permissions + +## Deploy Contour + +Run: + +```bash +$ kubectl apply -f {{< param base_url >}}/quickstart/contour.yaml +``` + +This creates a `projectcontour` namespace and sets up Contour as a deployment and Envoy as a daemonset, with communication between them secured by mutual TLS. + +Check the status of the Contour pods with this command: + +```bash +$ kubectl -n projectcontour get pods -l app=contour +NAME READY STATUS RESTARTS AGE +contour-8596d6dbd7-9nrg2 1/1 Running 0 32m +contour-8596d6dbd7-mmtc8 1/1 Running 0 32m +``` + +If installation was successful, all pods should reach `Running` status shortly. + +## Deploy Gatekeeper + +The following instructions are summarized from the [Gatekeeper documentation](https://github.com/open-policy-agent/gatekeeper#installation-instructions). +If you already have Gatekeeper running in your cluster, you can skip this section. + +Run: + +```bash +$ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml +``` + +This creates a `gatekeeper-system` namespace and sets up the Gatekeeper controller manager and audit deployments using the latest Gatekeeper release. + +Check the status of the Gatekeeper pods with this command: + +```bash +$ kubectl -n gatekeeper-system get pods +NAME READY STATUS RESTARTS AGE +gatekeeper-audit-67dfc46db6-kjcmc 1/1 Running 0 40m +gatekeeper-controller-manager-7cbc758844-64hhn 1/1 Running 0 40m +gatekeeper-controller-manager-7cbc758844-c4dkd 1/1 Running 0 40m +gatekeeper-controller-manager-7cbc758844-xv9jn 1/1 Running 0 40m +``` + +If installation was successful, all pods should reach `Running` status shortly. + +## Configure Gatekeeper + +### Background + +Gatekeeper uses the [OPA Constraint Framework](https://github.com/open-policy-agent/frameworks/tree/master/constraint) to define and enforce policies. +This framework has two key types: `ConstraintTemplate` and `Constraint`. +A `ConstraintTemplate` defines a reusable OPA policy, along with the parameters that can be passed to it when it is instantiated. +When a `ConstraintTemplate` is created, Gatekeeper automatically creates a custom resource definition (CRD) to represent it in the cluster. + +A `Constraint` is an instantiation of a `ConstraintTemplate`, which tells Gatekeeper to apply it to specific Kubernetes resource types (e.g. `HTTPProxy`) and provides any relevant parameter values. +A `Constraint` is defined as an instance of the CRD representing the associated `ConstraintTemplate`. + +We'll now look at some examples to make these concepts concrete. + +### Configure resource caching + +First, Gatekeeper needs to be configured to store all `HTTPProxy` resources in its internal cache, so that existing `HTTPProxy` resources can be referenced within constraint template policies. +This is essential for being able to define constraints that look across all `HTTPProxies` -- for example, to verify FQDN uniqueness. + +Create a file called `config.yml` containing the following YAML: + +```yaml +apiVersion: config.gatekeeper.sh/v1alpha1 +kind: Config +metadata: + name: config + namespace: "gatekeeper-system" +spec: + sync: + syncOnly: + - group: "projectcontour.io" + version: "v1" + kind: "HTTPProxy" +``` + +Apply it to the cluster: + +```bash +$ kubectl apply -f config.yml +``` + +Note that if you already had Gatekeeper running in your cluster, you may already have the `Config` resource defined. +In that case, you'll need to edit the existing resource to add `HTTPProxy` to the `spec.sync.syncOnly` list. + +### Configure HTTPProxy validations + +The first constraint template and constraint that we'll define are what we'll refer to as a **validation**. +These are rules for `HTTPProxy` specs that Contour universally requires to be true. +In this example, we'll define a constraint template and constraint to enforce that all `HTTPProxies` must have a unique FQDN. + +Create a file called `unique-fqdn-template.yml` containing the following YAML: + +```yaml +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: httpproxyuniquefqdn +spec: + crd: + spec: + names: + kind: HTTPProxyUniqueFQDN + listKind: HTTPProxyUniqueFQDNList + plural: HTTPProxyUniqueFQDNs + singular: HTTPProxyUniqueFQDN + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package httpproxy.uniquefqdn + + violation[{"msg": msg, "other": sprintf("%v/%v", [other.metadata.namespace, other.metadata.name])}] { + got := input.review.object.spec.virtualhost.fqdn + other := data.inventory.namespace[_]["projectcontour.io/v1"]["HTTPProxy"][_] + other.spec.virtualhost.fqdn = got + + not same(other, input.review.object) + msg := "HTTPProxy must have a unique spec.virtualhost.fqdn" + } + + same(a, b) { + a.metadata.namespace == b.metadata.namespace + a.metadata.name == b.metadata.name + } +``` + +Apply it to the cluster: + +```bash +$ kubectl apply -f unique-fqdn-template.yml +``` + +Within a few seconds, you'll see that a corresponding CRD has been created in the cluster: + +```bash +$ kubectl get crd httpproxyuniquefqdn.constraints.gatekeeper.sh +NAME CREATED AT +httpproxyuniquefqdn.constraints.gatekeeper.sh 2020-08-13T16:08:57Z +``` + +Now, create a file called `unique-fqdn-constraint.yml` containing the following YAML: + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: HTTPProxyUniqueFQDN +metadata: + name: httpproxy-unique-fqdn +spec: + match: + kinds: + - apiGroups: ["projectcontour.io"] + kinds: ["HTTPProxy"] +``` + +Note that the `Kind` of this resource corresponds to the new CRD. + +Apply it to the cluster: + +```bash +$ kubectl apply -f unique-fqdn-constraint.yml +``` + +Now, let's create some `HTTPProxies` to see the validation in action. + +Create a file called `httpproxies.yml` containing the following YAML: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: demo + namespace: default +spec: + virtualhost: + fqdn: demo.projectcontour.io +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: demo2 + namespace: default +spec: + virtualhost: + fqdn: demo.projectcontour.io +``` + +Note that both `HTTPProxies` have the same FQDN. + +Apply the YAML: + +```bash +$ kubectl apply -f httpproxies.yml +``` + +You should see something like: +``` +httpproxy.projectcontour.io/demo created +Error from server ([denied by httpproxy-unique-fqdn] HTTPProxy must have a unique FQDN): error when creating "httpproxies.yml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by httpproxy-unique-fqdn] HTTPProxy must have a unique FQDN +``` + +The first `HTTPProxy` was created successfully, because there was not already an existing proxy with the `demo.projectcontour.io` FQDN. +However, when the second `HTTPProxy` was submitted, Gatekeeper rejected its creation because it used the same FQDN as the first one. + +### Configure HTTPProxy policies + +The next constraint template and constraint that we'll create are what we refer to as a **policy**. +These are rules for `HTTPProxy` specs that an individual Contour administrator may want to enforce for their cluster, but that are not explicitly required by Contour itself. +In this example, we'll define a constraint template and constraint to enforce that all `HTTPProxies` can be configured with at most five retries for any route. + +Create a file called `retry-count-range-template.yml` containing the following YAML: + +```yaml +apiVersion: templates.gatekeeper.sh/v1beta1 +kind: ConstraintTemplate +metadata: + name: httpproxyretrycountrange +spec: + crd: + spec: + names: + kind: HTTPProxyRetryCountRange + listKind: HTTPProxyRetryCountRangeList + plural: HTTPProxyRetryCountRanges + singular: HTTPProxyRetryCountRange + scope: Namespaced + validation: + openAPIV3Schema: + properties: + min: + type: integer + max: + type: integer + targets: + - target: admission.k8s.gatekeeper.sh + rego: | + package httpproxy.retrycountrange + + # build a set of all the retry count values + retry_counts[val] { + val := input.review.object.spec.routes[_].retryPolicy.count + } + + # is there a retry count value that's greater than the allowed max? + violation[{"msg": msg}] { + retry_counts[_] > input.parameters.max + msg := sprintf("retry count must be less than or equal to %v", [input.parameters.max]) + } + + # is there a retry count value that's less than the allowed min? + violation[{"msg": msg}] { + retry_counts[_] < input.parameters.min + msg := sprintf("retry count must be greater than or equal to %v", [input.parameters.min]) + } +``` + +Apply it to the cluster: + +```bash +$ kubectl apply -f retry-count-range-template.yml +``` + +Again, within a few seconds, you'll see that a corresponding CRD has been created in the cluster: + +```bash +$ kubectl get crd httpproxyretrycountrange.constraints.gatekeeper.sh +NAME CREATED AT +httpproxyretrycountrange.constraints.gatekeeper.sh 2020-08-13T16:12:10Z +``` + +Now, create a file called `retry-count-range-constraint.yml` containing the following YAML: + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: HTTPProxyRetryCountRange +metadata: + name: httpproxy-retry-count-range +spec: + match: + kinds: + - apiGroups: ["projectcontour.io"] + kinds: ["HTTPProxy"] + namespaces: + - my-namespace + parameters: + max: 5 +``` + +Note that for this `Constraint`, we've added a `spec.match.namespaces` field which defines that this policy should only be applied to `HTTPProxies` created in the `my-namespace` namespace. +If this `namespaces` matcher is not specified, then the `Constraint` applies to all namespaces. +You can read more about `Constraint` matchers on the [Gatekeeper website](https://github.com/open-policy-agent/gatekeeper#constraints). + +Apply it to the cluster: + +```bash +$ kubectl apply -f retry-count-range-constraint.yml +``` + +Now, let's create some `HTTPProxies` to see the policy in action. + +Create a namespace called `my-namespace`: + +```bash +$ kubectl create namespace my-namespace +namespace/my-namespace created +``` + +Create a file called `httpproxy-retries.yml` containing the following YAML: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: demo-retries + namespace: my-namespace +spec: + virtualhost: + fqdn: retries.projectcontour.io + routes: + - conditions: + - prefix: /foo + services: + - name: s1 + port: 80 + retryPolicy: + count: 6 +``` + +Apply the YAML: + +```bash +$ kubectl apply -f httpproxy-retries.yml +``` + +You should see something like: +``` +Error from server ([denied by httpproxy-retry-count-range] retry count must be less than or equal to 5): error when creating "proxy-retries.yml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by httpproxy-retry-count-range] retry count must be less than or equal to 5 +``` + +Now, change the `count` field on the last line of `httpproxy-retries.yml` to have a value of `5`. Save the file, and apply it again: + +```bash +$ kubectl apply -f httpproxy-retries.yml +``` + +Now the `HTTPProxy` creates successfully*. + +_* Note that the HTTPProxy is still marked invalid by Contour after creation because the service `s1` does not exist, but that's outside the scope of this guide._ + +Finally, create a file called `httpproxy-retries-default.yml` containing the following YAML: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: demo-retries + namespace: default +spec: + virtualhost: + fqdn: default.retries.projectcontour.io + routes: + - conditions: + - prefix: /foo + services: + - name: s1 + port: 80 + retryPolicy: + count: 6 +``` + +Remember that our `Constraint` was defined to apply only to the `my-namespace` namespace, so it should not block the creation of this proxy, even though it has a retry policy count outside the allowed range. + +Apply the YAML: + +```bash +$ kubectl apply -f httpproxy-retries-default.yml +``` + +The `HTTPProxy` creates successfully. + +## Gatekeeper Audit + +We've seen how Gatekeeper constraints can enforce constraints when a user tries to create a new `HTTPProxy`. Now let's look at how constraints can be applied to pre-existing resources in the cluster. + +Gatekeeper has an audit functionality, that periodically (every `60s` by default) checks all existing resources against the relevant set of constraints. Any violations are reported in the `Constraint` custom resource's `status.violations` field. This allows an administrator to periodically review & correct any pre-existing misconfigurations, while not having to worry about breaking existing resources when rolling out a new or updated constraint. + +To try this out, let's revisit the previous example, and change our constraint to allow a maximum retry count of four. + +Edit `retry-count-range-constraint.yml` and change the `max` field to have a value of `4`. Save the file. + +Apply it to the cluster: + +```bash +$ kubectl apply -f retry-count-range-constraint.yml +``` + +We know that the `demo-retries` proxy has a route with a `retryPolicy.count` of `5`. This should now be invalid according to the updated constraint. + +Wait up to `60s` for the next periodic audit to finish, then run: + +```bash +$ kubectl describe httpproxyretrycountrange httpproxy-retry-count-range +``` + +You should see something like: + +``` +... +Status: + ... + Violations: + Enforcement Action: deny + Kind: HTTPProxy + Message: retry policy count must be less than or equal to 4 + Name: demo-retries + Namespace: my-namespace +``` + +However, our `HTTPProxy` remains in the cluster and can continue to route requests, and the user can remediate the proxy to bring it inline with the policy on their own timeline. + +## Next steps + +Contour has a [growing library](https://github.com/projectcontour/contour/tree/main/examples/gatekeeper) of Gatekeeper constraint templates and constraints, for both **validations** and **policies**. + +If you're using Gatekeeper, we recommend that you apply all of the **validations** we've defined, since these rules are already being checked internally by Contour and reported as status errors/invalid proxies. +Using the Gatekeeper constraints will only improve the user experience since users will get earlier feedback if their proxies are invalid. +The **validations** can be found in `examples/gatekeeper/validations`. + + +You should take more of a pick-and-choose approach to our sample **policies**, since every organization will have different policy needs. +Feel free to use any/all/none of them, and augment them with your own policies if applicable. +The sample **policies** can be found in `examples/gatekeeper/policies`. + +And of course, if you do develop any new constraints that you think may be useful for the broader Contour community, we welcome contributions! diff --git a/site/content/docs/1.30/guides/gateway-api.md b/site/content/docs/1.30/guides/gateway-api.md new file mode 100644 index 00000000000..4bcc3140c03 --- /dev/null +++ b/site/content/docs/1.30/guides/gateway-api.md @@ -0,0 +1,212 @@ +--- +title: Using Gateway API with Contour +--- + +This tutorial walks through an example of using [Gateway API][1] with Contour. +See the [Contour reference documentation][5] for more information on Contour's Gateway API support. + +### Prerequisites +The following prerequisites must be met before following this guide: + +- A working [Kubernetes][2] cluster. Refer to the [compatibility matrix][3] for cluster version requirements. +- The [kubectl][4] command-line tool, installed and configured to access your cluster. + +## Deploy Contour with Gateway API enabled + +First, deploy Contour with Gateway API enabled. +This can be done using either [static or dynamic provisioning][6]. + +### Option #1: Statically provisioned + +Create Gateway API CRDs: +```shell +$ kubectl apply -f {{< param github_raw_url>}}/{{< param branch >}}/examples/gateway/00-crds.yaml +``` + +Create a GatewayClass: +```shell +kubectl apply -f - <}}/quickstart/contour.yaml +``` +This command creates: + +- Namespace `projectcontour` to run Contour +- Contour CRDs +- Contour RBAC resources +- Contour Deployment / Service +- Envoy DaemonSet / Service +- Contour ConfigMap + +Update the Contour configmap to enable Gateway API processing by specifying a gateway, and restart Contour to pick up the config change: + +```shell +kubectl apply -f - <}}/quickstart/contour-gateway-provisioner.yaml +``` + +This command creates: + +- Namespace `projectcontour` to run the Gateway provisioner +- Contour CRDs +- Gateway API CRDs +- Gateway provisioner RBAC resources +- Gateway provisioner Deployment + +Create a GatewayClass: + +```shell +kubectl apply -f - <}}/{{< param branch >}}/examples/example-workload/gatewayapi/kuard/kuard.yaml +``` +This command creates: + +- A Deployment named `kuard` in the default namespace to run kuard as the test application. +- A Service named `kuard` in the default namespace to expose the kuard application on TCP port 80. +- An HTTPRoute named `kuard` in the default namespace, attached to the `contour` Gateway, to route requests for `local.projectcontour.io` to the kuard service. + +Verify the kuard resources are available: +```shell +$ kubectl get po,svc,httproute -l app=kuard +NAME READY STATUS RESTARTS AGE +pod/kuard-798585497b-78x6x 1/1 Running 0 21s +pod/kuard-798585497b-7gktg 1/1 Running 0 21s +pod/kuard-798585497b-zw42m 1/1 Running 0 21s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/kuard ClusterIP 172.30.168.168 80/TCP 21s + +NAME HOSTNAMES +httproute.gateway.networking.k8s.io/kuard ["local.projectcontour.io"] +``` + +## Test Routing + +_Note, for simplicity and compatibility across all platforms we'll use `kubectl port-forward` to get traffic to Envoy, but in a production environment you would typically use the Envoy service's address._ + +Port-forward from your local machine to the Envoy service: +```shell +# If using static provisioning +$ kubectl -n projectcontour port-forward service/envoy 8888:80 + +# If using dynamic provisioning +$ kubectl -n projectcontour port-forward service/envoy-contour 8888:80 +``` + +In another terminal, make a request to the application via the forwarded port (note, `local.projectcontour.io` is a public DNS record resolving to 127.0.0.1 to make use of the forwarded port): +```shell +$ curl -i http://local.projectcontour.io:8888 +``` +You should receive a 200 response code along with the HTML body of the main `kuard` page. + +You can also open http://local.projectcontour.io:8888/ in a browser. + +### Further reading + +This guide only scratches the surface of the Gateway API's capabilities. See the [Gateway API website][1] for more information. + + +[1]: https://gateway-api.sigs.k8s.io/ +[2]: https://kubernetes.io/ +[3]: https://projectcontour.io/resources/compatibility-matrix/ +[4]: https://kubernetes.io/docs/tasks/tools/install-kubectl/ +[5]: /docs/{{< param version >}}/config/gateway-api +[6]: /docs/{{< param version >}}/config/gateway-api#enabling-gateway-api-in-contour \ No newline at end of file diff --git a/site/content/docs/1.30/guides/global-rate-limiting.md b/site/content/docs/1.30/guides/global-rate-limiting.md new file mode 100644 index 00000000000..99a3c45d1bc --- /dev/null +++ b/site/content/docs/1.30/guides/global-rate-limiting.md @@ -0,0 +1,503 @@ +--- +title: Global Rate Limiting +--- + +Starting in version 1.13, Contour supports [Envoy global rate limiting][1]. +In global rate limiting, Envoy communicates with an external Rate Limit Service (RLS) over gRPC to make rate limit decisions for each request. +Envoy is configured to produce 1+ descriptors for incoming requests, containing things like the client IP, header values, and more. +Envoy sends descriptors to the RLS, and the RLS returns a rate limiting decision to Envoy based on the descriptors and the RLS's configured rate limits. + +In this guide, we'll walk through deploying an RLS, configuring it in Contour, and configuring an `HTTPProxy` to use it for rate limiting. + +**NOTE: you should not consider the RLS deployment in this guide to be production-ready.** +The instructions and example YAML below are intended to be a demonstration of functionality only. +Each user will have their own unique production requirements for their RLS deployment. + +## Prerequisites + +This guide assumes that you have: + +- A local KinD cluster created using [the Contour guide][2]. +- Contour installed and running in the cluster using the [quick start][3]. + +## Deploy an RLS + +For this guide, we'll deploy the [Envoy rate limit service][4] as our RLS. +Per the project's README: + +> The rate limit service is a Go/gRPC service designed to enable generic rate limit scenarios from different types of applications. +> Applications request a rate limit decision based on a domain and a set of descriptors. +> The service reads the configuration from disk via [runtime][10], composes a cache key, and talks to the Redis cache. +> A decision is then returned to the caller. + +However, any service that implements the [RateLimitService gRPC interface][5] is supported by Contour/Envoy. + +Create a config map with [the ratelimit service configuration][6]: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: ratelimit-config + namespace: projectcontour +data: + ratelimit-config.yaml: | + domain: contour + descriptors: + + # requests with a descriptor of ["generic_key": "foo"] + # are limited to one per minute. + - key: generic_key + value: foo + rate_limit: + unit: minute + requests_per_unit: 1 + + # each unique remote address (i.e. client IP) + # is limited to three requests per minute. + - key: remote_address + rate_limit: + unit: minute + requests_per_unit: 3 +``` + +Create a deployment for the RLS that mounts the config map as a volume. +**This configuration is for demonstration purposes only and is not a production-ready deployment.** +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: ratelimit + name: ratelimit + namespace: projectcontour +spec: + replicas: 1 + selector: + matchLabels: + app: ratelimit + template: + metadata: + labels: + app: ratelimit + spec: + containers: + - name: redis + image: redis:alpine + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis:6379 + - name: ratelimit + image: docker.io/envoyproxy/ratelimit:19f2079f + ports: + - containerPort: 8080 + name: http + protocol: TCP + - containerPort: 8081 + name: grpc + protocol: TCP + volumeMounts: + - name: ratelimit-config + mountPath: /data/ratelimit/config + readOnly: true + env: + - name: USE_STATSD + value: "false" + - name: LOG_LEVEL + value: debug + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: localhost:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_WATCH_ROOT + value: "false" + # need to set RUNTIME_IGNOREDOTFILES to true to avoid issues with + # how Kubernetes mounts configmaps into pods. + - name: RUNTIME_IGNOREDOTFILES + value: "true" + command: ["/bin/ratelimit"] + livenessProbe: + httpGet: + path: /healthcheck + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: ratelimit-config + configMap: + name: ratelimit-config +``` + +Create a service: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: ratelimit + namespace: projectcontour +spec: + ports: + - port: 8081 + name: grpc + protocol: TCP + selector: + app: ratelimit + type: ClusterIP +``` + +Check the progress of the deployment: + +```bash +$ kubectl -n projectcontour get pods -l app=ratelimit +NAME READY STATUS RESTARTS AGE +ratelimit-658f4b8f6b-2hnrf 2/2 Running 0 12s +``` + +Once the pod is `Running` with `2/2` containers ready, move onto the next step. + +## Configure the RLS with Contour + +Create a Contour extension service for the RLS: + +```yaml +apiVersion: projectcontour.io/v1alpha1 +kind: ExtensionService +metadata: + namespace: projectcontour + name: ratelimit +spec: + protocol: h2c + # The service name and port correspond to + # the service we created in the previous + # step. + services: + - name: ratelimit + port: 8081 + timeoutPolicy: + response: 100ms +``` + +Update the Contour configmap to have the following RLS configuration: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: contour + namespace: projectcontour +data: + contour.yaml: | + rateLimitService: + # extensionService is the / + # of the ExtensionService we created in the + # previous step. + extensionService: projectcontour/ratelimit + # domain corresponds to the domain in the + # projectcontour/ratelimit-config config map. + domain: contour + # failOpen is whether to allow requests through + # if there's an error connecting to the RLS. + failOpen: false +``` + +Restart Contour to pick up the new config map: + +```bash +$ kubectl -n projectcontour rollout restart deploy/contour +deployment.apps/contour restarted +``` + +## Deploy a sample app + +To demonstrate how to use global rate limiting in a `HTTPProxy` resource, we first need to deploy a simple echo application: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ingress-conformance-echo +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: ingress-conformance-echo + template: + metadata: + labels: + app.kubernetes.io/name: ingress-conformance-echo + spec: + containers: + - name: conformance-echo + image: agervais/ingress-conformance-echo:latest + ports: + - name: http-api + containerPort: 3000 + readinessProbe: + httpGet: + path: /health + port: 3000 +--- +apiVersion: v1 +kind: Service +metadata: + name: ingress-conformance-echo +spec: + ports: + - name: http + port: 80 + targetPort: http-api + selector: + app.kubernetes.io/name: ingress-conformance-echo +``` + +This echo server will respond with a JSON object that reports information about the HTTP request it received, including the request headers. + +Once the application is running, we can expose it to Contour with a `HTTPProxy` resource: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: ingress-conformance-echo + port: 80 + - conditions: + - prefix: /foo + services: + - name: ingress-conformance-echo + port: 80 +``` + +We can verify that the application is working by requesting any path: + +```bash +$ curl -k http://local.projectcontour.io/test/$((RANDOM)) +{"TestId":"","Path":"/test/22808","Host":"local.projectcontour.io","Method":"GET","Proto":"HTTP/1.1","Headers":{"Accept":["*/*"],"Content-Length":["0"],"User-Agent":["curl/7.75.0"],"X-Envoy-Expected-Rq-Timeout-Ms":["15000"],"X-Envoy-Internal":["true"],"X-Forwarded-For":["172.18.0.1"],"X-Forwarded-Proto":["http"],"X-Request-Id":["8ecb85e1-271b-44b4-9cf0-4859cbaed7a7"],"X-Request-Start":["t=1612903866.309"]}} +``` + +## Add global rate limit policies + +Now that we have a working application exposed by a `HTTPProxy` resource, we can add global rate limiting to it. + +Edit the `HTTPProxy` that we created in the previous step to add rate limit policies to both routes: + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + routes: + - conditions: + - prefix: / + services: + - name: ingress-conformance-echo + port: 80 + rateLimitPolicy: + global: + descriptors: + - entries: + - remoteAddress: {} + - conditions: + - prefix: /foo + services: + - name: ingress-conformance-echo + port: 80 + rateLimitPolicy: + global: + descriptors: + - entries: + - remoteAddress: {} + - entries: + - genericKey: + value: foo +``` + +## Default Global rate limit policy + +Contour supports defining a default global rate limit policy in the `rateLimitService` configuration +which is applied to all virtual hosts unless the host is opted-out by +explicitly setting `disabled` to `true`. This is useful for a single-tenant +setup use-case. This means you don't have to edit all HTTPProxy objects with the same rate limit policies, instead you can +define the policies in the `rateLimitService` configuration like this: +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: contour + namespace: projectcontour +data: + contour.yaml: | + rateLimitService: + extensionService: projectcontour/ratelimit + domain: contour + failOpen: false + defaultGlobalRateLimitPolicy: + descriptors: + - entries: + - requestHeader: + headerName: X-Custom-Header + descriptorKey: CustomHeader +``` + +Virtual host can opt out by setting `disabled` to `true`. +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + global: + disabled: true + routes: + - conditions: + - prefix: / + services: + - name: ingress-conformance-echo + port: 80 +``` + +Also, the default global rate limit policy is not applied in case the virtual host defines its own global rate limit policy. +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: local.projectcontour.io + rateLimitPolicy: + global: + descriptors: + - entries: + - remoteAddress: {} + routes: + - conditions: + - prefix: / + services: + - name: ingress-conformance-echo + port: 80 +``` + +## Make requests + +Before making requests to our `HTTPProxy`, let's quickly revisit the `ratelimit-config` config map. +Here's what we defined: + +```yaml +... +descriptors: + # requests with a descriptor of ["generic_key": "foo"] + # are limited to one per minute. + - key: generic_key + value: foo + rate_limit: + unit: minute + requests_per_unit: 1 + + # each unique remote address (i.e. client IP) + # is limited to three total requests per minute. + - key: remote_address + rate_limit: + unit: minute + requests_per_unit: 3 +``` + +The first entry says that requests with a descriptor of `["generic_key": "foo"]` should be limited to one per minute. +The second entry says that each unique remote address (client IP) should be allowed three total requests per minute. +All relevant rate limits are applied for each request, and requests that result in a `429 (Too Many Requests)` count against limits. + +So, we should be able to make: +- a first request to `local.projectcontour.io/foo` that get a `200 (OK)` response +- a second request to `local.projectcontour.io/foo` that gets a `429 (Too Many Requests)` response (due to the first rate limit) +- a third request to `local.projectcontour.io/bar`that gets a `200 (OK)` response +- a fourth request to `local.projectcontour.io/bar`that gets a `429 (Too Many Requests)` response (due to the second rate limit) + +Let's try it out (remember, you'll need to make all of these requests within 60 seconds since the rate limits are per minute): + +Request #1: +``` +$ curl -I local.projectcontour.io/foo + +HTTP/1.1 200 OK +content-type: application/json +date: Mon, 08 Feb 2021 22:25:06 GMT +content-length: 403 +x-envoy-upstream-service-time: 4 +vary: Accept-Encoding +server: envoy +``` + +Request #2: + +``` +$ curl -I local.projectcontour.io/foo + +HTTP/1.1 429 Too Many Requests +x-envoy-ratelimited: true +date: Mon, 08 Feb 2021 22:59:10 GMT +server: envoy +transfer-encoding: chunked +``` + +Request #3: + +``` +$ curl -I local.projectcontour.io/bar + +HTTP/1.1 200 OK +content-type: application/json +date: Mon, 08 Feb 2021 22:59:54 GMT +content-length: 404 +x-envoy-upstream-service-time: 2 +vary: Accept-Encoding +server: envoy +``` + +Request #4: + +``` +$ curl -I local.projectcontour.io/bar + +HTTP/1.1 429 Too Many Requests +x-envoy-ratelimited: true +date: Mon, 08 Feb 2021 23:00:28 GMT +server: envoy +transfer-encoding: chunked +``` + +## Wrapping up + +For more information, see the [Contour rate limiting documentation][7] and the [API reference documentation][8]. + +The YAML used in this guide is available [in the Contour repository][9]. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting +[2]: ../deploy-options/#kind +[3]: https://projectcontour.io/getting-started/#option-1-quickstart +[4]: https://github.com/envoyproxy/ratelimit +[5]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ratelimit/v3/rls.proto +[6]: https://github.com/envoyproxy/ratelimit#configuration +[7]: ../config/rate-limiting/ +[8]: ../config/api/ +[9]: {{< param github_url>}}/tree/main/examples/ratelimit +[10]: https://github.com/lyft/goruntime diff --git a/site/content/docs/1.30/guides/grpc.md b/site/content/docs/1.30/guides/grpc.md new file mode 100644 index 00000000000..acdec3ca203 --- /dev/null +++ b/site/content/docs/1.30/guides/grpc.md @@ -0,0 +1,225 @@ +--- +title: Configuring ingress to gRPC services with Contour +--- + +## Example gRPC Service + +The below examples use the [gRPC server][1] used in Contour end to end tests. +The server implements a service `yages.Echo` with two methods `Ping` and `Reverse`. +It also implements the [gRPC health checking service][2] (see [here][3] for more details) and is bundled with the [gRPC health probe][4]. + +An example base deployment and service for a gRPC server utilizing plaintext HTTP/2 are provided here: + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: grpc-echo + name: grpc-echo +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: grpc-echo + template: + metadata: + labels: + app.kubernetes.io/name: grpc-echo + spec: + containers: + - name: grpc-echo + image: ghcr.io/projectcontour/yages:v0.1.0 + ports: + - name: grpc + containerPort: 9000 + readinessProbe: + exec: + command: ["/grpc-health-probe", "-addr=localhost:9000"] +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: grpc-echo + name: grpc-echo +spec: + selector: + app.kubernetes.io/name: grpc-echo + ports: + - port: 9000 + protocol: TCP + targetPort: grpc +``` + +## HTTPProxy Configuration + +Configuring proxying to a gRPC service with HTTPProxy is as simple as specifying the protocol Envoy uses with the upstream application via the `spec.routes[].services[].protocol` field. +For example, in the resource below, for proxying plaintext gRPC to the `yages` sample app, the protocol is set to `h2c` to denote HTTP/2 over cleartext. +For TLS secured gRPC, the protocol used would be `h2`. + +Route path prefix matching can be used to match a specific gRPC message if required. + +```yaml +--- +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: my-grpc-service +spec: + virtualhost: + fqdn: my-grpc-service.foo.com + routes: + - conditions: + - prefix: /yages.Echo/Ping # Matches a specific gRPC method. + services: + - name: grpc-echo + port: 9000 + protocol: h2c + - conditions: + - prefix: / # Matches everything else. + services: + - name: grpc-echo + port: 9000 + protocol: h2c +``` + +Using the sample deployment above along with this HTTPProxy example, you can test calling this plaintext gRPC server with the following [grpcurl][5] command: + +``` +grpcurl -plaintext -authority=my-grpc-service.foo.com yages.Echo/Ping +``` + +If implementing a streaming RPC, it is likely you will need to adjust per-route timeouts to ensure streams are kept alive for the appropriate durations needed. +Relevant timeout fields to adjust include the HTTPProxy `spec.routes[].timeoutPolicy.response` field which defaults to 15s and should be increased as well as the global timeout policy configurations in the Contour configuration file `timeouts.request-timeout` and `timeouts.max-connection-duration`. + +## Ingress v1 Configuration + +To configure routing for gRPC requests with Ingress v1, you must add an annotation on the upstream Service resource as below. + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: grpc-echo + annotations: + projectcontour.io/upstream-protocol.h2c: "9000" + name: grpc-echo +spec: + selector: + app.kubernetes.io/name: grpc-echo + ports: + - port: 9000 + protocol: TCP + targetPort: grpc +``` + +The annotation key must follow the form `projectcontour.io/upstream-protocol.{protocol}` where `{protocol}` is `h2c` for plaintext gRPC or `h2` for TLS encrypted gRPC to the upstream application. +The annotation value contains a comma-separated list of port names and/or numbers that must match with the ones defined in the Service definition. + +Using the Service above with the Ingress resource below should achieve the same configuration as with an HTTPProxy. + +```yaml +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: my-grpc-service +spec: + rules: + - host: my-grpc-service.foo.com + http: + paths: + - path: / + backend: + service: + name: grpc-echo + port: + number: 9000 + pathType: Prefix +``` + +## Gateway API Configuration + +Gateway API supports a specific resource [GRPCRoute][6] for routing gRPC requests. + +Configuring GRPCRoute for routing gRPC requests needs to specify parentRefs, hostnames, and routing rules with specific backendRefs. In the below example, route path matching is conducted via method matching rule for declared services and their methods. + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: GRPCRoute +metadata: + name: yages +spec: + parentRefs: + - namespace: projectcontour + name: contour + hostnames: + - my-grpc-service.foo.com + rules: + - matches: + - method: + service: yages.Echo + method: Ping + - method: + service: grpc.reflection.v1alpha.ServerReflection + method: ServerReflectionInfo + backendRefs: + - name: grpc-echo + port: 9000 +``` +Using the sample deployment above along with this GRPCRoute example, you can test calling this plaintext gRPC server with the same grpcurl command: + +```yaml +grpcurl -plaintext -authority=my-grpc-service.foo.com yages.Echo/Ping +``` +Note that the second matching method for service of ServerReflection is required by grpcurl command. + +When using GRPCRoute, user should annotate their Service similarly to when using Ingress Configuration, to indicate the protocol to use when connecting to the backend Service, i.e. h2c for HTTP plaintext and h2 for TLS encrypted HTTPS. If it's not specified, Contour will infer the protocol based on the Gateway Listener protocol, h2c for HTTP and h2 for HTTPS. + + + + +## gRPC-Web + +Contour configures Envoy to automatically convert [gRPC-Web][7] HTTP/1 requests to gRPC over HTTP/2 RPC calls to an upstream service. +This is a convenience addition to make usage of gRPC web application client libraries and the like easier. + +Note that you still must provide configuration of the upstream protocol to have gRPC-Web requests converted to gRPC to the upstream app. +If your upstream application does not in fact support gRPC, you may get a protocol error. +In that case, please see [this issue][8]. + +For example, with the example deployment and routing configuration provided above, an example HTTP/1.1 request and response via `curl` looks like: + +``` +curl \ + -s -v \ + /yages.Echo/Ping \ + -XPOST \ + -H 'Host: my-grpc-service.foo.com' \ + -H 'Content-Type: application/grpc-web-text' \ + -H 'Accept: application/grpc-web-text' \ + -d'AAAAAAA=' +``` + +This `curl` command sends and receives gRPC messages as base 64 encoded text over HTTP/1.1. +Piping the output to `base64 -d | od -c` we can see the raw text gRPC response: + +``` +0000000 \0 \0 \0 \0 006 \n 004 p o n g 200 \0 \0 \0 036 +0000020 g r p c - s t a t u s : 0 \r \n g +0000040 r p c - m e s s a g e : \r \n +0000056 +``` + +[1]: https://github.com/projectcontour/yages +[2]: https://pkg.go.dev/google.golang.org/grpc/health/grpc_health_v1 +[3]: https://github.com/grpc/grpc/blob/master/doc/health-checking.md +[4]: https://github.com/grpc-ecosystem/grpc-health-probe +[5]: https://github.com/fullstorydev/grpcurl +[6]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GRPCRoute +[7]: https://github.com/grpc/grpc-web +[8]: https://github.com/projectcontour/contour/issues/4290 diff --git a/site/content/docs/1.30/guides/health-checking.md b/site/content/docs/1.30/guides/health-checking.md new file mode 100644 index 00000000000..8e7bcdb5bb5 --- /dev/null +++ b/site/content/docs/1.30/guides/health-checking.md @@ -0,0 +1,11 @@ +--- +title: Health Checking +--- + +Contour exposes two health endpoints `/health` and `/healthz`. By default these paths are serviced by `0.0.0.0:8000` and are configurable using the `--health-address` and `--health-port` flags. + +e.g. `--health-port 9999` would create a health listener of `0.0.0.0:9999` + +**Note:** the `Service` deployment manifest when installing Contour must be updated to represent the same port as the above configured flags. + +The health endpoints perform a connection to the Kubernetes cluster's API. diff --git a/site/content/docs/1.30/guides/kind.md b/site/content/docs/1.30/guides/kind.md new file mode 100644 index 00000000000..dcc374b70af --- /dev/null +++ b/site/content/docs/1.30/guides/kind.md @@ -0,0 +1,63 @@ +--- +title: Creating a Contour-compatible kind cluster +--- + +This guide walks through creating a kind (Kubernetes in Docker) cluster on your local machine that can be used for developing and testing Contour. + +# Prerequisites + +Download & install Docker and kind: + +- Docker [installation information](https://docs.docker.com/desktop/#download-and-install) +- kind [download and install instructions](https://kind.sigs.k8s.io/docs/user/quick-start/) + +# Kind configuration file + +Create a kind configuration file locally. +This file will instruct kind to create a cluster with one control plane node and one worker node, and to map ports 80 and 443 on your local machine to ports 80 and 443 on the worker node container. +This will allow us to easily get traffic to Contour/Envoy running inside the kind cluster from our local machine. + +Copy the text below into the local yaml file `kind-config.yaml`: + +```yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: worker + extraPortMappings: + - containerPort: 80 + hostPort: 80 + listenAddress: "0.0.0.0" + - containerPort: 443 + hostPort: 443 + listenAddress: "0.0.0.0" +``` + +# Kubernetes cluster using kind + +Create a kind cluster using the config file from above: + +```yaml +$ kind create cluster --config kind-config.yaml +``` + +Verify the nodes are ready by running: + +```yaml +$ kubectl get nodes +``` + +You should see 2 nodes listed with status **Ready**: +- kind-control-plane +- kind-worker + +Congratulations, you have created your cluster environment. You're ready to install Contour. + +_Note:_ When you are done with the cluster, you can delete it by running: +```yaml +$ kind delete cluster +``` + +# Next Steps +See https://projectcontour.io/getting-started/ for how to install Contour into your kind cluster. diff --git a/site/content/docs/1.30/guides/metrics/table.md b/site/content/docs/1.30/guides/metrics/table.md new file mode 100644 index 00000000000..89405d815c6 --- /dev/null +++ b/site/content/docs/1.30/guides/metrics/table.md @@ -0,0 +1,20 @@ +| Name | Type | Labels | Description | +| ---- | ---- | ------ | ----------- | +| contour_build_info | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | branch, revision, version | Build information for Contour. Labels include the branch and git SHA that Contour was built from, and the Contour version. | +| contour_cachehandler_onupdate_duration_seconds | [SUMMARY](https://prometheus.io/docs/concepts/metric_types/#summary) | | Histogram for the runtime of xDS cache regeneration. | +| contour_dag_cache_object | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | kind | Total number of items that are currently in the DAG cache. | +| contour_dagrebuild_seconds | [SUMMARY](https://prometheus.io/docs/concepts/metric_types/#summary) | | Duration in seconds of DAG rebuilds | +| contour_dagrebuild_timestamp | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | | Timestamp of the last DAG rebuild. | +| contour_dagrebuild_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | | Total number of times DAG has been rebuilt since startup | +| contour_eventhandler_operation_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind, op | Total number of Kubernetes object changes Contour has received by operation and object kind. | +| contour_httpproxy | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace | Total number of HTTPProxies that exist regardless of status. | +| contour_httpproxy_invalid | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace, vhost | Total number of invalid HTTPProxies. | +| contour_httpproxy_orphaned | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace | Total number of orphaned HTTPProxies which have no root delegating to them. | +| contour_httpproxy_root | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace | Total number of root HTTPProxies. Note there will only be a single root HTTPProxy per vhost. | +| contour_httpproxy_valid | [GAUGE](https://prometheus.io/docs/concepts/metric_types/#gauge) | namespace, vhost | Total number of valid HTTPProxies. | +| contour_status_update_conflict_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status update conflicts encountered by object kind. | +| contour_status_update_duration_seconds | [SUMMARY](https://prometheus.io/docs/concepts/metric_types/#summary) | error, kind | How long a status update takes to finish. | +| contour_status_update_failed_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status updates that failed by object kind. | +| contour_status_update_noop_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status updates that are no-ops by object kind. This is a subset of successful status updates. | +| contour_status_update_success_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Number of status updates that succeeded by object kind. | +| contour_status_update_total | [COUNTER](https://prometheus.io/docs/concepts/metric_types/#counter) | kind | Total number of status updates by object kind. | diff --git a/site/content/docs/1.30/guides/prometheus.md b/site/content/docs/1.30/guides/prometheus.md new file mode 100644 index 00000000000..87d1a514ab3 --- /dev/null +++ b/site/content/docs/1.30/guides/prometheus.md @@ -0,0 +1,81 @@ +--- +title: Collecting Metrics with Prometheus +--- + + + +## Envoy Metrics + +Envoy typically [exposes metrics](https://www.envoyproxy.io/docs/envoy/v1.15.0/configuration/http/http_conn_man/stats#config-http-conn-man-stats) through an endpoint on its admin interface. To +avoid exposing the entire admin interface to Prometheus (and other workloads in +the cluster), Contour configures a static listener that sends traffic to the +stats endpoint and nowhere else. + +Envoy supports Prometheus-compatible `/stats/prometheus` endpoint for metrics on +port `8002`. + +## Contour Metrics + +Contour exposes a Prometheus-compatible `/metrics` endpoint that defaults to listening on port 8000. This can be configured by using the `--http-address` and `--http-port` flags for the `serve` command. + +**Note:** the `Service` deployment manifest when installing Contour must be updated to represent the same port as the configured flag. + +**The metrics endpoint exposes the following metrics:** + +{{% metrics-table %}} + +## Deploy Sample Monitoring Stack + +Follow the instructions [here][0] to install a monitoring stack to your cluster using the [kube-prometheus][1] project sample manifests. +These instructions install the [Prometheus Operator][2], a [Prometheus][3] instance, a [Grafana][4] `Deployment`, and other components. +Note that this is a quickstart installation, see documentation [here][5] for more details on customizing the installation for production usage. + +The instructions above show how to access the Prometheus and Grafana web interfaces using `kubectl port-forward`. +Sample `HTTPProxy` resources in the `examples/` directory can also be used to access these through your Contour installation: + +```sh +$ kubectl apply -f examples/prometheus/httpproxy.yaml +$ kubectl apply -f examples/grafana/httpproxy.yaml +``` + +### Scrape Contour and Envoy metrics + +To enable Prometheus to scrape metrics from the Contour and Envoy pods, we can add some RBAC customizations with a `Role` and `RoleBinding` in the `projectcontour` namespace: + +```sh +kubectl apply -f examples/prometheus/rbac.yaml +``` + +Now add [`PodMonitor`][6] resources for scraping metrics from Contour and Envoy pods in the `projectcontour` namespace: + +```sh +kubectl apply -f examples/prometheus/podmonitors.yaml +``` + +You should now be able to browse Contour and Envoy Prometheus metrics in the Prometheus and Grafana web interfaces to create dashboards and alerts. + +### Apply Contour and Envoy Grafana Dashboards + +Some sample Grafana dashboards are provided as `ConfigMap` resources in the `examples/grafana` directory. +To use them with your Grafana installation, apply the resources: + +```sh +$ kubectl apply -f examples/grafana/dashboards.yaml +``` + +And update the Grafana `Deployment`: + +```sh +$ kubectl -n monitoring patch deployment grafana --type=json --patch-file examples/grafana/deployment-patch.json +``` + +You should now see dashboards for Contour and Envoy metrics available in the Grafana web interface. + + +[0]: https://prometheus-operator.dev/docs/prologue/quick-start/ +[1]: https://github.com/prometheus-operator/kube-prometheus +[2]: https://github.com/prometheus-operator/prometheus-operator +[3]: https://prometheus.io/ +[4]: https://grafana.com/ +[5]: https://github.com/prometheus-operator/kube-prometheus?tab=readme-ov-file#getting-started +[6]: https://prometheus-operator.dev/docs/operator/design/#podmonitor diff --git a/site/content/docs/1.30/guides/proxy-proto.md b/site/content/docs/1.30/guides/proxy-proto.md new file mode 100644 index 00000000000..7753d8c5776 --- /dev/null +++ b/site/content/docs/1.30/guides/proxy-proto.md @@ -0,0 +1,53 @@ +--- +title: How to Configure PROXY v1/v2 Support +--- + +If you deploy Contour as a Deployment or Daemonset, you will likely use a `type: LoadBalancer` Service to request an [external load balancer][1] from your hosting provider. +If you use the Elastic Load Balancer (ELB) service from Amazon's EC2, you need to perform a couple of additional steps to enable the [PROXY][0] protocol. Here's why: + +External load balancers typically operate in one of two modes: a layer 7 HTTP proxy, or a layer 4 TCP proxy. +The former cannot be used to load balance TLS traffic, because your cloud provider attempts HTTP negotiation on port 443. +So the latter must be used when Contour handles HTTP and HTTPS traffic. + +However this leads to a situation where the remote IP address of the client is reported as the inside address of your cloud provider's load balancer. +To rectify the situation, you can add annotations to your service and flags to your Contour Deployment or DaemonSet to enable the [PROXY][0] protocol which forwards the original client IP details to Envoy. + +## Enable PROXY protocol on your service in GKE + +In GKE clusters a `type: LoadBalancer` Service is provisioned as a Network Load Balancer and will forward traffic to your Envoy instances with their client addresses intact. +Your services should see the addresses in the `X-Forwarded-For` or `X-Envoy-External-Address` headers without having to enable a PROXY protocol. + +## Enable PROXY protocol on your service in AWS + +To instruct EC2 to place the ELB into `tcp`+`PROXY` mode, add the following annotations to the `contour` Service: + +``` +apiVersion: v1 +kind: Service +metadata: + annotations: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' + name: contour + namespace: projectcontour +spec: + type: LoadBalancer +... +``` + +## Enable PROXY protocol support for all Envoy listening ports + +``` +... +spec: + containers: + - image: ghcr.io/projectcontour/contour: + imagePullPolicy: Always + name: contour + command: ["contour"] + args: ["serve", "--incluster", "--use-proxy-protocol"] +... +``` + +[0]: http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt +[1]: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer \ No newline at end of file diff --git a/site/content/docs/1.30/guides/resource-limits.md b/site/content/docs/1.30/guides/resource-limits.md new file mode 100644 index 00000000000..a531221a88f --- /dev/null +++ b/site/content/docs/1.30/guides/resource-limits.md @@ -0,0 +1,161 @@ +--- +title: Contour / Envoy Resource Limits +--- + +## Performance Testing Contour / Envoy + +- Cluster Specs + - Kubernetes + - Version: v1.12.6 + - Nodes: + - 5 Worker Nodes + - 2 CPUs Per Node + - 8 GB RAM Per Node + - 10 GB Network + - Contour + - Single Instance + - 4 Instances of Envoy running in a Daemonset + - Each instance of Envoy is running with HostNetwork + - Cluster Network Bandwidth + +Having a good understanding of the available bandwidth is key when it comes to analyzing performance. It will give you a sense of how many requests per second you can expect to push through the network you are working with. + +Use iperf3 to figure out the bandwidth available between two of the kubernetes nodes. The following will deploy an iperf3 server on one node, and an iperf3 client on another node: + +```bash +[ ID] Interval Transfer Bandwidth Retr +[ 4] 0.00-60.00 sec 34.7 GBytes 4.96 Gbits/sec 479 sender +[ 4] 0.00-60.00 sec 34.7 GBytes 4.96 Gbits/sec receiver +``` + +## Memory / CPU usage + +Verify the Memory & CPU usage with varying numbers of services, IngressRoute resources, and traffic load into the cluster. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test CriteriaContourEnvoy
#Svc#IngRPSCCMemory (MB)CPU% / CoreMemory (MB)CPU% / Core
0000100150
5k000462%150%
10k000773%2052%
05k00361%2302%
010k00631%101%
5k5k002441%2211%
10k10k0026006%4304%
0030k60081%173%
00100k10k101%11814%
00200k20k91%19131%
00300k30k101%22540%
diff --git a/site/content/docs/1.30/img/archoverview.png b/site/content/docs/1.30/img/archoverview.png new file mode 100644 index 00000000000..f79bbfe1b4b Binary files /dev/null and b/site/content/docs/1.30/img/archoverview.png differ diff --git a/site/content/docs/1.30/img/contour_deployment_in_k8s.png b/site/content/docs/1.30/img/contour_deployment_in_k8s.png new file mode 100644 index 00000000000..add5e554a07 Binary files /dev/null and b/site/content/docs/1.30/img/contour_deployment_in_k8s.png differ diff --git a/site/content/docs/1.30/img/shutdownmanager.png b/site/content/docs/1.30/img/shutdownmanager.png new file mode 100644 index 00000000000..ab8b7821d3c Binary files /dev/null and b/site/content/docs/1.30/img/shutdownmanager.png differ diff --git a/site/content/docs/1.30/img/source/shutdownmanager.drawio b/site/content/docs/1.30/img/source/shutdownmanager.drawio new file mode 100644 index 00000000000..99b86620c42 --- /dev/null +++ b/site/content/docs/1.30/img/source/shutdownmanager.drawio @@ -0,0 +1 @@ +7Vtbc9o4FP41zOw+kLF84fKYG2236ZTZZKbNo7AFdiNbVBYJ9NfvkS3fjQ3EYWlKXmIdyUdC33duEvSMa3/9geOl+4U5hPZ0zVn3jJueriNkIvgnJZtYMhqYsWDBPUcNygT33i+ihJqSrjyHhIWBgjEqvGVRaLMgILYoyDDn7KU4bM5ocdYlXpCK4N7GtCr95jnCTT6XpmUdH4m3cNXUI0t1zLD9tOBsFaj5eroxj/7ibh8nutT40MUOe8mJjNuecc0ZE/GTv74mVO5tsm3xe5Mtvem6OQnELi8MZ3iGkW3ObH04N2daX481PGO6UntxGzyzjVqt2CQ7BAtfyseVT++8OaFeAK2rJeGeTwTh0EOVeJrJrl5cT5D7Jbblqy/AHZC5wqfQQvAIcAoMr/C0TSleht4smlUDCSf2iofeM/mXhDFrpJSthJzpOmVDNFSiQBylKt3oWK/v2WoYxTNCr1LYrhllcvqARR8oFJw9pRyQ785hjRPse1RS+25lew6GnYGpQyZXGfUrQiOA8wpTbxFAwwZEoj2oQqRQeyZckHVOpCD7QBjsHwcMNNVrJjxMzEs1X3JcTYa4OZoOEiFW9rFIVWccgQdFkx0pkxhtjjMVuuRAXjIvENH81lXPuimxhnHhsgULMM3zJsNSy2OpnR6WWw1qd3CtIraoBtsqtOZw/AbQGhVk792VgM0PQPoFB+AG+dk1dEanBcVhqCbvwE1Y1km5iSqZzm6iYmkHu4k6bGvcxKgDaBff6cPPZ775yZxBXzy6/6zNSR9ZFXinLHrt65IE8X5JE/Rg25pwlzvgQSZ2qTZxxoRgPnSQwLmUqZ2UUWY/tQK5L2yEziLtyQqkyIG0UC0zo9xtJr0Cn/OcepLdcZaKd0FZuxho5riAtGpxQrEAb1fMfWtQVbqn0p620scYDIoaQrbiNlEv5RPIZj2mZhX1CMwXRFT0AJJ4kxumrH3rcvuolPIkC962rsoLycoyjsdrKL2eLIjN5yERvbJVpAgd5gNHNS5wQIUiIzwv5PPnFdBaTh53wSz53nO8PaVUHILlCcXY8TnEbne9o32xPaVMHKEKtFMOUYgtZTRZEzs6DfF9HDjw9Jc0X/Dgsi8u37VQJe5/n2jwzUXaKBDng2xdZA5gR7+DrK9d6En7UbLvwhiaieBmrfgYtzb5Vo7VzQl3HMJastrdA7pmIrOTEG6gUgw3Sy5l1xhujbVmRVuC+LGiZrJfOe5/fHiYgh5delHt6+f3wWkHh25DLqkIEqPanF42Una0L2Mt9EaMhcUdytjxRYuqjhJPs2QbyTzbVmaUam7Lahlf1l8cf5Q0tbaeG1ZsTh0EazccEsPfoqDb0/62mlyrqbzSLqxxqYpCB3py02pRtMUquiJNNf+8g10JSAgM0aaczUhS1Mx4Vs9MXIKpcH+9cxY1OuU90wjIetDQ0gtg9y2jIy89LOhFY3QgG80WRa15RfJpLbP+k769G6zJu7eV7DyAbFIS/XL66Vy7/wa1O0JFAzpq7V7PNr2GbX9qAd9sj7/vQXm1mnkg3PcCLIiMkszpKg6mNXJa8z7uhO67zbPQsFToHppnGeXT6CPnWWhQ4VB2GhTXxtpHxp7gH3j4JSBHXksqJm9xSjUqdCsejGRr7YmUbfAcn8ZAats13w7nTy57QokneW22pJcKPkM/LMkpn8JUFLWS8wjZUPUCI6kKJ9ijEd2w4xUT/k54d0InM7C4iSf3rfnYsJWMSTI77IaHWjHZNvemT+IkBy2KjnsaWMvDxOYKl80QN7U0kp6D6FsF0YrDK2dKux9WtCh64yCq15V25xOIN6ZPK+o7nwGPjkYfM+gPfiB0F5DBT/poDb0f80/9pgu5Qgr2HiiV5nYX40J2ZxpD1c6u2mRjk2vsfNHWeLMx/n+8mzHsyLtVFB03jNZSeL/Thj+TraXUL7t1lnlS4d5ZaT+xe+fXuutBhcYXhm4cZhOVi+YObWLvi70t9ll78daVwdV9BXYSpl+pLtmexPZOGlLxeLdydFY2TN9znMg0uDzdxdmxb/W8sEq+RkdRPnRLf4GjJunlf8VSf5lsmGOl7ZXM7MvvUqAChv3yMcwhrhOa2e9v4uHZj5yM2/8A \ No newline at end of file diff --git a/site/content/docs/1.30/redeploy-envoy.md b/site/content/docs/1.30/redeploy-envoy.md new file mode 100644 index 00000000000..2456b53d2bf --- /dev/null +++ b/site/content/docs/1.30/redeploy-envoy.md @@ -0,0 +1,72 @@ +# Redeploying Envoy + +The Envoy process, the data path component of Contour, at times needs to be re-deployed. +This could be due to an upgrade, a change in configuration, or a node-failure forcing a redeployment. + +When implementing this roll out, the following steps should be taken: + +1. Stop Envoy from accepting new connections +2. Start draining existing connections in Envoy by sending a `POST` request to `/healthcheck/fail` endpoint +3. Wait for connections to drain before allowing Kubernetes to `SIGTERM` the pod + +## Overview + +Contour implements an `envoy` sub-command named `shutdown-manager` whose job is to manage a single Envoy instances lifecycle for Kubernetes. +The `shutdown-manager` runs as a new container alongside the Envoy container in the same pod. +It uses a Kubernetes `preStop` event hook to keep the Envoy container running while waiting for connections to drain. The `/shutdown` endpoint blocks until the connections are drained. + +```yaml + - name: shutdown-manager + command: + - /bin/contour + args: + - envoy + - shutdown-manager + image: ghcr.io/projectcontour/contour:main + imagePullPolicy: Always + lifecycle: + preStop: + exec: + command: + - /bin/contour + - envoy + - shutdown +``` + +The Envoy container also has some configuration to implement the shutdown manager. +First the `preStop` hook is configured to use the `/shutdown` endpoint which blocks the Envoy container from exiting. +Finally, the pod's `terminationGracePeriodSeconds` is customized to extend the time in which Kubernetes will allow the pod to be in the `Terminating` state. +The termination grace period defines an upper bound for long-lived sessions. +If during shutdown, the connections aren't drained to the configured amount, the `terminationGracePeriodSeconds` will send a `SIGTERM` to the pod killing it. + +![shutdown-manager overview][1] + +### Shutdown Manager Config Options + +The `shutdown-manager` runs as another container in the Envoy pod. +When the pod is requested to terminate, the `preStop` hook on the `shutdown-manager` executes the `contour envoy shutdown` command initiating the shutdown sequence. + +The shutdown manager has a single argument that can be passed to change how it behaves: + +| Name | Type | Default | Description | +|------------|------|---------|-------------| +|
serve-port | integer | 8090 | Port to serve the http server on | +| ready-file | string | /admin/ok | File to poll while waiting shutdown to be completed. | + +### Shutdown Config Options + +The `shutdown` command does the work of draining connections from Envoy and polling for open connections. + +The shutdown command has a few arguments that can be passed to change how it behaves: + +| Name | Type | Default | Description | +|------------|------|---------|-------------| +| check-interval | duration | 5s | Time interval to poll Envoy for open connections. | +| check-delay | duration | 0s | Time wait before polling Envoy for open connections. | +| drain-delay | duration | 0s | Time wait before draining Envoy connections. | +| min-open-connections | integer | 0 | Min number of open connections when polling Envoy. | +| admin-port (Deprecated) | integer | 9001 | Deprecated: No longer used, Envoy admin interface runs as a unix socket. | +| admin-address | string | /admin/admin.sock | Path to Envoy admin unix domain socket. | +| ready-file | string | /admin/ok | File to write when shutdown is completed. | + + [1]: ../img/shutdownmanager.png diff --git a/site/content/docs/1.30/start-contributing.md b/site/content/docs/1.30/start-contributing.md new file mode 100644 index 00000000000..2ddefb6c485 --- /dev/null +++ b/site/content/docs/1.30/start-contributing.md @@ -0,0 +1,130 @@ +# Getting Started with Contributing + +Thanks for your interest in contributing to Contour. Community contributions are always needed, welcome, and appreciated. This guide shows how you can contribute to Contour in the following areas: + +- Code +- Website +- Documentation + +Please familiarize yourself with the [Code of Conduct][1] and project [Philosophy][15] before contributing. + +# Getting Started with Code + +Everything is managed on the [Project Contour GitHub][2] organization. Create an issue for a new idea or look for issues labeled **good first issue** to get started. + +## How we work + +See [How We Work][3] for an overview: +- Issue management +- Code reviews +- Coding practice +- GitHub labels + +## Contribution workflow + +Review the [Contribution workflow][4] to understand how to work with the code. + +Below is a list of workflow areas: +- Building from source +- Contribution workflow +- Contour testing +- Developer Certificate of Origin (DCO) sign off + +# Getting Started with the Website + +Updates, corrections, or improvements are managed through [GitHub][16] issues. + +When you are ready to take on an issue, see [Website Contribution Guidelines][5] to understand how the Contour website contributions are managed. There is information on: +- Site structure +- Link formatting +- Testing +- Setting up your environment + +# Getting Started with Documentation + +Documentation is critical to the success of any project. Open to all levels, Contour needs help to create and update its documentation. Join the [Contour Community Meetings][8] meeting and learn more about the Tech Docs Working Group. + +Review the [Contour Technical Documentation Contributing Guide][6] for instructions to set up your environment. + +Technical documentation will follow the [Website Contribution Guidelines][5]. + +## New documentation suggestions + +If you have a document suggestion, create an issue in [GitHub][16]. The team will triage and prioritize the issue. Connect on Slack or in a meeting to discuss your issue or request. + +## Helping with identified document issues + +Take a look at the project issues list with the label **area/documentation**. If you are new to technical writing, add in the **good first issue** label: +[area/documentation and good first issue][7] + +Reach out on Slack or a Contour meeting for any assistance. Help is always appreciated. + +# Filing and Working on Issues + +Whether code, website, or documentation, Contour uses GitHub to create, track, and manage all issues. + +If there is a fix or a suggestion for improvement, create an issue in [GitHub][16]. + +All issues are reviewed and evaluated by the Contour team. + +# Meet the Community and the Team + +To find out more about contributing to Contour, connect with us at a Contour Community Meeting, on Slack, or through the mailing list. We also have an Office Hours meeting to answer “How do I…” questions. + +## Contour Community meetings + +Discuss issues, features, or suggestions with the Contour team and other community members. Ask anything and find out more about Contour. + +Ask questions: +- “How do I do this in Contour?” +- “Why does Contour do this thing this way?” +- “Where can I find…?” + +See the [Community][8] page for: +- Meeting schedule +- Meeting notes with zoom link +- Meeting recordings + +## Mailing list + +To get email updates to Contour, join the [mailing list][10]. Topics include: +- Release notifications +- Issues +- Feedback and suggestions +- Meeting notifications + +## Find us +There are many ways to connect with the Contour team: + +- Slack: Kubernetes [#contour][11] +- Contour YouTube Channel: [CNCF Contour][12] +- Twitter: [@projectcontour][13] +- GitHub: [projectcontour][14] + +# Want More Contributing Information? + +Slack or a meeting is a great way to introduce yourself. Let us know what you are interested in, your background, and what you want to accomplish. + +# Next steps + +Come out and join a [Community meeting][8] or an [Office Hours meeting][9]. Ask questions about how to get started or just sit back and get to know the team. + + + +[1]: {{< param github_url >}}/blob/main/CODE_OF_CONDUCT.md +[2]: https://github.com/projectcontour +[3]: {{< relref "resources/how-we-work.md" >}} +[4]: {{< param github_url >}}/blob/main/CONTRIBUTING.md +[5]: {{< param github_url >}}/blob/main/SITE_CONTRIBUTION.md +[6]: {{< relref "resources/contributing-docs.md" >}} +[7]: {{< param github_url >}}/issues/?q=is%3Aopen+is%3Aissue+label%3Aarea%2Fdocumentation+label%3A%22good+first+issue%22 +[8]: {{< relref "community.md" >}} +[9]: https://github.com/projectcontour/community/wiki/Office-Hours +[10]: https://lists.cncf.io/g/cncf-contour-users/ +[11]: {{< param slack_url >}} +[12]: https://www.youtube.com/channel/UCCde7QSfcyYJ8AuXofD5bTA +[13]: https://twitter.com/projectcontour +[14]: https://github.com/projectcontour +[15]: {{< relref "resources/philosophy.md" >}} +[16]: {{< param github_url >}}/issues/ +[17]: {{< param github_url >}}/ \ No newline at end of file diff --git a/site/content/docs/1.30/troubleshooting.md b/site/content/docs/1.30/troubleshooting.md new file mode 100644 index 00000000000..28461bd8641 --- /dev/null +++ b/site/content/docs/1.30/troubleshooting.md @@ -0,0 +1,41 @@ +## Troubleshooting + +If you encounter issues, follow the guides below for help. For topics not covered here, you can [file an issue][0], or talk to us on the [#contour channel][1] on Kubernetes Slack. + +### [Troubleshooting Common Proxy Errors][2] +A guide on how to investigate common errors with Contour and Envoy. + +### [Envoy Administration Access][3] +Review the linked steps to learn how to access the administration interface for your Envoy instance. + +### [Contour Debug Logging][4] +Learn how to enable debug logging to diagnose issues between Contour and the Kubernetes API. + +### [Envoy Debug Logging][5] +Learn how to enable debug logging to diagnose TLS connection issues. + +### [Visualize the Contour Graph][6] +Learn how to visualize Contour's internal object graph in [DOT][9] format, or as a png file. + +### [Show Contour xDS Resources][7] +Review the linked steps to view the [xDS][10] resource data exchanged by Contour and Envoy. + +### [Profiling Contour][8] +Learn how to profile Contour by using [net/http/pprof][11] handlers. + +### [Envoy container stuck in unready/draining state][12] +Read the linked document if you have Envoy containers stuck in an unready/draining state. + +[0]: {{< param github_url >}}/issues +[1]: {{< param slack_url >}} +[2]: /docs/{{< param version >}}/troubleshooting/common-proxy-errors/ +[3]: /docs/{{< param version >}}/troubleshooting/envoy-admin-interface/ +[4]: /docs/{{< param version >}}/troubleshooting/contour-debug-log/ +[5]: /docs/{{< param version >}}/troubleshooting/envoy-debug-log/ +[6]: /docs/{{< param version >}}/troubleshooting/contour-graph/ +[7]: /docs/{{< param version >}}/troubleshooting/contour-xds-resources/ +[8]: /docs/{{< param version >}}/troubleshooting/profiling-contour/ +[9]: https://en.wikipedia.org/wiki/Dot +[10]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol +[11]: https://golang.org/pkg/net/http/pprof/ +[12]: /docs/{{< param version >}}/troubleshooting/envoy-container-draining/ diff --git a/site/content/docs/1.30/troubleshooting/common-proxy-errors.md b/site/content/docs/1.30/troubleshooting/common-proxy-errors.md new file mode 100644 index 00000000000..e05f153242d --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/common-proxy-errors.md @@ -0,0 +1,96 @@ +# Troubleshooting Common Proxy Errors + +## Unexpected HTTP errors + +Here are some steps to take in investigating common HTTP errors that users may encounter. +We'll include example error cases to debug with these steps. + +1. Inspect the HTTP response in detail (possibly via `curl -v`). + + Here we're looking to validate if the error response is coming from the backend app, Envoy, or possibly another proxy in front of Envoy. + If the response has the `server: envoy` header set, the request at least made it to the Envoy proxy so we can likely rule out anything before it. + The error may originate from Envoy itself or the backend app. + Look for headers or a response body that may originate from the backend app to verify if the error is in fact just the intended app behavior. + In the example below, we can see the response looks like it originates from Envoy, based on the `server: envoy` header and response body string. + + ``` + curl -vvv example.projectcontour.io + ... + > GET / HTTP/1.1 + > Host: example.projectcontour.io + ... + > + < HTTP/1.1 503 Service Unavailable + < content-length: 91 + < content-type: text/plain + < vary: Accept-Encoding + < date: Tue, 06 Feb 2024 03:44:30 GMT + < server: envoy + < + * Connection #0 to host example.projectcontour.io left intact + upstream connect error or disconnect/reset before headers. reset reason: connection failure + ``` + +1. Look at the Envoy pod logs for the access logs corresponding to the erroring request/response. + + The exact fields/field ordering present in the access log may vary if you have [configured a custom access log string or JSON access logs][0]. + For example for a Contour installation using the [default Envoy access log format][1] we would want to inspect: + * `%REQ(:METHOD)%`, `%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%`, `%REQ(:AUTHORITY)%`, `%PROTOCOL%`: Ensure these are sensible values based on your configured route and HTTP request + * `%RESPONSE_FLAGS%`: See the [documentation on Envoy response flags][2] and below how to interpret a few of them in a Contour context: + * `UF`: Likely that Envoy could not connect to the upstream + * `UH`: Upstream Service has no health/ready pods + * `NR`: No configured route matching the request + * `%DURATION%`: Can correlate this with any configured timeouts + * `%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%`: Can correlate this with any configured timeouts. If `-` then this is a hint the request was never forwarded to the upstream. + * `%UPSTREAM_HOST%`: This is the IP of the upstream pod that was selected to proxy the request to and can be used to verify the exact upstream instance that might be erroring. + + For example in this access log: + + ``` + [2024-02-06T15:18:17.437Z] "GET / HTTP/1.1" 503 UF 0 91 1998 - "103.67.2.26" "curl/8.4.0" "d70640ec-2feb-46f8-9f63-24c44142c42e" "example.projectcontour.io" "10.244.8.27:8080" + ``` + + We can see the `UF` response flag as the cause of the `503` response code. + We also see the `-` for upstream request time. + It is likely in this case that Envoy was not able to establish a connection to the upstream. + That is further supported by the request duration of `1998` which is approximately the default upstream connection timeout of `2s`. + +1. Inspect Envoy metrics + + This method of debugging can be useful especially for deployments that service a large volume of traffic. + In this case, access logs are possibly not suitable to use, as the volume of logs may be too large to pinpoint an exact erroring request. + + Metrics from individual Envoy instances can be viewed manually or scraped using Envoy's prometheus endpoints and graphed using common visualization tools. + See the `/stats/prometheus` endpoint of the [Envoy admin interface][3]. + + Metrics that may be useful to inspect: + * [Listener metrics][4] + * `downstream_cx_total` + * `ssl.connection_error` + * [HTTP metrics][5] + * `downstream_cx_total` + * `downstream_cx_protocol_error` + * `downstream_rq_total` + * `downstream_rq_rx_reset` + * `downstream_rq_tx_reset` + * `downstream_rq_timeout` + * `downstream_rq_5xx` (and other status code groups) + * [Upstream metrics][6] + * `upstream_cx_total` + * `upstream_cx_connect_fail` + * `upstream_cx_connect_timeout` + * `upstream_rq_total` + * `upstream_rq_timeout` + +1. Send a direct request to the backend app to narrow down where the error may be originating. + + This can be done via a port-forward to send a request to the app directly, skipping over the Envoy proxy. + If this sort of request succeeds, we know the issue likely originates from Contour configuration or the Envoy proxy rather than the app itself. + +[0]: /docs/{{< param latest_version >}}/config/access-logging/ +[1]: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string +[2]: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-response-flags +[3]: /docs/{{< param latest_version >}}/guides/prometheus/#envoy-metrics +[4]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/stats +[5]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/stats +[6]: https://www.envoyproxy.io/docs/envoy/latest/configuration/upstream/cluster_manager/cluster_stats diff --git a/site/content/docs/1.30/troubleshooting/contour-debug-log.md b/site/content/docs/1.30/troubleshooting/contour-debug-log.md new file mode 100644 index 00000000000..821634242c6 --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/contour-debug-log.md @@ -0,0 +1,6 @@ +# Enabling Contour Debug Logging + +The `contour serve` subcommand has two command-line flags that can be helpful for debugging. +The `--debug` flag enables general Contour debug logging, which logs more information about how Contour is processing API resources. +The `--kubernetes-debug` flag enables verbose logging in the Kubernetes client API, which can help debug interactions between Contour and the Kubernetes API server. +This flag requires an integer log level argument, where higher number indicates more detailed logging. diff --git a/site/content/docs/1.30/troubleshooting/contour-graph.md b/site/content/docs/1.30/troubleshooting/contour-graph.md new file mode 100644 index 00000000000..5abcfeb22af --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/contour-graph.md @@ -0,0 +1,25 @@ +# Visualizing Contour's Internal Object Graph + +Contour models its configuration using a directed acyclic graph (DAG) of internal objects. +This can be visualized through a debug endpoint that outputs the DAG in [DOT][2] format. +To visualize the graph, you must have [`graphviz`][3] installed on your system. + +To download the graph and save it as a PNG: + +```bash +# Port forward into the contour pod +$ CONTOUR_POD=$(kubectl -n projectcontour get pod -l app=contour -o name | head -1) +# Do the port forward to that pod +$ kubectl -n projectcontour port-forward $CONTOUR_POD 6060 +# Download and store the DAG in png format +$ curl localhost:6060/debug/dag | dot -T png > contour-dag.png +``` + +The following is an example of a DAG that maps `http://kuard.local:80/` to the +`kuard` service in the `default` namespace: + +![Sample DAG][4] + +[2]: https://en.wikipedia.org/wiki/DOT +[3]: https://graphviz.gitlab.io/ +[4]: /img/kuard-dag.png diff --git a/site/content/docs/1.30/troubleshooting/contour-xds-resources.md b/site/content/docs/1.30/troubleshooting/contour-xds-resources.md new file mode 100644 index 00000000000..69f413a8cb3 --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/contour-xds-resources.md @@ -0,0 +1,19 @@ +# Interrogate Contour's xDS Resources + +Sometimes it's helpful to be able to interrogate Contour to find out exactly what [xDS][1] resource data it is sending to Envoy. +Contour ships with a `contour cli` subcommand which can be used for this purpose. + +Because Contour secures its communications with Envoy using Secrets in the cluster, the easiest way is to run `contour cli` commands _inside_ the pod. +Do this is via `kubectl exec`: + +```bash +# Get one of the pods that matches the examples/daemonset +$ CONTOUR_POD=$(kubectl -n projectcontour get pod -l app=contour -o jsonpath='{.items[0].metadata.name}') +# Do the port forward to that pod +$ kubectl -n projectcontour exec $CONTOUR_POD -c contour -- contour cli lds --cafile=/certs/ca.crt --cert-file=/certs/tls.crt --key-file=/certs/tls.key +``` + +Which will stream changes to the LDS api endpoint to your terminal. +Replace `contour cli lds` with `contour cli rds` for route resources, `contour cli cds` for cluster resources, and `contour cli eds` for endpoints. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol diff --git a/site/content/docs/1.30/troubleshooting/envoy-admin-interface.md b/site/content/docs/1.30/troubleshooting/envoy-admin-interface.md new file mode 100644 index 00000000000..c44b6fe3e9d --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/envoy-admin-interface.md @@ -0,0 +1,32 @@ +# Accessing the Envoy Administration Interface + +Getting access to the Envoy [administration interface][1] can be useful for diagnosing issues with routing or cluster health. +However, Contour doesn't expose the entire Envoy Administration interface since that interface contains many options, such as shutting down Envoy or draining traffic. +To prohibit this behavior, Contour only exposes the read-only options from the admin interface which still allows for debugging Envoy, but without the options mentioned previously. + +Those endpoints are: + - /certs + - /clusters + - /listeners + - /config_dump + - /memory + - /ready + - /runtime + - /server_info + - /stats + - /stats/prometheus + - /stats/recentlookups + +The Envoy administration interface is bound by default to `http://127.0.0.1:9001`. +To access it from your workstation use `kubectl port-forward` like so: + +```sh +# Get one of the pods that matches the Envoy daemonset +ENVOY_POD=$(kubectl -n projectcontour get pod -l app=envoy -o name | head -1) +# Do the port forward to that pod +kubectl -n projectcontour port-forward $ENVOY_POD 9001 +``` + +Then navigate to `http://127.0.0.1:9001/` to access the administration interface for the Envoy container running on that pod. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin diff --git a/site/content/docs/1.30/troubleshooting/envoy-container-draining.md b/site/content/docs/1.30/troubleshooting/envoy-container-draining.md new file mode 100644 index 00000000000..82bb47cb883 --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/envoy-container-draining.md @@ -0,0 +1,29 @@ +# Envoy container stuck in unready/draining state + +It's possible for the Envoy containers to become stuck in an unready/draining state. +This is an unintended side effect of the shutdown-manager sidecar container being restarted by the kubelet. +For more details on exactly how this happens, see [this issue][1]. + +If you observe Envoy containers in this state, you should `kubectl delete` them to allow new Pods to be created to replace them. + +To make this issue less likely to occur, you should: +- ensure you have [resource requests][2] on all your containers +- ensure you do **not** have a liveness probe on the shutdown-manager sidecar container in the envoy daemonset (this was removed from the example YAML in Contour 1.24.0). + +If the above are not sufficient for preventing the issue, you may also add a liveness probe to the envoy container itself, like the following: + +```yaml +livenessProbe: + httpGet: + path: /ready + port: 8002 + initialDelaySeconds: 15 + periodSeconds: 5 + failureThreshold: 6 +``` + +This will cause the kubelet to restart the envoy container if it does get stuck in this state, resulting in a return to normal operations load balancing traffic. +Note that in this case, it's possible that a graceful drain of connections may or may not occur, depending on the exact sequence of operations that preceded the envoy container failing the liveness probe. + +[1]: https://github.com/projectcontour/contour/issues/4851 +[2]: /docs/{{< param latest_version >}}/deploy-options/#setting-resource-requests-and-limits \ No newline at end of file diff --git a/site/content/docs/1.30/troubleshooting/envoy-debug-log.md b/site/content/docs/1.30/troubleshooting/envoy-debug-log.md new file mode 100644 index 00000000000..bfef4fa5531 --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/envoy-debug-log.md @@ -0,0 +1,8 @@ +# Enabling Envoy Debug Logging + +The `envoy` command has a `--log-level` [flag][1] that can be useful for debugging. +By default, it's set to `info`. +To change it to `debug`, edit the `envoy` DaemonSet in the `projectcontour` namespace and replace the `--log-level info` flag with `--log-level debug`. +Setting the Envoy log level to `debug` can be particilarly useful for debugging TLS connection failures. + +[1]: https://www.envoyproxy.io/docs/envoy/latest/operations/cli diff --git a/site/content/docs/1.30/troubleshooting/profiling-contour.md b/site/content/docs/1.30/troubleshooting/profiling-contour.md new file mode 100644 index 00000000000..95bb0164210 --- /dev/null +++ b/site/content/docs/1.30/troubleshooting/profiling-contour.md @@ -0,0 +1,14 @@ +# Accessing Contour's /debug/pprof Service + +Contour exposes the [net/http/pprof][1] handlers for `go tool pprof` and `go tool trace` by default on `127.0.0.1:6060`. +This service is useful for profiling Contour. +To access it from your workstation use `kubectl port-forward` like so, + +```bash +# Get one of the pods that matches the Contour deployment +$ CONTOUR_POD=$(kubectl -n projectcontour get pod -l app=contour -o name | head -1) +# Do the port forward to that pod +$ kubectl -n projectcontour port-forward $CONTOUR_POD 6060 +``` + +[1]: https://golang.org/pkg/net/http/pprof diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html index e2f957d50b4..57bc87795fd 100644 --- a/site/content/docs/main/config/api-reference.html +++ b/site/content/docs/main/config/api-reference.html @@ -5191,9 +5191,9 @@

ContourConfiguration

FeatureFlags defines toggle to enable new contour features. Available toggles are: -useEndpointSlices - configures contour to fetch endpoint data -from k8s endpoint slices. defaults to false and reading endpoint -data from the k8s endpoints.

+useEndpointSlices - Configures contour to fetch endpoint data +from k8s endpoint slices. defaults to true, +If false then reads endpoint data from the k8s endpoints.

@@ -5522,6 +5522,22 @@

ExtensionService protocol options will be available in future.

+ + +circuitBreakerPolicy +
+ + +CircuitBreakers + + + + +(Optional) +

CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. +If defined this overrides the global circuit breaker budget.

+ + @@ -5610,6 +5626,90 @@

AccessLogType +

CircuitBreakers +

+

+(Appears on: +ClusterParameters, +ExtensionServiceSpec) +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+maxConnections +
+ +uint32 + +
+(Optional) +

The maximum number of connections that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

+
+maxPendingRequests +
+ +uint32 + +
+(Optional) +

The maximum number of pending requests that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

+
+maxRequests +
+ +uint32 + +
+(Optional) +

The maximum parallel requests a single Envoy instance allows to the Kubernetes Service; defaults to 1024

+
+maxRetries +
+ +uint32 + +
+(Optional) +

The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3.

+
+perHostMaxConnections +
+ +uint32 + +
+

PerHostMaxConnections is the maximum number of connections +that Envoy will allow to each individual host in a cluster.

+

ClusterDNSFamilyType (string alias)

@@ -5723,8 +5823,8 @@

ClusterParameters circuitBreakers
- -GlobalCircuitBreakerDefaults + +CircuitBreakers @@ -5984,9 +6084,9 @@

ContourConfiguratio

FeatureFlags defines toggle to enable new contour features. Available toggles are: -useEndpointSlices - configures contour to fetch endpoint data -from k8s endpoint slices. defaults to false and reading endpoint -data from the k8s endpoints.

+useEndpointSlices - Configures contour to fetch endpoint data +from k8s endpoint slices. defaults to true, +If false then reads endpoint data from the k8s endpoints.

@@ -7529,6 +7629,22 @@

ExtensionServiceSpec protocol options will be available in future.

+ + +circuitBreakerPolicy +
+ + +CircuitBreakers + + + + +(Optional) +

CircuitBreakerPolicy specifies the circuit breaker budget across the extension service. +If defined this overrides the global circuit breaker budget.

+ +

ExtensionServiceStatus @@ -7671,76 +7787,6 @@

GatewayConfig -

GlobalCircuitBreakerDefaults -

-

-(Appears on: -ClusterParameters) -

-

-

- - - - - - - - - - - - - - - - - - - - - - - - - -
FieldDescription
-maxConnections -
- -uint32 - -
-(Optional) -

The maximum number of connections that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

-
-maxPendingRequests -
- -uint32 - -
-(Optional) -

The maximum number of pending requests that a single Envoy instance allows to the Kubernetes Service; defaults to 1024.

-
-maxRequests -
- -uint32 - -
-(Optional) -

The maximum parallel requests a single Envoy instance allows to the Kubernetes Service; defaults to 1024

-
-maxRetries -
- -uint32 - -
-(Optional) -

The maximum number of parallel retries a single Envoy instance allows to the Kubernetes Service; defaults to 3.

-

HTTPProxyConfig

@@ -9031,6 +9077,8 @@

XDSServerConfig

Defines the XDSServer to use for contour serve.

Values: envoy (default), contour (deprecated).

Other values will produce an error.

+

Deprecated: this field will be removed in a future release when +the contour xDS server implementation is removed.

diff --git a/site/content/docs/main/config/gateway-api.md b/site/content/docs/main/config/gateway-api.md index 605103dc7e3..c38c2b49c04 100644 --- a/site/content/docs/main/config/gateway-api.md +++ b/site/content/docs/main/config/gateway-api.md @@ -198,7 +198,8 @@ containers: - --contour-key-file=/certs/tls.key - --config-path=/config/contour.yaml - --disable-feature=tlsroutes - - --disable-feature=grpcroutes + - --disable-feature=tcproutes + ... ``` [1]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/docs/main/config/tls-termination.md b/site/content/docs/main/config/tls-termination.md index d1b26dc2f4e..d284ba082b0 100644 --- a/site/content/docs/main/config/tls-termination.md +++ b/site/content/docs/main/config/tls-termination.md @@ -265,7 +265,11 @@ spec: ## Client Certificate Details Forwarding -HTTPProxy supports passing certificate data through the `x-forwarded-client-cert` header to let applications use details from client certificates (e.g. Subject, SAN...). Since the certificate (or the certificate chain) could exceed the web server header size limit, you have the ability to select what specific part of the certificate to expose in the header through the `forwardClientCertificate` field. Read more about the supported values in the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert). +HTTPProxy supports passing certificate data through the `x-forwarded-client-cert` (XFCC) header to let applications use details from client certificates (e.g. Subject, SAN...). + +Contour will never forward or append to an existing XFCC header from a client, regardless of whether forwarding client certificate details is enabled. It will always sanitize the request, first dropping the header if present, and then if configured to pass client certificate details, and a client certificate has been presented, then it will add a new XFCC header. + +Since the certificate (or the certificate chain) could exceed the web server header size limit, you have the ability to select what specific part of the certificate to expose in the header through the `forwardClientCertificate` field. Read more about the supported values in the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert). ```yaml apiVersion: projectcontour.io/v1 diff --git a/site/content/docs/main/configuration.md b/site/content/docs/main/configuration.md index 8e20de93fe5..5277ab79e38 100644 --- a/site/content/docs/main/configuration.md +++ b/site/content/docs/main/configuration.md @@ -206,7 +206,7 @@ The server configuration block can be used to configure various settings for the | Field Name | Type | Default | Description | | --------------- | ------ | ------- | ----------------------------------------------------------------------------- | -| xds-server-type | string | envoy | This field specifies the xDS Server to use. Options are `envoy` or `contour` (deprecated). | +| xds-server-type | string | envoy | This field specifies the xDS Server to use. Options are `envoy` or `contour` (deprecated). **This field is deprecated** and will be removed in a future release when the `contour` xDS server implementation is removed. | ### Gateway Configuration diff --git a/site/content/docs/main/guides/grpc.md b/site/content/docs/main/guides/grpc.md index 12f0d9035fb..acdec3ca203 100644 --- a/site/content/docs/main/guides/grpc.md +++ b/site/content/docs/main/guides/grpc.md @@ -69,7 +69,7 @@ metadata: name: my-grpc-service spec: virtualhost: - fqdn: my-grpc-service.foo.com + fqdn: my-grpc-service.foo.com routes: - conditions: - prefix: /yages.Echo/Ping # Matches a specific gRPC method. @@ -77,7 +77,7 @@ spec: - name: grpc-echo port: 9000 protocol: h2c - - conditions: + - conditions: - prefix: / # Matches everything else. services: - name: grpc-echo @@ -144,12 +144,12 @@ spec: ## Gateway API Configuration -Gateway API now supports a specific resource [GRPCRoute][6] for routing gRPC requests. +Gateway API supports a specific resource [GRPCRoute][6] for routing gRPC requests. Configuring GRPCRoute for routing gRPC requests needs to specify parentRefs, hostnames, and routing rules with specific backendRefs. In the below example, route path matching is conducted via method matching rule for declared services and their methods. ```yaml -apiVersion: gateway.networking.k8s.io/v1alpha2 +apiVersion: gateway.networking.k8s.io/v1 kind: GRPCRoute metadata: name: yages @@ -220,6 +220,6 @@ Piping the output to `base64 -d | od -c` we can see the raw text gRPC response: [3]: https://github.com/grpc/grpc/blob/master/doc/health-checking.md [4]: https://github.com/grpc-ecosystem/grpc-health-probe [5]: https://github.com/fullstorydev/grpcurl -[6]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute +[6]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GRPCRoute [7]: https://github.com/grpc/grpc-web [8]: https://github.com/projectcontour/contour/issues/4290 diff --git a/site/content/docs/main/guides/prometheus.md b/site/content/docs/main/guides/prometheus.md index f0b7364c340..87d1a514ab3 100644 --- a/site/content/docs/main/guides/prometheus.md +++ b/site/content/docs/main/guides/prometheus.md @@ -4,10 +4,6 @@ title: Collecting Metrics with Prometheus -Contour and Envoy expose metrics that can be scraped with Prometheus. By -default, annotations to gather them are in all the `deployment` yamls and they -should work out of the box with most configurations. - ## Envoy Metrics Envoy typically [exposes metrics](https://www.envoyproxy.io/docs/envoy/v1.15.0/configuration/http/http_conn_man/stats#config-http-conn-man-stats) through an endpoint on its admin interface. To @@ -28,67 +24,58 @@ Contour exposes a Prometheus-compatible `/metrics` endpoint that defaults to lis {{% metrics-table %}} -## Sample Deployment - -In the `/examples` directory there are example deployment files that can be used to spin up an example environment. -All deployments there are configured with annotations for prometheus to scrape by default, so it should be possible to utilize any of them with the following quickstart example instructions. - -### Deploy Prometheus - -A sample deployment of Prometheus and Alertmanager is provided that uses temporary storage. This deployment can be used for testing and development, but might not be suitable for all environments. - -#### Stateful Deployment +## Deploy Sample Monitoring Stack - A stateful deployment of Prometheus should use persistent storage with [Persistent Volumes and Persistent Volume Claims][1] to maintain a correlation between a data volume and the Prometheus Pod. - Persistent volumes can be static or dynamic and depends on the backend storage implementation utilized in environment in which the cluster is deployed. For more information, see the [Kubernetes documentation on types of persistent volumes][2]. +Follow the instructions [here][0] to install a monitoring stack to your cluster using the [kube-prometheus][1] project sample manifests. +These instructions install the [Prometheus Operator][2], a [Prometheus][3] instance, a [Grafana][4] `Deployment`, and other components. +Note that this is a quickstart installation, see documentation [here][5] for more details on customizing the installation for production usage. -#### Quick start +The instructions above show how to access the Prometheus and Grafana web interfaces using `kubectl port-forward`. +Sample `HTTPProxy` resources in the `examples/` directory can also be used to access these through your Contour installation: ```sh -# Deploy -$ kubectl apply -f examples/prometheus +$ kubectl apply -f examples/prometheus/httpproxy.yaml +$ kubectl apply -f examples/grafana/httpproxy.yaml ``` -#### Access the Prometheus web UI +### Scrape Contour and Envoy metrics + +To enable Prometheus to scrape metrics from the Contour and Envoy pods, we can add some RBAC customizations with a `Role` and `RoleBinding` in the `projectcontour` namespace: ```sh -$ kubectl -n projectcontour-monitoring port-forward $(kubectl -n projectcontour-monitoring get pods -l app=prometheus -l component=server -o jsonpath='{.items[0].metadata.name}') 9090:9090 +kubectl apply -f examples/prometheus/rbac.yaml ``` -then go to `http://localhost:9090` in your browser. - -#### Access the Alertmanager web UI +Now add [`PodMonitor`][6] resources for scraping metrics from Contour and Envoy pods in the `projectcontour` namespace: ```sh -$ kubectl -n projectcontour-monitoring port-forward $(kubectl -n projectcontour-monitoring get pods -l app=prometheus -l component=alertmanager -o jsonpath='{.items[0].metadata.name}') 9093:9093 +kubectl apply -f examples/prometheus/podmonitors.yaml ``` -then go to `http://localhost:9093` in your browser. - -### Deploy Grafana +You should now be able to browse Contour and Envoy Prometheus metrics in the Prometheus and Grafana web interfaces to create dashboards and alerts. -A sample deployment of Grafana is provided that uses temporary storage. +### Apply Contour and Envoy Grafana Dashboards -#### Quick start +Some sample Grafana dashboards are provided as `ConfigMap` resources in the `examples/grafana` directory. +To use them with your Grafana installation, apply the resources: ```sh -# Deploy -$ kubectl apply -f examples/grafana/ - -# Create secret with grafana credentials -$ kubectl create secret generic grafana -n projectcontour-monitoring \ - --from-literal=grafana-admin-password=admin \ - --from-literal=grafana-admin-user=admin +$ kubectl apply -f examples/grafana/dashboards.yaml ``` -#### Access the Grafana UI +And update the Grafana `Deployment`: ```sh -$ kubectl port-forward $(kubectl get pods -l app=grafana -n projectcontour-monitoring -o jsonpath='{.items[0].metadata.name}') 3000 -n projectcontour-monitoring +$ kubectl -n monitoring patch deployment grafana --type=json --patch-file examples/grafana/deployment-patch.json ``` -then go to `http://localhost:3000` in your browser. -The username and password are from when you defined the Grafana secret in the previous step. +You should now see dashboards for Contour and Envoy metrics available in the Grafana web interface. + -[1]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ -[2]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes \ No newline at end of file +[0]: https://prometheus-operator.dev/docs/prologue/quick-start/ +[1]: https://github.com/prometheus-operator/kube-prometheus +[2]: https://github.com/prometheus-operator/prometheus-operator +[3]: https://prometheus.io/ +[4]: https://grafana.com/ +[5]: https://github.com/prometheus-operator/kube-prometheus?tab=readme-ov-file#getting-started +[6]: https://prometheus-operator.dev/docs/operator/design/#podmonitor diff --git a/site/content/guides/ingressroute-to-httpproxy.md b/site/content/guides/ingressroute-to-httpproxy.md deleted file mode 100644 index bc321795a6f..00000000000 --- a/site/content/guides/ingressroute-to-httpproxy.md +++ /dev/null @@ -1,555 +0,0 @@ ---- -title: Migrating from IngressRoute to HTTPProxy -layout: page ---- - -This document describes the differences between IngressRoute and HTTPProxy. -It is intended for Contour users who have existing IngressRoute resources they wish to migrate to HTTPProxy. -It is not intended a comprehensive documentation of HTTPProxy, for that please see the [`HTTPProxy` documentation][1]. - -_Note: IngressRoute has been removed from Contour in v1.6._ - -## The easy way - -The simplest way to migrate from IngressRoute to HTTPProxy is to use the `ir2proxy` tool. -Installation instructions are available at [its github repo](https://github.com/projectcontour/ir2proxy). -It's installable either by homebrew or downloading the binary. - -This tool can automatically migrate most IngressRoutes to HTTPProxies. -However, due to the behavior changes around the move from delegation to inclusion, not all IngressRoutes can be translated without manual intervention. -The tool will tell you when manual intervention is required. - - -## Manual conversion notes - -### Group, Version and Kind changes - -`HTTPProxy` has moved to the `projectcontour.io` group. -The version is `v1`, with all the guarantees a GA API implies. - - -Before: - -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -``` -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -``` - -### TLS secrets - -No change. - -Before: - -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: tls-example - namespace: default -spec: - virtualhost: - fqdn: example.com - tls: - secretName: tlssecret -``` - -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: tls-example - namespace: default -spec: - virtualhost: - fqdn: example.com - tls: - secretName: tlssecret -``` - -#### TLS Minimum protocol version - -No change. - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: tls-example - namespace: default -spec: - virtualhost: - fqdn: example.com - tls: - secretName: tlssecret - minimumProtocolVersion: "1.3" -``` - -#### Upstream TLS validation - -No change. - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: secure-backend -spec: - virtualhost: - fqdn: www.example.com - routes: - - match: / - services: - - name: service - port: 8443 - validation: - caSecret: my-certificate-authority - subjectName: backend.example.com -``` - -#### TLS Certificate Delegation - -The group and version of the TLSCertificateDelegation CRD have changed. -`contour.heptio.com/v1beta1.TLSCertificateDelegation` has been removed. - -Before: - -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: TLSCertificateDelegation -metadata: - name: example-com-wildcard - namespace: www-admin -spec: - delegations: - - secretName: example-com-wildcard - targetNamespaces: - - example-com -``` -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: TLSCertificateDelegation -metadata: - name: example-com-wildcard - namespace: www-admin -spec: - delegations: - - secretName: example-com-wildcard - targetNamespaces: - - example-com -``` - -### Routing - -HTTPProxy offers additional ways to match incoming requests to routes. -This document covers the conversion between the routing offered in IngressRoute and HTTPProxy. -For a broader discussion of HTTPProxy routing, see the [HTTPProxy documentation][1]. - -Before: - -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: multiple-paths - namespace: default -spec: - virtualhost: - fqdn: multi-path.bar.com - routes: - - match: / # matches everything else - services: - - name: s1 - port: 80 - - match: /blog # matches `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` - services: - - name: s2 - port: 80 -``` - -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: multiple-paths - namespace: default -spec: - virtualhost: - fqdn: multi-path.bar.com - routes: - - conditions: - - prefix: / # matches everything else - services: - - name: s1 - port: 80 - - conditions: - - prefix: /blog # matches `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` - services: - - name: s2 - port: 80 -``` - -#### Multiple services - -No change. - -#### Upstream weighting - -No change. - -#### Response timeout - -`routes.timeoutPolicy.request` has been renamed to `routes.timeoutPolicy.response` to more accurately reflect is the timeout for the response. - -Before: - -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: request-timeout - namespace: default -spec: - virtualhost: - fqdn: timeout.bar.com - routes: - - match: / - timeoutPolicy: - request: 1s - services: - - name: s1 - port: 80 -``` - -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: request-timeout - namespace: default -spec: - virtualhost: - fqdn: timeout.bar.com - routes: - - conditions: - - prefix: / - timeoutPolicy: - response: 1s - services: - - name: s1 - port: 80 -``` - -#### Prefix rewriting - -Prefix rewriting is supported in HTTPProxy. - -Before: -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: app - namespace: default -spec: - virtualhost: - fqdn: app.example.com - routes: - - match: / - services: - - name: app - port: 80 - - match: /service2 - prefixRewrite: "/" # Setting this rewrites the request from `/service2` to `/` - services: - - name: app-service - port: 80 -``` - -After: -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: app - namespace: default -spec: - virtualhost: - fqdn: app.example.com - routes: - - conditions: - - prefix: "/" - services: - - name: app - port: 80 - - conditions: - - prefix: "/service2" - pathRewritePolicy: - replacePrefix: - - replacement: / # app-service will see client requests to `/service2` coming in to `/` - services: - - name: app-service - port: 80 -``` - -### Load balancing strategies - -Per service load balancing strategy has moved to a per route strategy that applies to all services for that route. - -Before: - -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: lb-strategy - namespace: default -spec: - virtualhost: - fqdn: strategy.bar.com - routes: - - match: / - services: - - name: s1-strategy - port: 80 - strategy: WeightedLeastRequest - - name: s2-strategy - port: 80 - strategy: WeightedLeastRequest -``` - -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: lb-strategy - namespace: default -spec: - virtualhost: - fqdn: strategy.bar.com - routes: - - services: - - name: s1-strategy - port: 80 - - name: s2-strategy - port: 80 - loadBalancerStrategy: - strategy: WeightedLeastRequest -``` - -### Session affinity - -See above. - -### Per upstream health check - -Per service health check has moved to a per route health check that applies to all services for that route. - -Before: - -```yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: health-check - namespace: default -spec: - virtualhost: - fqdn: health.bar.com - routes: - - match: / - services: - - name: s1-health - port: 80 - healthCheck: - path: /healthy - intervalSeconds: 5 - timeoutSeconds: 2 - unhealthyThresholdCount: 3 - healthyThresholdCount: 5 - - name: s2-health # no health-check defined for this service - port: 80 -``` - -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: health-check - namespace: default -spec: - virtualhost: - fqdn: health.bar.com - routes: - - conditions: - - prefix: / - healthCheckPolicy: - path: /healthy - intervalSeconds: 5 - timeoutSeconds: 2 - unhealthyThresholdCount: 3 - healthyThresholdCount: 5 - services: - - name: s1-health - port: 80 - - name: s2-health - port: 80 -``` - -### Websocket support - -No change. - -### External name support - -No change. - -## IngressRoute delegation - -IngressRoute delegation has been replaced with HTTPProxy inclusion. -Functionally inclusion is similar to delegation. -In both scenarios the routes from one document are combined with those of the parent. - -The key difference between IngressRoute's delegation and HTTPProxy's inclusion is the former has the appearance of being scoped by the path of the route of which it was attached. -As we explored the design of the next revision of IngressRoute the tight coupling of the properties of an incoming HTTP request; its path, its IP address, its headers, and so on--fundamentally run time concepts--with the inclusion of some configuration from another IngressRoute--which is definitely a configuration time concept--lead us to unanswerable questions like "what does it mean to delegate to an IngressRoute via a header". - -This Gordian Knot was severed by decoupling the inclusion of one document into its parent from the facility to place restrictions on what route matching conditions could be specified in that document. -The former we call _inclusion_, the latter are known as _conditions_. -This section discusses conversion from delegation to inclusion, please see the [HTTPProxy documentation][1] for a discussion of conditions. - -Before: - -```yaml -# root.ingressroute.yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: delegation-root - namespace: default -spec: - virtualhost: - fqdn: root.bar.com - routes: - - match: / - services: - - name: s1 - port: 80 - - match: /service2 - delegate: - name: www - namespace: www ---- -# service2.ingressroute.yaml -apiVersion: contour.heptio.com/v1beta1 -kind: IngressRoute -metadata: - name: www - namespace: www -spec: - routes: - - match: /service2 - services: - - name: s2 - port: 80 - - match: /service2/blog - services: - - name: blog - port: 80 -``` - -After: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: delegation-root - namespace: default -spec: - virtualhost: - fqdn: root.bar.com - includes: - - conditions: - - prefix: /service2 - name: www - namespace: www - routes: - - conditions: - - prefix: / - services: - - name: s1 - port: 80 ---- -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: www - namespace: www -spec: - routes: - - conditions: - - prefix: / # matches /service2 - services: - - name: s2 - port: 80 - - conditions: - - prefix: /blog # matches /service2/blog - services: - - name: blog - port: 80 -``` - -### Virtualhost aliases - -No change. - -### Inclusion across namespaces - -As above. No change. - -### Orphaned HTTPProxies - -No change. -Orphaned status will be reported on _child_ HTTPProxy objects that are not included by any _root_ HTTPProxy records. - -### Restricted root namespaces - -The `--ingressroute-root-namespace` flag has been renamed to `--root-namespaces` for obvious reasons. -The old name has been removed. -See the [upgrading documentation]({% link _resources/upgrading.md %}) for more information on upgrading Contour. - -### TCP Proxying - -No change. - -### TLS Termination - -No change. - -### TLS Passthrough - -No change. - -### Status reporting - -Status reporting on HTTPProxy objects is similar in scope and function to IngressRoute status. - -[1]: /docs/{{< param latest_version >}}/httpproxy diff --git a/site/content/guides/structured-logs.md b/site/content/guides/structured-logs.md deleted file mode 100644 index 2792169c587..00000000000 --- a/site/content/guides/structured-logs.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: How to enable structured JSON logging -layout: page ---- - -This document describes how to configure structured logging for Envoy via Contour. - -## How the feature works - -Contour allows you to choose from a set of JSON fields that will be expanded into Envoy templates and sent to Envoy. -There is a default set of fields if you enable JSON logging, and you may customize which fields you log. - -The list of available fields are discoverable in the following objects: -- [JSONFields][1] are fields that have built in mappings to commonly used envoy - operators. -- [envoySimpleOperators][2] are the names of simple envoy operators that don't - require arguments, they are case-insensitive when configured. -- [envoyComplexOperators][3] are the names of complex envoy operators that require - arguments. - -The default list of fields is available at [DefaultFields][4]. - -## Enabling the feature - -To enable the feature you have two options: - -- Add `--accesslog-format=json` to your Contour startup line. -- Add `accesslog-format: json` to your configuration file. - -Without any further customization, the [default fields][4] will be used. - -## Customizing logged fields - -To customize the logged fields, add a `json-fields` list of strings to your -config file. If the `json-fields` key is not specified, the [default fields][4] -will be configured. - -To use a value from [JSONFields][1] or [envoySimpleOperators][2], simply include -the name of the value in the list of strings. The JSONFields are case-sensitive, -but envoySimpleOperators are not. - -To use [envoyComplexOperators][3] or to use alternative field names, specify strings as -key/value pairs like `"fieldName=%OPERATOR(...)%"`. - -Unknown field names in non key/value fields will result in validation errors, as -will unknown Envoy operators in key/value fields. Note that the -`DYNAMIC_METADATA` and `FILTER_STATE` Envoy logging operators are not supported -at this time due to the complexity of their validation. - -See the [example config file][5] to see this used in context. - -## Sample configuration file - -Here is a sample config: - -```yaml -accesslog-format: json -json-fields: - - "@timestamp" - - "authority" - - "bytes_received" - - "bytes_sent" - - "customer_id=%REQ(X-CUSTOMER-ID)%" - - "downstream_local_address" - - "downstream_remote_address" - - "duration" - - "method" - - "path" - - "protocol" - - "request_id" - - "requested_server_name" - - "response_code" - - "response_flags" - - "uber_trace_id" - - "upstream_cluster" - - "upstream_host" - - "upstream_local_address" - - "upstream_service_time" - - "user_agent" - - "x_forwarded_for" -``` - -[1]: https://github.com/projectcontour/contour/blob/main/pkg/config/accesslog.go#L33-L45 -[2]: https://github.com/projectcontour/contour/blob/main/pkg/config/accesslog.go#L49-L93 -[3]: https://github.com/projectcontour/contour/blob/main/pkg/config/accesslog.go#L97-L102 -[4]: https://github.com/projectcontour/contour/blob/main/pkg/config/accesslog.go#L4 -[5]: {{< param github_url >}}/tree/{{< param latest_version >}}/examples/contour/01-contour-config.yaml diff --git a/site/content/guides/tls.md b/site/content/guides/tls.md deleted file mode 100644 index 19aa190dbb0..00000000000 --- a/site/content/guides/tls.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: TLS support -layout: page ---- - -# TLS support - -Contour supports HTTPS (TLS/SSL) ingress by integrating Envoy's SNI support. -Certificates must be provisioned which are saved as Kubernetes secrets and get passed to Envoy. -A common way to implement this is to use [JetStack's Cert Manager][3]. - -## Enabling TLS support - -Enabling TLS support requires Contour version 0.3 or later. You must also add an [entry for port 443][1] to your `contour` service object. - -## Configuring TLS with Contour on an ELB - -If you deploy behind an AWS Elastic Load Balancer, see [EC2 ELB PROXY protocol support][2] for special instructions. - -## TLS SNI name matching -Envoy SNI name matching during TLS handshake is case-sensitive. -For example, for a cert with common name foo.bar.com, requests to Foo.bar.com would not match. -Similarly, for cert with wildcard name \*.bar.com, only requests to lower case name will match. -Here is the [known issue][4] reported on Envoy. - -[1]: {{< param github_url >}}/tree/{{< param latest_version >}}/examples/contour/03-contour.yaml/#L45 -[2]: /guides/proxy-proto -[3]: /guides/cert-manager -[4]: https://github.com/envoyproxy/envoy/issues/6199 diff --git a/site/content/guides/xds-migration.md b/site/content/guides/xds-migration.md deleted file mode 100644 index c653a6b1a27..00000000000 --- a/site/content/guides/xds-migration.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Migrating from xDS v2 --> v3 -layout: page ---- - -This guide shows you how to migrate in-place instances of Envoy running xDS v2 to v3. - -## Summary - -Envoy communicates with Contour over gRPC which allows for dynamic communication for Envoy configuration updates. -Until Contour v1.10, this gRPC xDS communication utilized the v2 xDS for transport as well as resource version. - -In the beginning of Q1 2021, the Envoy community is [deprecating][0] the v2 xDS API in favor of the v3 which has been stable since Q1 2020. -Contour offers support for the v3 xDS API in Contour v1.10.0. - -Practically for users, this change has no effect on how Contour configures Envoy to route ingress traffic inside a Kubernetes cluster, however -it's important to upgrade to this new version immediately since newer versions of Envoy won't support the `v2` api. - -## Background - -Envoy gets configured with a bootstrap configuration file which Contour provides via an `initContainer` on the Envoy daemonset. -This file configures the dynamic xDS resources, Listener Discovery Service (LDS) and Cluster Discovery Service (CDS), to point to Contour's xDS gRPC server endpoint. - -The bootstrap configuration file has two settings in the LDS/CDS entries which tell Contour what Resource & Transport version they would like to use. -In Contour v1.10.0, there's a new flag, `--xds-resource-version`, on the `contour bootstrap` command which is used in the `initContainer` that allows users to specify the xDS resource version. - -Setting this flag to `v3` will configure Envoy to request the `v3` xDS Resource API version and will become the default in Contour v1.11.0. - -## In-Place Upgrade - -When users have an existing Contour installation and wish to upgrade without dropping connections, users should first upgrade Contour to v1.10.0 which will serve both v2 and v3 xDS versions from the same gRPC endpoint. -Next, change the Envoy Daemonset or deployment to include `--xds-resource-version=v3` on the `initContainer` which runs the `contour bootstrap` command. -Setting this new flag to `v3` tells Envoy to upgrade to the v3 resource version. -The usual rollout process will handle draining connections allowing a fleet of Envoy instances to move from the v2 xDS Resource API version gradually to the v3 version. - -## Redeploy Upgrade - -Redeploying Contour is a simple path for users who do not need to upgrade without dropping connections. -The only change to remember is to set the `--xds-resource-version=v3` on the bootstrap `initContainer` to configure the new instances of Envoy to use the `v3` xDS Resource API. - -[0]: https://www.envoyproxy.io/docs/envoy/latest/api/api_supported_versions \ No newline at end of file diff --git a/site/content/posts/2019-04-22-Routing-Traffic-to-Applications-in-Kubernetes-with-Contour.md b/site/content/posts/2019-04-22-Routing-Traffic-to-Applications-in-Kubernetes-with-Contour.md deleted file mode 100644 index ba7add1b188..00000000000 --- a/site/content/posts/2019-04-22-Routing-Traffic-to-Applications-in-Kubernetes-with-Contour.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Routing Traffic to Applications in Kubernetes with Contour -image: /img/posts/image1.png -excerpt: One of the most critical needs in running workloads at scale with Kubernetes is efficient and smooth traffic ingress management at the Layer 7 level. -author_name: Contour Team -# author_avatar: https://placehold.it/64x64 -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team'] -date: 2019-04-22 -slug: routing-traffic-to-applications-in-kubernetes-with-contour ---- -One of the most critical needs in running workloads at scale with Kubernetes is efficient and smooth traffic ingress management at the [Layer 7][1] level. Getting an application up and running is not always the entire story; it may still need a way for users to access it. Filling that operational gap is what Contour was designed to do by providing a way to allow users to access applications within a Kubernetes cluster. -Contour is an Ingress controller for Kubernetes that works by deploying the Envoy proxy as a reverse proxy and load balancer. Contour supports dynamic configuration updates out of the box while maintaining a lightweight profile. - -Contour offers the following benefits for users: - - - A simple installation mechanism to quickly deploy and integrate Envoy - - Safely support ingress in multi-team Kubernetes clusters - - Clean integration with the Kubernetes object model - - Dynamic updates to ingress configuration without dropped connections - -## What is Ingress? -[Kubernetes Ingress][2] is a set of configurations that define how external traffic can be routed to an application inside a Kubernetes cluster. A controller (Contour) watches for changes to objects in the cluster, then wires together the configurations to create a data path for the request to be resolved, implementing the configurations defined. It makes decisions based on the request received (e.g., example.com/blog), provides TLS termination, and performs other functions. - -Ingress is an important component of a cloud native system because it allows for a clean separation between the application and how it’s accessed. A cluster administrator deals with providing access to the controller, and the application engineer just deals with deploying the application. Ingress is the glue that ties the two together. - -## Contour in Detail -Since it was added in Kubernetes 1.1, Ingress hasn’t gotten much attention but is still very popular in the community. Many controllers rely on annotations on the Ingress object to clarify, restrict, or augment the structure imposed by the Ingress object, which is no different from how Contour supports Ingress. - -At the same time a number of web application deployment patterns, such as blue/green deployments, explicit load balancing strategies, and presenting more than one Kubernetes Service behind a single route, are difficult to achieve with Ingress as it stands today. Contour has introduced a new Custom Resource Definition (CRD) that allows for a new data model called `IngressRoute` and enhances what Ingress can do today by enabling new features not previously possible. - -IngressRoute is designed to provide a sensible home for configuration parameters as well as to share an ingress controller across multiple namespaces and teams in the same Kubernetes cluster. We do this by using a process we call delegation. This delegation concept patterns off of the way a subdomain is delegated from one domain name server to another, and allows for teams to define and self-manage IngressRoute resources safely. - -## Contour 0.10 -Version 0.10 of Contour adds some exciting features to address TLS certificates and how they are referenced. This new version brings a feature called [TLS Certificate Delegation][3]. This facility makes it possible for an IngressRoute objects to reference, subject to the appropriate permissions, a Kubernetes Secret object in another namespace. The primary use case for this facility is to allow you, as an administrator, to place a TLS wildcard certificate in a secret object in your own namespace and delegate the permission for Contour to reference that secret from another namespace. - -Much like how IngressRoute delegation can limit which namespaces can utilize a host plus path combination, this TLS cert delegation now similarly limits what certificates users can access, further enhancing Contour’s multi-team functionality. - -## Future Plans -The Contour team would love to hear your feedback on your application requirements (not just how you do it today). This approach ensures that we don’t use a feature the wrong way to abuse how one is designed to solve other requirements. - -Contour is also very community driven so please speak up! Many features today (including IngressRoute) were driven from users who needed a better way to solve their current problems. - -If you are interested in contributing, a great place to start is to comment on one of the issues labeled with [Help Wanted][4] and work with the team on how to resolve them. - -We’re immensely grateful for all of the community contributions that help make Contour even better! For version 0.10, special thanks go out to: -* @vaamarnath -* @256dpi - -_Previously posted on _ - -[1]: https://en.wikipedia.org/wiki/OSI_model#Layer_7:_Application_Layer -[2]: https://kubernetes.io/docs/concepts/services-networking/ingress/ -[3]: {{< param github_url >}}/blob/v0.10.0/design/tls-certificate-delegation.md -[4]: {{< param github_url >}}/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3A%22Help+wanted%22+ diff --git a/site/content/posts/2019-07-11-kindly-running-contour.md b/site/content/posts/2019-07-11-kindly-running-contour.md deleted file mode 100644 index 50dd1a89a14..00000000000 --- a/site/content/posts/2019-07-11-kindly-running-contour.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: Kind-ly running Contour -image: /img/posts/kind-contour.png -excerpt: This blog post demonstrates how to install kind, create a cluster, deploy Contour, and then deploy a sample application, all locally on your machine. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Steve Sloka', 'kind'] -date: 2019-07-11 -slug: kindly-running-contour ---- - -[kind][1] is a tool for running local Kubernetes clusters using Docker container “nodes.” Primarily designed for testing Kubernetes 1.11 or later, kind is initially targeting the upstream Kubernetes conformance tests, which are run to verify if a cluster meets standard expectations. It is also an excellent tool for creating a Kubernetes cluster locally on many platforms (Linux, macOS, or Windows), especially since it can create multi-node clusters quickly and reliably. - -This blog post demonstrates how to install kind, create a cluster, deploy Contour, and deploy a sample application, all locally on your machine which enables running applications locally the same way they are deployed to production. - - -![image](/img/posts/kind-contour.png) - -*Example of a four worker node cluster with a single control plane.* - -Here's a quick video demonstration of how to install kind, create a cluster, deploy Contour, and deploy a sample application. - -[![image](/img/posts/kind-contour-video.png)][4] - -## Install Kind - -There are a number of ways to [install kind][5]. Here is a simple way to grab the latest release for a Darwin architecture. The following commands downloads the latest binary, makes it executable, and moves it to your local bin path. - -Note: You may want to update some portions of the commands to match your local operating system and configuration. - -```bash -$ curl -Lo ./kind-darwin-amd64 https://github.com/kubernetes-sigs/kind/releases/download/v0.6.0/kind-darwin-amd64 -$ chmod +x ./kind-darwin-amd64 -$ sudo mv ./kind-darwin-amd64 /usr/local/bin/kind -``` - -## Create a Cluster - -Now that we have kind installed, let’s create a cluster. Running the command `kind create cluster` generates a single node cluster. This command is the simplest way of creating a cluster, but for this example, we want to pass an additional configuration to the cluster creation step to map Ports 80 on the Kubernetes worker node to Port 80 on the local Docker network. - -Save the following yaml to a file named `kind.config.yaml` and run the create cluster command: - -```bash -$ kind create cluster --config kind.config.yaml -``` - -```yaml -# Save to 'kind.config.yaml' -kind: Cluster -apiVersion: kind.sigs.k8s.io/v1alpha3 -nodes: -- role: control-plane -- role: worker - extraPortMappings: - - containerPort: 80 - hostPort: 80 - listenAddress: "0.0.0.0" - - containerPort: 443 - hostPort: 443 - listenAddress: "0.0.0.0" -``` - -Note: You can only have a single worker with this configuration because you can’t map multiple Docker containers (i.e., worker nodes) to the same port on a single Docker instance. - - -After the cluster comes up, you should have two nodes in the cluster, a worker node and a control plane node: - - -![image](/img/posts/kind-contour2.png) - - -## Deploy Contour - -Next, we’ll deploy Contour into our freshly created cluster. We are going to use a "split" deployment, which configures [Envoy][7] as a DaemonSet. - -Contour is the configuration server for Envoy --- Contour, that is, exposes an xDS API for Envoy. Contour watches the Kubernetes cluster for changes to services, end points, secrets, ingress, and HTTPProxies. Contour generates a set of configurations that is streamed to Envoy via the xDS gRPC connection. All data travels through Envoy, which is running on every node in the cluster (a single node in our example). - -Additionally, the Envoy DaemonSet will be configured to use `HostNetworking` to bind Envoy's ports directly to the worker node. - -Deploy contour: - -```bash -$ git clone https://github.com/projectcontour/contour.git -$ kubectl apply -f contour/examples/contour -``` - -Since our deployment of kind is binding ports 80 and 443 to our laptop, when we curl `localhost:80` or `localhost:443`, the request will arrive at the Envoy pod. But to enable Envoy to route these requests, we need to deploy some ingress resources, which we will do as part of deploying the sample application. - -## Deploy the Sample Application - -Finally, we’ll deploy a sample application to to verify the network ingress path is functional to an application. By deploying this way, we are matching how we would deploy an application in production within Kubernetes, so any testing done locally inside the `kind` cluster should match how the application will perform once deployed. Since we already cloned the Contour repo in the previous step, let’s deploy the [kuard][8] sample application, which is an example workload in the repo. - -Deploy the application: - -```bash -$ kubectl apply -f https://projectcontour.io/examples/kuard-httpproxy.yaml -``` - -Now that the application is up and running, we need a way to route to it. The sample we just deployed uses `kuard.local` for the domain name. - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - labels: - app: kuard - name: kuard - namespace: default -spec: - virtualhost: - fqdn: kuard.local - routes: - - conditions: - - path: / - services: - - name: kuard - port: 80 -``` - -Let’s create an entry in our local `/etc/hosts` to route `kuard.local` to `127.0.0.1` (i.e., Envoy running in kind). - -```bash -## -# Host Database -# -# localhost is used to configure the loopback interface -# when the system is booting. Do not change this entry. -## -127.0.0.1 localhost -255.255.255.255 broadcasthost -::1 localhost -127.0.0.1 kuard.local # <--- add this! -``` - -Now open a browser and go to: `http://kuard.local` -![image](/img/posts/kind-contour3.png) - -What's happening is that the request to `http://kuard.local` is resolved to `127.0.0.1` via the entry the `/etc/hosts` file. That request is then sent to Envoy running on the single Kubernetes worker node in the `kind` cluster. Envoy is configured to send any request to `kuard.local/` to the `kuard` application in the cluster. The request then gets routed to an instance of `kuard` and the response is sent back to the user. - -This blog post helps you enable Contour in your local development environment by allowing you to match the way you'd deploy your application in production. Any testing done locally inside the `kind` cluster should match how the application will perform once deployed reducing the time required testing in production. I hope this blog post better equip your usage of Contour! - - -[1]: https://github.com/kubernetes-sigs/kind -[4]: https://youtu.be/j97MueCYcvc -[5]: https://github.com/kubernetes-sigs/kind#installation-and-usage -[7]: https://envoyproxy.io -[8]: https://github.com/kubernetes-up-and-running/kuard - - diff --git a/site/content/posts/2019-07-23-contour-v014.md b/site/content/posts/2019-07-23-contour-v014.md deleted file mode 100644 index 5082202841b..00000000000 --- a/site/content/posts/2019-07-23-contour-v014.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Secure xDS Server Communication with Contour v0.14 -image: /img/posts/post-contour-split-deployment.png -excerpt: This blog post covers key features of the Contour v0.14.0 release including securing xDS communication with Envoy. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Steve Sloka', 'release'] -date: 2019-07-23 -slug: contour-v014 ---- - -Contour is an Ingress controller for Kubernetes that works by deploying the Envoy proxy as a reverse proxy and load balancer. Contour supports dynamic configuration updates out of the box while maintaining a lightweight profile. - -There are a few different models that you can implement when you deploy Contour to a Kubernetes cluster. Up until the latest Contour release, v0.14, we’ve typically used the co-located model, which places Contour and Envoy in the same pod communicating over `localhost`. - -However, there are many use cases where this deployment paradigm is less desired. With v0.14, a more secure split deployment model has been added. This style separates Contour’s deployment from Envoy so that they can have different life cycles. - -![image](/img/posts/post-contour-split-deployment.png) -*Overview of the split-model deployment.* - -Contour’s split model offers the following benefits for users: - -- Contour and Envoy life cycles can be managed independently -- Less load on the Kubernetes API server -- Secure communication between the Contour xDS server and Envoy - - -## Contour’s Architecture - -Contour provides the management server for Envoy by implementing an xDS server. Envoy connects to the Contour xDS server over gRPC and requests configuration items, such as clusters, endpoints, and routes to configure itself. Contour integrates with the Kubernetes API server and looks for services, endpoints, secrets, Kubernetes Ingress resources, and Contour IngressRoute objects. When a change to any of these happen, Contour rebuilds a set of configurations for Envoy to consume through the xDS server. - -## Secure Split Deployment Model - -Until Contour release v0.14, the deployment model placed Contour and Envoy in the same pod, so gRPC communication occurred over `localhost`. This approach was convenient because Contour was deployed in a single service. However, as you scale out Contour in this model, Contour and Envoy scale together. Each instance of Contour adds a `watch` on the Kubernetes API server for the objects it acts on, adding load to the server. - -The split model allows Contour and Envoy to scale independently. If a new version of Contour is released, you can now upgrade to the new version without having to restart each instance of Envoy in your cluster. - -A key new feature in Contour v0.14 is that we have secured the communication between Contour and Envoy over the xDS API connection utilizing mutually checked self-signed certificates. There are three ways to generate certificates to secure this connection. -The Contour repo includes step-by-step examples of how to generate certificates from a command line if you want to [generate them by hand][2]; the example/contour [example][3] includes a [job][4] which automatically generate the certificates, or you could provide your own based on your IT security requirements. - - -## More new features in Contour v0.14 - -Version 0.14 also adds better support for deploying Envoy with various hostnames. Envoy routes traffic at the L7 or HTTP routing level. Previous versions of Contour required requests to be sent over Port 80 or Port 443. Now Contour configures Envoy to route requests without this requirement, allowing for easier deployments within your local laptop or network infrastructure. - -We recently wrote a blog post walking through how to deploy Contour to [kind][5], which is a tool for creating Kubernetes clusters on your local development machine: [Kind-ly running Contour][6]. - -## Future Plans - -The Contour project is very community driven and the team would love to hear your feedback! Many features (including IngressRoute) were driven by users who needed a better way to solve their problems. We’re working hard to add features to Contour, especially in expanding how we approach routing. Please look out for [design documents](https://github.com/projectcontour/contour/tree/main/design) for the new IngressRoute/v1 routing design which will be a large discussion topic for our next community meeting! - -If you are interested in contributing, a great place to start is to comment on one of the issues labeled with [Help Wanted][7] and work with the team on how to resolve them. - -We’re immensely grateful for all the community contributions that help make Contour even better! For version v0.14, special thanks go out to: - -- [@odacremolbap](https://github.com/odacremolbap) -- [@mwhittington21](https://github.com/mwhittington21) - - -[2]: /docs/{{< param latest_version >}}/grpc-tls-howto -[3]: {{< param github_url >}}/blob/{{< param latest_version >}}/examples/contour -[4]: {{< param github_url >}}/blob/{{< param latest_version >}}/examples/contour/02-job-certgen.yaml -[5]: https://github.com/kubernetes-sigs/kind -[6]: {{< relref "/posts/2019-07-11-kindly-running-contour" >}} -[7]: {{< param github_url >}}/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22 diff --git a/site/content/posts/2019-09-17-projectcontour.md b/site/content/posts/2019-09-17-projectcontour.md deleted file mode 100644 index b2ba1ea049b..00000000000 --- a/site/content/posts/2019-09-17-projectcontour.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: New GitHub Organization, Who Dis? -excerpt: Contour has moved to a new GitHub organization -author_name: Dave Cheney -author_avatar: /img/contributors/dave-cheney.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Dave Cheney'] -date: 2019-09-17 -slug: projectcontour ---- - -Times change. Summer turns to autumn, leaves fall from their branches, brands die and are reborn. The cycle of life. - -Yes, it's time to wish the Heptio brand a fond farewell. As we gather on the shores to watch the pyre burn it is a time for happiness because Contour isn't dead, we've just moved house. - -You might have noticed the cheery 301 redirect that GitHub sent your browser to inform it that Contour's new home is https://github.com/projectcontour/contour. diff --git a/site/content/posts/2019-09-27-from-ingressroute-to-httpproxy.md b/site/content/posts/2019-09-27-from-ingressroute-to-httpproxy.md deleted file mode 100644 index 55c09fa2333..00000000000 --- a/site/content/posts/2019-09-27-from-ingressroute-to-httpproxy.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: From IngressRoute to HTTPProxy -excerpt: -author_name: Dave Cheney -author_avatar: /img/contributors/dave-cheney.png -categories: [kubernetes] -tags: ['IngressRoute', 'HTTPProxy', 'ingress', 'Dave Cheney'] -date: 2019-09-27 -slug: from-ingressroute-to-httpproxy ---- - -As part of the preparations to deliver Contour 1.0 at KubeCon US, [Contour 1.0.0-beta.1 (available now!)][1] renamed the [IngressRoute][2] CRD to [HTTPProxy][3]. -This post explains the path from IngressRoute to HTTPProxy and why the change isn't a revolution but an evolution. - -## IngressRoute is dead, long live HTTPProxy - -More than a year ago Contour 0.6 introduced a new CRD, IngressRoute. -IngressRoute was our attempt to address the issues preventing Kubernetes developers from utilizing modern web deployment patterns in multi tenant Kubernetes clusters. - -Fast forward to July of this year where plans to move Contour out of the _0.whatever_ doldrums were being set in motion. -We knew that stamping a 1.0 release on Contour required us to do the same for IngressRoute, which had at that point been in beta for a period of time that would make a Google product blush. -Bringing IngressRoute, as it was known at the time, to 1.0 status would involve three things. - -The first was addressing, which in retrospect seemed like an inspired piece of guerrilla marketing, the fact that I had plastered not just the name of the product but the name of the sponsoring company throughout annotation names, CRD groups, repository image hosting, and namespace objects. -Taking the necessary hit to _rename all the things_ is the focus of the beta.1 and upcoming rc.1 releases. - -Once these procedural issues were in hand the second issue was to consider the name _IngressRoute_ itself. -The name, to the best of my recollection chosen without any particular deliberation, was more of a portmanteau of the problems IngressRoute was designed to solve; improving Ingress in multi tenant clusters, and more flexible Routing. - -With a year's experience developing and supporting IngressRoute, a few problems with the name had become evident. -As a name, IngressRoute was lengthy. -Abbreviating it introduced confusion with another Kubernetes object--also in beta--which we didn't want to be confused with. -If you wanted to be precise, you had to type, and _say aloud_, the entire thing. -But there are more problems than verbosity. - -The original Kubernetes Ingress object was clearly intended to address more than just HTTP routing. -The word Ingress, especially if you talk to the overlay, physical, or software defined networking folks, has nothing to do with layer 7 proxying and load balancing. -Contour defined its mission as an Ingress controller by what Kubernetes users were using the Ingress object for in 2017: HTTP routing, load balancing, and proxying. -Collectively Kubernetes cloud natives might call the configuration for our HTTP proxies _Ingress_, but what were were doing had little to do with ingress and egress traffic as networking vendors define it. -The name _HTTPProxy_ reflects the desire to clarify Contour's role in the crowded Kubernetes networking space. - -The final issue is addressing the limitations in the IngressRoute--now HTTPProxy--object which we felt could not be solved in an backwards compatible way once we committed to a v1 of the object. -HTTPProxy brings with it two new concepts--[inclusion][4] and [conditions][5]--which, like the transition from IngressRoute to HTTPProxy, represent the respective evaluations of the delegation model and our limited support for prefix based routing. - -The intent of making this change now is to prepare HTTPProxy as a stable CRD for Contour users following the same backwards compatibility goals as Contour 1.0. -With this goal in mind the IngressRoute CRD, having never made it out of beta, should be considered deprecated. -Contour will continue to support the IngressRoute CRD up to the 1.0 release of Contour in November, however no further enhancements or bug fixes will be made over this period unless absolutely necessary. -The plan at this stage is to remove support for the IngressRoute CRD after Contour 1.0 ships. -We've [written a guide][6] to help you transition your IngressRoute objects to HTTPProxy. - -The next blog post in this series will delve into how to use inclusion and conditions. -Stay tuned for that. - -## TCP proxying future - -The final question that should be answered is, with the focus on layer 7 HTTP proxying, what is the future of Contour's TCP proxying feature? -The short answer is Contour's layer 3/4 TCP proxying feature is not going away. -Despite the cognitive dissonance, we're committed to supporting and enhancing Contour's TCP proxying abilities via the HTTPProxy CRD for the long term. - -[1]: {{< param github_url >}}/releases/tag/v1.0.0-beta.1 -[2]: {{< param github_url >}}/blob/v1.0.0-beta.1/docs/ingressroute.md -[3]: {{< param github_url >}}/blob/v1.0.0-beta.1/docs/httpproxy.md -[4]: {{< param github_url >}}/blob/v1.0.0-beta.1/docs/httpproxy.md#httpproxy-inclusion -[5]: {{< param github_url >}}/blob/v1.0.0-beta.1/docs/httpproxy.md#conditions -[6]: {% link _guides/ingressroute-to-httpproxy.md %} diff --git a/site/content/posts/2019-09-5-contour-v015.md b/site/content/posts/2019-09-5-contour-v015.md deleted file mode 100644 index 638a0083519..00000000000 --- a/site/content/posts/2019-09-5-contour-v015.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Leader Election and Configuration Files with Contour v0.15 -image: /img/posts/leader-election.png -excerpt: This blog post covers key features of the Contour v0.15 release including leader election and the Contour configuration file. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Steve Sloka', 'release'] -date: 2019-09-05 -slug: contour-v015 ---- - -In the previous release of Contour, a split deployment model was improved to secure communication between Envoy and Contour. Now, with our latest release, Contour v0.15, leader election is available to ensure that all instances of Envoy take their configuration from a single Contour instance. - -![img](/img/posts/leader-election.png) -*Overview of leader election.* - -## Leader Election - -Each instance of Contour configures a connection to the Kubernetes API server in order to watch for changes to objects in the cluster. Contour is concerned with Services, Endpoints, Secrets, Ingress, and IngressRoute objects. Having multiple readers to the Kubernetes API is fine (and is implemented in many different components); however, since Contour updates the status of an IngressRoute object, multiple writers (that is, multiple instances of Contour) can cause issues when each one of them attempts to update the status. Additionally, it’s possible that each instance of Contour processes events from Kubernetes at a different time, causing different configurations to be passed to Envoy. - -In leader election mode, only one Contour pod in a deployment, the leader, will open its gRPC endpoint to serve requests from Envoy. All other Contour instances will continue to watch the API server but will not serve gRPC requests. Leader election can be used to ensure that all instances of Envoy take their configuration from a single Contour instance. - -Leader election is currently opt in. In future versions of Contour, we plan to make leader election mode the default. - -For more information, please consult the [documentation on upgrading][1]. - -## Contour Configuration File - -Contour has previously supported configuration options to be passed via command-line arguments to the Contour process. Changes to these parameters meant updating the deployment spec. - -Here’s an example spec from a Kubernetes Deployment manifest: - -```yaml -containers: - - args: - - serve - - --incluster - - --enable-leader-election - - --xds-address=0.0.0.0 - - --xds-port=8001 -``` - -Now with v0.15, a configuration file can specify configurations that apply to each Contour installation. However, per-Ingress or per-Route configuration continues to be drawn from the objects and CRDs in the Kubernetes API server. - -Sample configuration file: - -``` -apiVersion: v1 -kind: ConfigMap -metadata: - name: contour - namespace: heptio-contour -data: - contour.yaml: | - # should contour expect to be running inside a k8s cluster - # incluster: true - # - # path to kubeconfig (if not running inside a k8s cluster) - # kubeconfig: /path/to/.kube/config - # - # disable ingressroute permitInsecure field - # disablePermitInsecure: false - tls: - # minimum TLS version that Contour will negotiate - # minimumProtocolVersion: "1.1" - # The following config shows the defaults for the leader election. - # leaderelection: - # configmap-name: contour - # configmap-namespace: leader-elect -``` - -## More new features in Contour v0.15 - -Version 0.15 includes several fixes. It patches several CVEs related to HTTP/2 by upgrading Envoy to v1.11.1. To help with the number and frequency of configuration updates sent to Envoy, Contour now ignores unrelated Secrets and Services that are not referenced by an active Ingress or IngressRoute object. - -We recommend reading the full release notes for [Contour v0.15][2] as well as digging into the [upgrade guide][3], which outlines some key changes to be aware of when moving from v0.14 to v0.15. - -## Future Plans - -The Contour project is very community driven and the team would love to hear your feedback! Many features (including IngressRoute) were driven by users who needed a better way to solve their problems. We’re working hard to add features to Contour, especially in expanding how we approach routing. - -If you are interested in contributing, a great place to start is to comment on one of the issues labeled with [Help Wanted][4] and work with the team on how to resolve them. - -We’re immensely grateful for all the community contributions that help make Contour even better! For version v0.15, special thanks go out to: - -- [@DylanGraham](https://github.com/DylanGraham) -- [@so0k](https://github.com/so0k) -- [@mattalberts](https://github.com/mattalberts) - -[1]: {{< param github_url >}}/blob/v0.15.0/docs/upgrading.md#enabling-leader-election -[2]: {{< param github_url >}}/releases/tag/v0.15.0 -[3]: {{< param github_url >}}/blob/v0.15.0/docs/upgrading.md -[4]: {{< param github_url >}}/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22 diff --git a/site/content/posts/2019-10-23-httpproxy-in-action.md b/site/content/posts/2019-10-23-httpproxy-in-action.md deleted file mode 100644 index 4c146fd8fa0..00000000000 --- a/site/content/posts/2019-10-23-httpproxy-in-action.md +++ /dev/null @@ -1,358 +0,0 @@ ---- -title: HTTPProxy in Action -image: /img/posts/proxyinaction.png -excerpt: This blog post covers a practical demonstration of how HTTPProxy works. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Steve Sloka', 'tutorial'] -date: 2019-10-23 -slug: httpproxy-in-action ---- - -In our previous [blog post][1], Dave Cheney walked through Contour’s evolution from `IngressRoute` to `HTTPProxy` and explained how & why the move happened. - -Now with `HTTPProxy`, Contour allows for additional routing configuration outside of just supporting a `path prefix`. - -This post demonstrates a practical implementation of `HTTPProxy` and reviews some examples that explain how you can use it in your cluster today. - -[![img][2]][3] -*Here's a quick video demonstration walking through the rest of the blog post.* - -## Prerequisites -If you’d like to follow along in your own cluster, you’ll need a working Kubernetes cluster as well as Contour deployed. There are a number of ways to get these up and working. A simple way to test this locally is to use Kubernetes in Docker (Kind); you can check out our previous blog post on how to get this up and running on your local machine: [https://projectcontour.io/kindly-running-contour/][4] - -## Demo Time -Let’s walk through a simple scenario to quickly demonstrate how these new features work with `HTTPProxy`. This demo will progress through various features of `HTTPProxy` by starting off with a set of prerequisite services and deployments. Then it will move to implement `conditions` on routes to further specify request route matching. Finally, we’ll introduce `includes`, which will allow us to delegate path and header conditions to other `HTTPProxy` resources in different namespaces. - -## Setup and Prerequisites -We’ll start by creating a sample set of applications and services, which we will use to set up some routing with `HTTPProxy`: - -```bash -$ kubectl apply -f https://projectcontour.io/examples/proxydemo/01-prereq.yaml -``` - -## Basic HTTPProxy -Next, we’ll apply our root HTTPProxy. This proxy is unique since it defines the `fqdn` for the requests. In our example, the FQDN is `local.projectcontour.io`. It configures two routes, one for `/` and another for `/secure`. - -_Note: If you’re running this in your own cluster, update the `fqdn` value in the spec.virtualhost section of the HTTPProxy before applying each HTTPProxy update. `local.projectcontour.io` points to 127.0.0.1 and works well if you’re running a `kind` setup._ - -```bash -$ kubectl apply -f https://projectcontour.io/examples/proxydemo/02-proxy-basic.yaml - -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: root - namespace: projectcontour-roots -spec: - virtualhost: - fqdn: local.projectcontour.io - routes: - - services: - - name: rootapp - port: 80 - conditions: - - prefix: / - - services: - - name: secureapp-default - port: 80 - conditions: - - prefix: /secure -``` - -This proxy configures any request to `projectcontour.io/` to be handled by the service `rootapp`. Requests to `/secure` will be handled by the service `secureapp-default`. - -At this point, the following requests map like this: - -- GET projectcontour.io/ → `rootapp:80` service -- GET projectcontour.io/secure → `secureapp-default:80` service - -### Sample Requests -```bash -$ curl http://local.projectcontour.io/ - -ECHO Request Server: --------------------- -App: - This is the default app site! -Request: - http://local.projectcontour.io/ - -$ curl http://local.projectcontour.io/secure - -ECHO Request Server: --------------------- -App: - This is the secure app site! -Request: - http://local.projectcontour.io/secure -``` -## Conditions -New in `HTTPProxy` is a concept called `conditions`, which allows you to define a set of request parameters that need to match for a route to receive requests. Contour allows for a `prefix` condition as well as a set of `header` conditions to be defined on requests. - -Let’s reconfigure the `root` proxy to handle requests with HTTP headers. We will target any request to `local.projectcontour.io/secure` that matches the header `User-Agent` containing the value of `Chrome` to route to the `secureapp` backend. Any other requests to `local.projectcontour.io/secure` that do not match the header we defined should route to `secureapp-default`. - -In the previous example, we added `prefix` conditions to the route. In this example, we add a new type called `header`, which allows us to define a header key and value that must match the request. Header conditions can use `exact` to match the value exactly, or they can use `contains` to match a specified value that exists somewhere in the header value. (We can also specify `notexact` and `notcontains`, which inverse the match.) - -```bash -$ kubectl apply -f https://projectcontour.io/examples/proxydemo/03-proxy-conditions.yaml - -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: root - namespace: projectcontour-roots -spec: - virtualhost: - fqdn: local.projectcontour.io - routes: - - services: - - name: rootapp - port: 80 - conditions: - - prefix: / - - services: - - name: secureapp-default - port: 80 - conditions: - - prefix: /secure - - services: - - name: secureapp - port: 80 - conditions: - - prefix: /secure - - header: - name: User-Agent - contains: Chrome -``` - -It’s important to call out that for a request to match a route, all `conditions` defined must match. In the example we just applied, for the request to route to the `secreapp` service, it must have a path prefix of `/secure` as well as have a header `User-Agent` containing the value `Chrome`. Adding additional header conditions would extend the match requirements for that route. - -At this point the following requests map as follows: - -- GET local.projectcontour.io/ → `rootapp:80` service -- GET local.projectcontour.io/secure → `secureapp-default:80` service -- GET local.projectcontour.io/secure + Header[User-Agent: Chrome] → `secureapp:80` service - -### Sample Requests -``` -$ curl http://local.projectcontour.io/secure - -ECHO Request Server: --------------------- -App: - This is the DEFAULT secure app site! -Request: - http://local.projectcontour.io/secure - -$ curl -H "User-Agent: Chrome" http://local.projectcontour.io/secure - -ECHO Request Server: --------------------- -App: - This is the secure app site! -Request: - http://local.projectcontour.io/secure -``` - -## Includes across Namespaces -Also new in `HTTPProxy` is the concept of `includes` for a resource. Defining an `include` on an `HTTPProxy` causes Contour to prepend any `conditions` defined in the include to the conditions of the child proxy referenced. This can be used to delegate path prefixes to teams in different namespaces or require specific headers to be present on requests. There isn’t a limit to the number of times a proxy can reference an `include`. - -First, let’s set up a new marketing team namespace allowing them to self-manage its `HTTPProxy` resources as well as deploy a sample app/service. The marketing team will be in charge of managing the `/blog` path from the `local.projectcontour.io` domain. - -```bash -$ kubectl apply -f https://projectcontour.io/examples/proxydemo/04-marketing-prereq.yaml -``` - -Next, let’s update our `root` proxy to pass off a path to the marketing team working in the `projectcontour-marketing` namespace. We’ll also create the marketing team’s `HTTPProxy`, which is referenced from the `root` HTTPProxy and will include the path condition of `/blog` to the marketing team’s proxy named `blogsite`. - -```bash -$ kubectl apply -f https://projectcontour.io/examples/proxydemo/04-proxy-include-basic.yaml - -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: root - namespace: projectcontour-roots -spec: - virtualhost: - fqdn: local.projectcontour.io - includes: - - name: blogsite - namespace: projectcontour-marketing - conditions: - - prefix: /blog - routes: - - services: - - name: rootapp - port: 80 - conditions: - - prefix: / - - services: - - name: secureapp-default - port: 80 - conditions: - - prefix: /secure - - services: - - name: secureapp - port: 80 - conditions: - - prefix: /secure - - header: - name: User-Agent - contains: Chrome ---- -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: blogsite - namespace: projectcontour-marketing -spec: - routes: - - services: - - name: wwwblog - port: 80 -``` - -Since the `root` proxy included the path of `/blog`, requests that match `local.projectcontour.io/blog` will route to the marketing team’s service named `wwwblog` in the `projectcontour-marketing` namespace. You will notice we didn’t define any `conditions` on the marketing teams proxy. We don’t need to define them because the root proxy passed the path prefix condition to this HTTPProxy through the include. - -It’s important to note that no one else in the cluster can now utilize this path prefix. If another team would create an HTTPProxy referencing the same path, Contour would reject it because it is not part of a delegation chain. - -### Sample Requests -``` -$ curl http://local.projectcontour.io/blog - -ECHO Request Server: --------------------- -App: - This is the blog site! -Request: - http://local.projectcontour.io/blog -``` - -## Includes to the same Namespace -Just as we learned in the first example of how conditions are applied to routes, the same logic is applied to conditions on an include. Currently, the marketing team is responsible for the path `/blog`, but let’s add a few more requirements. - -The marketing team wants to create an `information` site, which will be served by the path `/blog/info`. We will create another HTTPProxy to define how the information application should be accessed. This new `HTTPProxy` will be included in the path `/info` from the `blogsite` `HTTPProxy` in the `projectcontour-marketing` namespace. - -Since `Conditions` are appended to the `HTTPProxy` when Contour processes them, the result for the information site will have the path `/blog/info`. - -```bash -$ kubectl apply -f https://projectcontour.io/examples/proxydemo/05-proxy-include-info.yaml - -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: blogsite - namespace: projectcontour-marketing -spec: - includes: - - name: infosite - conditions: - - prefix: /info - routes: - - services: - - name: wwwblog - port: 80 ---- -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: infosite - namespace: projectcontour-marketing -spec: - routes: - - services: - - name: info - port: 80 -``` - -### Sample Requests -``` -$ curl http://local.projectcontour.io/blog/info - -ECHO Request Server: --------------------- -App: - This is the blog site! -Request: - http://local.projectcontour.io/blog/info -``` - -## Includes with Headers -Finally to complete our example, the administrative team now doesn’t want the marketing site to be served by Chrome or Firefox browsers. This rule needs to apply to all applications in the `projectcontour-marketing` namespace. - -We can easily implement this requirement by just adding another set of conditions to the `root` HTTPProxy. Once we add those, they will take effect across all the children of the root HTTPProxy defined in the `projectcontour-marketing` namespace. - -```bash -$ kubectl apply -f https://projectcontour.io/examples/proxydemo/06-proxy-include-headers.yaml - -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: root - namespace: projectcontour-roots -spec: - virtualhost: - fqdn: local.projectcontour.io - includes: - - name: blogsite - namespace: projectcontour-marketing - conditions: - - prefix: /blog - - header: - name: User-Agent - notcontains: Chrome - - header: - name: User-Agent - notcontains: Firefox - routes: - - services: - - name: rootapp - port: 80 - conditions: - - prefix: / - - services: - - name: secureapp-default - port: 80 - conditions: - - prefix: /secure - - services: - - name: secureapp - port: 80 - conditions: - - prefix: /secure - - header: - name: User-Agent - contains: Chrome -``` - -Requests to `local.projectcontour.io/blog/*` that do not match the `User-Agent` header of `Chrome` or `Firefox` will now route to the appropriate services in the marketing team’s namespace. Any other requests will be handled by the `rootapp` service because it matches the other requests. - -### Sample Requests -```bash -$ curl -H "User-Agent: Safari" http://local.projectcontour.io/blog/info - -ECHO Request Server: --------------------- -App: - This is the INFO site! -Request: - http://local.projectcontour.io/blog/info - -$ curl -H "User-Agent: Firefox" http://local.projectcontour.io/blog/info - -ECHO Request Server: --------------------- -App: - This is the default app site! -Request: - http://local.projectcontour.io/blog/info -``` - -[1]: {% post_url 2019-09-27-from-ingressroute-to-httpproxy %} -[2]: {% link img/posts/kind-contour-video.png %} -[3]: https://youtu.be/YA82A4Rcs_A -[4]: {% post_url 2019-07-11-kindly-running-contour %} diff --git a/site/content/posts/2019-10-25-contour-v100rc2.md b/site/content/posts/2019-10-25-contour-v100rc2.md deleted file mode 100644 index dbf11e54ad4..00000000000 --- a/site/content/posts/2019-10-25-contour-v100rc2.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Contour 1.0.0-rc.2 has been released -excerpt: Contour 1.0 is just around the corner. -author_name: Dave Cheney -author_avatar: /img/contributors/dave-cheney.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'release', 'Dave Cheney'] -date: 2019-10-25 -slug: contour-v100rc2 ---- - -Contour 1.0.0-rc.2 is the second, and hopefully final, release candidate on the path to Contour 1.0. -Assuming that no serious issues are found next week we're on track to release Contour 1.0 on November 1st. - -It goes without saying that without the help of the many community contributors this release, nor the 38 that preceded it, would not have been possible. -Thank you all. - -You can read the full [1.0.0-rc.2 release notes][1] over on GitHub, but as you're here, here are a few highlights. - -## Website improvements - -As part of the continued preparations for the 1.0 release Contour's documentation has been relocated to the projectcontour.io website. Specifically; - -* The Getting Started documentation has moved to [projectcontour.io/getting-started][2] -* Guides and How-to's have moved to [projectcontour.io/guides][3] -* Versioned release documentation has moved to [projectcontour.io/docs][4] -* Project related and non-versioned documentation has moved to [projectcontour.io/resources][5] - -We're working hard to polish the website content ahead of the 1.0 release. Please pardon our dust. - -## IngressRoute and HTTPProxy status update improvements - -IngressRoute and HTTPProxy status updates are now performed by the lead Contour in the deployment. -We're hopeful that this will put to rest the many issues related to status update loops over the years. - -## HTTPProxy and IngressRoute OpenAPIv3 schema validation - -Contour 1.0.0-rc.2 includes updated OpenAPIv3 schema validations. -These schemas are automatically generated from the CRDs themselves and should be more complete and consistent than the previous hand rolled versions. - -## TCPProxy delegation - -Contour 1.0.0-rc.2 now supports TCPProxy delegation. See the [relevant section][6] in the HTTPProxy documentation. - -## Envoy keepalive tuning - -Contour 1.0.0-rc.2 configures various keep alive mechanisms to detect network connectivity issues between Envoy and Contour. -This helps Contour and Envoy work better with overlay networks which drop long running idle TCP connections. - -## Contour now waits for a full cache before talking to Envoy. - -Contour now delays serving traffic to Envoy until each of the API informers caught up to the API server. -This changes reduces the likelihood that Envoy can connect to a Contour instance in the process of startup and thus observe an incomplete view of the cluster. - -## Upgrading - -Please consult the [Upgrading][7] document for information on upgrading from Contour 1.0.0-rc.1 to Contour 1.0.0-rc.2. - -[1]: {{< param github_url >}}/releases/tag/v1.0.0-rc.2 -[2]: /getting-started -[3]: /guides -[4]: /docs -[5]: /resources -[6]: {% link docs/v1.0.0/httpproxy.md %} -[7]: {% link _resources/upgrading.md %} diff --git a/site/content/posts/2019-11-01-announcing-contour-1.0.md b/site/content/posts/2019-11-01-announcing-contour-1.0.md deleted file mode 100644 index 4998243a949..00000000000 --- a/site/content/posts/2019-11-01-announcing-contour-1.0.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Announcing Contour 1.0: A Proxy for Your Multi-Tenant Future -excerpt: The Journey from 0.1 to 1.0 -author_name: Contour Team -#author_avatar: /img/Contour.svg -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'release'] -date: 2019-11-01 -slug: announcing-contour-1.0 ---- - -_Authored by Dave Cheney, Steve Sloka, Nick Young, and James Peach_ - -Exactly two years ago, we launched a [new open-source ingress controller][1]. Contour was the first ingress controller to take advantage of the growing popularity of Envoy to create a layer 7 load-balancing solution for Kubernetes users. Contour was also the first Ingress controller to make use of Envoy’s gRPC API, which allowed changes to be streamed directly from Kubernetes. - -Today, we are very happy to announce **Contour 1.0**. We’ve come a long way since that first commit two years ago! This blog post takes stock of our journey to Contour 1.0 and describes some of the new features in this milestone release. - -## The Journey from 0.1 to 1.0 - -Since its launch, Contour has held to a monthly release cadence. This pace allowed us to explore the problems that administrators and development teams were struggling with when deploying modern web applications on top of Kubernetes. In the process, we’ve iterated rapidly to introduce a compelling set of features. After two years, we’ve decided it's time to move out of the shadow of perpetual beta and commit to a stable version of Contour and its CRD types. - -Contour 1.0 moves the HTTPProxy CRD to version 1 and represents our commitment to evolve that API in a backward-compatible manner. - -## From Ingress to IngressRoute to HTTPProxy - -The Kubernetes Ingress object has many limitations. Some of those are being addressed as part of SIG-Networking’s work to bring Ingress to v2, but other limitations that prevent Ingress from being used safely inside multi-tenant clusters remain unsolved. - -In this spirit, Contour 0.6, released in September of 2018, introduced a new CRD, IngressRoute. IngressRoute was our attempt to address the issues preventing application developers from utilizing modern web development patterns in multi-tenant Kubernetes environments. - -As part of preparations for bringing IngressRoute from beta to v1, it has been renamed HTTPProxy. This new name reflects the desire to clarify Contour's role in the crowded Kubernetes networking space by setting it apart from other networking tools. - -HTTPProxy brings with it two new concepts, inclusion and conditions, both of which, like the transition from IngressRoute to HTTPProxy, represent evolutions of the IngressRoute’s delegation model and limited support for prefix-based matching. - -## Decoupled Deployment - -Originally, our recommended deployment model for Contour was for the Contour and Envoy containers to share a pod, controlled by a DaemonSet. However, this model linked the lifecycles of Contour and Envoy. You could not, for instance, update Contour’s configuration without having to take an outage of the co-located Envoy instances. - -In order to change this model, we needed to make it straightforward to secure your xDS traffic. This is because the TLS certificates and keys used for serving traffic must be transmitted to Envoy across the xDS connection. To make sure that these can’t leak out, we introduced secure gRPC over TLS and a subcommand, `contour certgen`, that generates a set of self-signed keypairs for you. When you install Contour 1.0 using our example deployment, this is all done automatically for you. - -Splitting Contour and Envoy apart also allowed us to enable leader election for Contour. Kubernetes leader election is a standard feature that allows you to use Kubernetes primitives as a distributed locking mechanism, and designate one Contour as the leader. In Contour 1.0, this leadership is what controls which Contour instance can write status updates back to HTTPProxy objects. - -## Notable Features - -* Contour 1.0 supports outputting HTTP request logs in a configurable structured JSON format. -* Under certain circumstances, it is now possible to combine TLS pass-through on Port 443 with Port 80 served from the same service. The use case for this feature is that the application on Port 80 can provide a helpful message when the service on Port 443 does not use HTTPS. -* One service per route can be nominated as a mirror. The mirror service will receive a copy of the read traffic sent to any non-mirror service. The mirror traffic is considered read only; any response by the mirror will be discarded. -* Per-route idle timeouts can be configured with the HTTPProxy CRD. - -## What’s Next after 1.0? - -What does the future hold for Contour? In a word (if this is a word): HTTPProxy. We plan to continue to explore the ways Contour can complement the work of application teams deploying web application workloads on Kubernetes, and the operations teams responsible for supporting those applications in production. - -We will continue to follow the progression of discussions about Ingress v1 and v2 in the Kubernetes community, and at this time, we expect to add support for those objects when they become available. - -We’re also mindful of the ever-present feature backlog we’ve accrued during the process of delivering Contour 1.0. The backlog will require careful prioritization, and we will have to walk the line between endless configuration knobs and a recognition that no two applications, deployments, or clusters are identical. - -## Contributor Shoutouts - -We’re immensely grateful for all the community contributions that help make Contour even better! The lifeblood of any open source project is its community. - -![Contour 1.0 stats][2] - -The sign of a strong community is how users communicate through Slack and GitHub Issues as well as make contributions back to the project. We couldn’t have made it to 1.0 without you. **Thank you!** - -[![256dpi](https://avatars2.githubusercontent.com/u/696886?v=4&s=48)](https://github.com/256dpi) -[![aknuds1](https://avatars1.githubusercontent.com/u/281303?v=4&s=48)](https://github.com/aknuds1) -[![alexbrand](https://avatars2.githubusercontent.com/u/545723?v=4&s=48)](https://github.com/alexbrand) -[![alvaroaleman](https://avatars2.githubusercontent.com/u/6496100?v=4&s=48)](https://github.com/alvaroaleman) -[![andrewsykim](https://avatars0.githubusercontent.com/u/12699319?v=4&s=48)](https://github.com/andrewsykim) -[![arminbuerkle](/img/contour-1.0/22750465.png)](https://github.com/arminbuerkle) -[![Atul9](https://avatars1.githubusercontent.com/u/3390330?v=4&s=48)](https://github.com/Atul9) -[![awprice](https://avatars3.githubusercontent.com/u/2804025?v=4&s=48)](https://github.com/awprice) -[![bgagnon](https://avatars2.githubusercontent.com/u/81865?v=4&s=48)](https://github.com/bgagnon) -[![bhudlemeyer](https://avatars1.githubusercontent.com/u/2275490?v=4&s=48)](https://github.com/bhudlemeyer) -[![Bradamant3](https://avatars2.githubusercontent.com/u/6934230?v=4&s=48)](https://github.com/Bradamant3) -[![ceralena](https://avatars3.githubusercontent.com/u/615299?v=4&s=48)](https://github.com/ceralena) -[![cromefire](https://avatars0.githubusercontent.com/u/26320625?v=4&s=48)](https://github.com/cromefire) -[![cw-sakamoto](https://avatars2.githubusercontent.com/u/29860510?v=4&s=48)](https://github.com/cw-sakamoto) -[![davecheney](https://avatars0.githubusercontent.com/u/7171?v=4&s=48)](https://github.com/davecheney) -[![dvdmuckle](https://avatars2.githubusercontent.com/u/8870292?v=4&s=48)](https://github.com/dvdmuckle) -[![DylanGraham](https://avatars1.githubusercontent.com/u/4900511?v=4&s=48)](https://github.com/DylanGraham) -[![embano1](https://avatars0.githubusercontent.com/u/15986659?v=4&s=48)](https://github.com/embano1) -[![emman27](https://avatars0.githubusercontent.com/u/6295583?v=4&s=48)](https://github.com/emman27) -[![ffahri](https://avatars2.githubusercontent.com/u/13694962?v=4&s=48)](https://github.com/ffahri) -[![glerchundi](/img/contour-1.0/2232214.png)](https://github.com/glerchundi) -[![HerrmannHinz](https://avatars0.githubusercontent.com/u/11093419?v=4&s=48)](https://github.com/HerrmannHinz) -[![jbeda](https://avatars2.githubusercontent.com/u/37310?v=4&s=48)](https://github.com/jbeda) -[![jelmersnoeck](https://avatars1.githubusercontent.com/u/815655?v=4&s=48)](https://github.com/jelmersnoeck) -[![jhamilton1](https://avatars1.githubusercontent.com/u/40370921?v=4&s=48)](https://github.com/jhamilton1) -[![johnharris85](https://avatars3.githubusercontent.com/u/746221?v=4&s=48)](https://github.com/johnharris85) -[![jonas](https://avatars2.githubusercontent.com/u/8417?v=4&s=48)](https://github.com/jonas) -[![jonasrosland](https://avatars3.githubusercontent.com/u/1690215?v=4&s=48)](https://github.com/jonasrosland) -[![joonathan](https://avatars0.githubusercontent.com/u/3045?v=4&s=48)](https://github.com/joonathan) -[![josebiro](https://avatars0.githubusercontent.com/u/1455144?v=4&s=48)](https://github.com/josebiro) -[![joshrosso](https://avatars2.githubusercontent.com/u/6200057?v=4&s=48)](https://github.com/joshrosso) -[![jpeach](/img/contour-1.0/9917.png)](https://github.com/jpeach) -[![Lookyan](/img/contour-1.0/1040646.png)](https://github.com/Lookyan) -[![lostllama](https://avatars2.githubusercontent.com/u/9258568?v=4&s=48)](https://github.com/lostllama) -[![lucasreed](https://avatars0.githubusercontent.com/u/6800091?v=4&s=48)](https://github.com/lucasreed) -[![mitsutaka](https://avatars2.githubusercontent.com/u/557782?v=4&s=48)](https://github.com/mitsutaka) -[![msample](https://avatars1.githubusercontent.com/u/4896732?v=4&s=48)](https://github.com/msample) -[![mwhittington21](https://avatars1.githubusercontent.com/u/29389868?v=4&s=48)](https://github.com/mwhittington21) -[![nicolasbernard](https://avatars1.githubusercontent.com/u/15658?v=4&s=48)](https://github.com/nicolasbernard) -[![norrs](https://avatars2.githubusercontent.com/u/272215?v=4&s=48)](https://github.com/norrs) -[![odacremolbap](https://avatars2.githubusercontent.com/u/9891289?v=4&s=48)](https://github.com/odacremolbap) -[![paivagustavo](https://avatars0.githubusercontent.com/u/7898464?v=4&s=48)](https://github.com/paivagustavo) -[![PeteE](https://avatars3.githubusercontent.com/u/89916?v=4&s=48)](https://github.com/PeteE) -[![pims](https://avatars3.githubusercontent.com/u/27320?v=4&s=48)](https://github.com/pims) -[![prasoontelang](https://avatars2.githubusercontent.com/u/2859827?v=4&s=48)](https://github.com/prasoontelang) -[![ramnes](https://avatars2.githubusercontent.com/u/835072?v=4&s=48)](https://github.com/ramnes) -[![rata](https://avatars1.githubusercontent.com/u/70861?v=4&s=48)](https://github.com/rata) -[![rbankston](https://avatars1.githubusercontent.com/u/130836?v=4&s=48)](https://github.com/rbankston) -[![robbiemcmichael](https://avatars2.githubusercontent.com/u/2044464?v=4&s=48)](https://github.com/robbiemcmichael) -[![rochacon](https://avatars2.githubusercontent.com/u/321351?v=4&s=48)](https://github.com/rochacon) -[![rohandvora](https://avatars3.githubusercontent.com/u/8749993?v=4&s=48)](https://github.com/rohandvora) -[![rosskukulinski](https://avatars2.githubusercontent.com/u/2746479?v=4&s=48)](https://github.com/rosskukulinski) -[![rothgar](https://avatars1.githubusercontent.com/u/371796?v=4&s=48)](https://github.com/rothgar) -[![rsyvarth](https://avatars3.githubusercontent.com/u/1712051?v=4&s=48)](https://github.com/rsyvarth) -[![samuela](https://avatars0.githubusercontent.com/u/226872?v=4&s=48)](https://github.com/samuela) -[![SDBrett](https://avatars0.githubusercontent.com/u/25494777?v=4&s=48)](https://github.com/SDBrett) -[![SEJeff](https://avatars1.githubusercontent.com/u/4603?v=4&s=48)](https://github.com/SEJeff) -[![sevein](https://avatars2.githubusercontent.com/u/606459?v=4&s=48)](https://github.com/sevein) -[![shaneog](https://avatars2.githubusercontent.com/u/130415?v=4&s=48)](https://github.com/shaneog) -[![shivanshu21](https://avatars2.githubusercontent.com/u/14923644?v=4&s=48)](https://github.com/shivanshu21) -[![stephenmoloney](https://avatars3.githubusercontent.com/u/12668653?v=4&s=48)](https://github.com/stephenmoloney) -[![stevesloka](https://avatars3.githubusercontent.com/u/1048184?v=4&s=48)](https://github.com/stevesloka) -[![sudeeptoroy](/img/contour-1.0/10099903.png)](https://github.com/sudeeptoroy) -[![tasdikrahman](https://avatars1.githubusercontent.com/u/4672518?v=4&s=48)](https://github.com/tasdikrahman) -[![uablrek](https://avatars1.githubusercontent.com/u/37046727?v=4&s=48)](https://github.com/uablrek) -[![unicell](https://avatars1.githubusercontent.com/u/35352?v=4&s=48)](https://github.com/unicell) -[![vaamarnath](https://avatars1.githubusercontent.com/u/1831109?v=4&s=48)](https://github.com/vaamarnath) -[![varunkumar](https://avatars1.githubusercontent.com/u/509433?v=4&s=48)](https://github.com/varunkumar) -[![vmogilev](https://avatars1.githubusercontent.com/u/1376994?v=4&s=48)](https://github.com/vmogilev) -[![wadeholler](https://avatars1.githubusercontent.com/u/13917666?v=4&s=48)](https://github.com/wadeholler) -[![willmadison](https://avatars2.githubusercontent.com/u/1326766?v=4&s=48)](https://github.com/willmadison) -[![yob](https://avatars2.githubusercontent.com/u/8132?v=4&s=48)](https://github.com/yob) -[![youngnick](https://avatars0.githubusercontent.com/u/9346599?v=4&s=48)](https://github.com/youngnick) -[![yvespp](https://avatars0.githubusercontent.com/u/15231595?v=4&s=48)](https://github.com/yvespp) -[![zhilingc](https://avatars1.githubusercontent.com/u/15104168?v=4&s=48)](https://github.com/zhilingc) -[![zxvdr](/img/contour-1.0/223340.png)](https://github.com/zxvdr) - -_**Note**: Stats above were taken on Oct. 31, 2019._ - -[1]: {{< param github_url >}}/commit/788feabc67c4da76cd1ae3c9ac1998b43cb0e2f3 -[2]: {% link img/contour-1.0/contour-1.0-stats.png %} diff --git a/site/content/posts/2020-01-16-announcing-contour-1.1.md b/site/content/posts/2020-01-16-announcing-contour-1.1.md deleted file mode 100644 index 9d178918754..00000000000 --- a/site/content/posts/2020-01-16-announcing-contour-1.1.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: Header and Host Rewrite with Contour 1.1 -excerpt: Our latest release, Contour 1.1, now includes request and response header manipulation as well as host rewriting to external domains. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Steve Sloka', 'release'] -date: 2020-01-16 -slug: announcing-contour-1.1 ---- - -Contour continues to take shape with new features. Our latest release, [Contour 1.1](https://github.com/projectcontour/contour/releases/tag/v1.1.0), now includes request and response header manipulation as well as host rewriting to external domains. Contour 1.1 also lets you specify a service’s protocol in HTTPProxy and adds back prefix rewrite support, which was the last feature blocking many users from migrating from IngressRoute to HTTPProxy. - -## Header Manipulation - -Manipulating request and response headers are supported per-Service or per-Route. A `HeaderRequestPolicy` can be defined for both request and response requests. - -The header request policy has the following configuration: - -* **Set**: Takes a name-value pair and will create a header if it does not exist or update the value of the header specified by the key -* **Remove**: Takes the name of a header to remove - -The following example takes requests from `headers.projectcontour.io/` and applies the following logic: - -* Adds the header `X-Foo: bar` to any request before it is proxied to the Kubernetes service named `s1` and removes the header `X-Baz` -* After the request is processed by service `s1`, the response back to the requester will have the header `X-Service-Name: s1` added and will remove the header `X-Internal-Secret` - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: header-manipulation - namespace: default -spec: - virtualhost: - fqdn: headers.projectcontour.io - routes: - - services: - - name: s1 - port: 80 - requestHeadersPolicy: - set: - - name: X-Foo - value: bar - remove: - - X-Baz - responseHeaderPolicy: - set: - - name: X-Service-Name - value: s1 - remove: - - X-Internal-Secret -``` - -## Prefix Rewrite Support - -Path prefix rewrite was a feature in IngressRoute that got removed right before Contour 1.0 was released. Now in Contour 1.1, HTTPProxy supports rewriting the HTTP request URL path prior to delivering the request to the backend service. Rewriting, which is performed after a routing decision has been made, never changes the request destination. - -The pathRewritePolicy field specifies how the path prefix should be rewritten. The replacePrefix rewrite policy specifies a replacement string for a HTTP request path prefix match. When this field is present, the path prefix that the request matched is replaced by the text specified in the replacement field. If the HTTP request path is longer than the matched prefix, the remainder of the path is unchanged. - -The following example will replace the prefix `/v1/api` with `/app/api/v1` on the request: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: rewrite-example - namespace: default -spec: - virtualhost: - fqdn: rewrite.bar.com - routes: - - services: - - name: s1 - port: 80 - pathRewritePolicy: - replacePrefix: - - prefix: /v1/api - replacement: /app/api/v1 -``` - -For more information, see the documentation on [`Path Rewriting`](https://projectcontour.io/docs/v1.1.0/httpproxy/#path-rewriting). - -## Host Rewrite - -Contour supports routing traffic to `ExternalName` service types. This kind of traffic routing allows users to proxy traffic to resources that aren’t running in the same Kubernetes cluster. You could, for example, proxy traffic to an external object storage bucket. - -Some users encountered a problem with this feature, in that the host header that the externalName service received was the same host header as in the original request. This problem potentially leads to routing in the external name service to fail. - -To solve this issue, you can set a `requestHeadersPolicy` and define the `Host` header to match the value of the externalName; here’s an example: - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: header-rewrite-example -spec: - virtualhost: - fqdn: header.projectcontour.io - routes: - - services: - - name: s1 - port: 80 - requestHeadersPolicy: - set: - - name: Host - value: external.dev -``` - -Now requests to `header.projectcontour.io` will proxy to `external.dev` with the header `Host: external.dev`. - -## IngressRoute Deprecation - -Since the release of Contour 1.0, `HTTPProxy` became the successor of `IngressRoute` going forward. One struggle for users wanting to migrate is a way to convert IngressRoute resources to HTTPProxy resources. - -A new tool named [`ir2proxy`](https://github.com/projectcontour/ir2proxy) will take an `IngressRoute` object and migrate it to an HTTPProxy. - -```yaml -$ ir2proxy basic.ingressroute.yaml ---- -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: basic - namespace: default -spec: - routes: - - conditions: - - prefix: / - services: - - name: s1 - port: 80 - virtualhost: - fqdn: foo-basic.bar.com -status: {} -``` - -Ir2proxy can be installed from the [releases](https://github.com/projectcontour/ir2proxy/releases) page or via [homebrew](https://github.com/projectcontour/ir2proxy#homebrew). - -## Future Plans - -The Contour team would love to hear your feedback! Many of the features in this release were driven by users who needed a better way to solve their problems. We’re working hard to add features to Contour, especially in expanding how we approach routing. - -We recommend reading the full release notes for [Contour 1.1](https://github.com/projectcontour/contour/releases/tag/v1.1.0) as well as digging into the [upgrade guide](https://projectcontour.io/resources/upgrading/), which outlines the changes to be aware of when moving to version 1.1. - -If you are interested in contributing, a great place to start is to comment on one of the issues labeled with [Help Wanted](https://github.com/projectcontour/contour/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) and work with the team on how to resolve them. - -## Thank you! - -We’re immensely grateful for all the community contributions that help make Contour even better! For version 1.1, special thanks go out to the following people: - -[@alvaroaleman](https://github.com/alvaroaleman) -[@SDBrett](https://github.com/SDBrett) -[@dhxgit](https://github.com/dhxgit) -[@mattmoor](https://github.com/mattmoor) -[@stefanprodan](https://github.com/stefanprodan) -[@surajssd](https://github.com/surajssd) -[@tsaarni](https://github.com/tsaarni) -[@masa213f](https://github.com/masa213f) diff --git a/site/content/posts/2020-03-03-hot-reload-certificates-safely-rollout-envoy-contour-1.2.md b/site/content/posts/2020-03-03-hot-reload-certificates-safely-rollout-envoy-contour-1.2.md deleted file mode 100644 index ec2a99970ff..00000000000 --- a/site/content/posts/2020-03-03-hot-reload-certificates-safely-rollout-envoy-contour-1.2.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Hot-Reload Certificates and Safely Rollout Envoy with Contour 1.2 -excerpt: Contour 1.2 includes support for certificate rotation for xDS gRPC interface between Contour and Envoy. Additionally, Contour 1.2 assists in Envoy rollouts in your cluster to minimize the number of connection errors. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Steve Sloka', 'release'] -date: 2020-03-03 -slug: hot-reload-certificates-safely-rollout-envoy-contour-1.2 ---- - -Contour continues to add new features to help you better manage Contour operations in a cluster. Our latest feature release, Contour 1.2.0, now includes support for certificate rotation for xDS gRPC interface between Contour and Envoy as well as a new subcommand which assists in Envoy rollouts to minimize the number of connection errors. Additionally, Contour v1.2.1 is a security release which upgrades the version of Envoy to v1.13.1 which includes many [CVE fixes](https://groups.google.com/forum/#!msg/envoy-announce/sVqmxy0un2s/8aq430xiHAAJ). - -## Hot-Reload Certificates - -A few releases ago, Contour enabled secure communication between Contour and Envoy. This new feature ensured that any communication between Contour and Envoy over its gRPC connection would be secure, mainly securing the communication using TLS certificate keys. - -This was just the first step, however, and we understood that it wouldn’t solve all of our users’ problems. Thanks to [@tsaarni](https://github.com/tsaarni), we now have support for Contour to rotate its certificates without the need to restart the Contour process. - -Future work includes enabling this same functionality for Envoy. This currently has some [open issues that need to be solved in Envoy first](https://github.com/envoyproxy/envoy/issues/9359). - -Big thanks to Tero on all your effort to send these PRs as well as driving the issues upstream! - -## Envoy Shutdown Manager - -The Envoy process, the data path component of Contour, at times needs to be re-deployed. This could be due to an upgrade, a change in configuration, or a node-failure forcing a redeployment. - -As with any application rollout strategy, we want a way to implement the rollout while minimizing the effect on users. If the Envoy pods are terminated while there are still open connections, then users will receive errors. - -Contour implements a new envoy sub-command which has a shutdown-manager whose job is to manage a single Envoy instance's lifecycle for Kubernetes. The shutdown-manager runs as a new container alongside the Envoy container in the same pod. It exposes two HTTP endpoints that are used for livenessProbe as well as to handle the Kubernetes preStop event hook. - -* livenessProbe: This is used to validate the shutdown manager is still running properly. If requests to /healthz fail, the container will be restarted -* preStop: This is used to keep the container running while waiting for Envoy to drain connections. The /shutdown endpoint blocks until the connections are drained - -The Envoy container also has some configuration to implement the shutdown manager. First the preStop hook is configured to use the /shutdown endpoint which blocks the container from exiting. Finally, the pod’s `terminationGracePeriodSeconds` is customized to extend the time in which Kubernetes will allow the pod to be in the Terminating state. The termination grace period defines an upper bound for long-lived sessions. If during shutdown, the connections aren’t drained to the configured amount, the terminationGracePeriodSeconds will send a SIGTERM to the pod killing it. - -![Envoy Shutdown Manager](/img/posts/contour-1.2/envoy-shutdown-manager.png){: .center-image } - -{% youtube oO52CV-EAkw %}{: .center-image } - -For more information on this feature, [check out the docs](https://projectcontour.io/docs/v1.2.0/redeploy-envoy/) - -## Thank you! - -We’re immensely grateful for all the community contributions that help make Contour even better! For version 1.2, special thanks go out to the following people: - -[@awprice](https://github.com/awprice) -[@alex1989hu](https://github.com/alex1989hu) -[@bgagnon](https://github.com/bgagnon) -[@danehans](https://github.com/danehans) -[@dhxgit](https://github.com/dhxgit) -[@SDBrett](https://github.com/SDBrett) -[@uablrek](https://github.com/uablrek) -[@rohandvora](https://github.com/rohandvora) -[@tsaarni](https://github.com/tsaarni) -[@shyaamsn](https://github.com/shyaamsn) -[@idealhack](https://github.com/idealhack) -[@dbason](https://github.com/dbason) - -## Future Plans - -The Contour team would love to hear your feedback! Many of the features in this release were driven by users who needed a better way to solve their problems. We’re working hard to add features to Contour, especially in expanding how we approach routing. - -We recommend reading the full release notes for [Contour 1.2](https://github.com/projectcontour/contour/releases/tag/v1.2.0) as well as digging into the [upgrade guide](https://projectcontour.io/resources/upgrading/), which outlines the changes to be aware of when moving to version 1.2. - -If you are interested in contributing, a great place to start is to comment on one of the issues labeled with [Help Wanted](https://github.com/projectcontour/contour/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) and work with the team on how to resolve them. diff --git a/site/content/posts/2020-04-27-client-cert-auth-ingress-improvements.md b/site/content/posts/2020-04-27-client-cert-auth-ingress-improvements.md deleted file mode 100644 index 632673c02a0..00000000000 --- a/site/content/posts/2020-04-27-client-cert-auth-ingress-improvements.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Client Certificate Authentication and Ingress improvements in Contour 1.4 -excerpt: Contour 1.4 adds support for client certificate authentication to HTTPProxy objects. Additionally, some Ingress behaviors are fixed - Ingress addresses are now recorded correctly, and Contour's `--ingress-class` argument behaves more as you would expect. -author_name: Nick Young -author_avatar: /img/contributors/nick-young.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Nick Young', 'release'] -date: 2020-04-27 -slug: client-cert-auth-ingress-improvements ---- - -Our latest release of Contour is 1.4, which includes support for Client Certificate authentication in your HTTPProxy objects, and also updates Contour’s Ingress support to fix some missing or incorrect behaviors. In addition Contour 1.4 upgrades Envoy to 1.14.1, to keep up with Envoy’s current supported version. - -## TLS Client authentication - -This release adds support for client authentication through the use of certificates. - -So what does this mean? Well, you can now configure your HTTPProxy routes so that they require a client certificate supplied by your client (usually your browser), which allows you to use that client certificate for authentication. - -To use this feature, add the new `clientValidation` field to the `tls` stanza of your HTTPProxy document: - -``` -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -metadata: - name: with-client-auth -spec: - virtualhost: - fqdn: www.example.com - tls: - secretName: secret - clientValidation: - caSecret: client-root-ca - routes: - - services: - - name: s1 - port: 80 - -``` - -The `caSecret` field is a reference to a Kubernetes Secret that holds the CA certificate used to validate the client certificate. The Secret must contain a `ca.crt` key that holds a PEM-encoded bundle of the full trust chain for any CA used to validate certificates. - -It’s important to note that this only provides *authentication*, not *authorization*. To put this another way, Contour and Envoy can only give you a guarantee that the supplied person is the bearer of a valid certificate, not they are allowed to do something. - -Thanks very much to [@tsaarni](https://github.com/tsaarni) for getting this implemented! - -## Ingress changes - -### Ingress class - -Before this release of Contour, when configured to accept a certain `ingress.class` annotation, Contour would watch objects with that annotation and *also* with *no annotation*. This caused problems in clusters with more than one ingress controller. - -Starting with Contour 1.4, having an `ingress.class` annotation configured means that *only* objects that have a matching annotation will cause changes in Contour. - -Note that this logic change applies to both Ingress and HTTPProxy objects. - -If you don’t give Contour an `ingress.class` on its command line, then Contour will look at all objects with no `ingress.class`, *and* objects with an `ingress.class` of `contour`. This preserves the old behavior so that we don’t break you if that’s what you expect. - -### Ingress Status - -Contour now has the ability to write a `status.loadBalancer.addresses` block to Ingress objects. This block is used by services which need to know how to reach an Ingress' backing service from outside the cluster, like [external-dns](https://github.com/kubernetes-sigs/external-dns). - -There are two ways for Contour to find this information: -- by watching a Service object for the Envoy service, and putting the associated `status.loadBalancer` block from that Service into all associated Ingress objects. This is what is used in the example deployment. -- Operators can also specify an address on Contour's command line, using the `--ingress-status-address` flag. The address that’s passed on the command line will be passed straight through to the Ingress status. - -This also means that when you `kubectl get` a Contour-owned Ingress, instead of this: - -``` -$ kubectl get ingress httpbin -NAME HOSTS ADDRESS PORTS AGE -httpbin httpbin.youngnick.dev 80, 443 336d -``` -you will see this: - -``` -$ kubectl get ingress httpbin -NAME HOSTS ADDRESS PORTS AGE -httpbin httpbin.youngnick.dev x.x.x.x 80, 443 336d - -``` - -### Removed the `--use-extensions-v1beta1-ingress` flag - -The `--use-extensions-v1beta1-ingress` flag was removed from the contour serve command in Contour 1.3. If you have a previous deployment that specifies this command, you must remove it or Contour will fail to start. - -## Future Plans - -The Contour project is very community-driven and the team would love to hear your feedback! - -- Come talk about topics at our next community meeting. -- We’ve heard that a number of teams have forked Contour and we would love to hear about what changes you needed, and to see if we can help to bring them upstream. -Please consider coming to our community meeting, or contact us: either via an issue, or hit me up on Twitter [@youngnick](https://twitter.com/youngnick). - -If you are interested in contributing, a great place to start is to comment on one of the issues labeled with [Help Wanted]({{< param github_url >}}/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3A%22Help+wanted%22+) and work with the team on how to resolve them. - -## Are you a Contour user? We would love to know! -If you're using Contour and want to add your organization to our adopters list, please visit this [page](https://github.com/projectcontour/contour/blob/main/ADOPTERS.md). -If you prefer to keep your organization name anonymous but still give us feedback into your usage and scenarios for Contour, please post on this [GitHub thread](https://github.com/projectcontour/contour/issues/1269) - -## Thanks to our contributors - -We’re immensely grateful for all the community contributions that help make Contour even better! Special thanks go out to: -- Tero Saarni ([@tsaarni](https://github.com/tsaarni)) -- Peter Grant ([@pickledrick](https://github.com/pickledrick)) diff --git a/site/content/posts/2020-07-10-Contours-landscape-jul-2020.md b/site/content/posts/2020-07-10-Contours-landscape-jul-2020.md deleted file mode 100644 index e7dd2b30ba2..00000000000 --- a/site/content/posts/2020-07-10-Contours-landscape-jul-2020.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Contour’s landscape, July 2020 -excerpt: Contour is now part of the CNCF, and we're taking the opportunity to reevaluate our product philosophy. -author_name: Nick Young -author_avatar: /img/contributors/nick-young.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team', 'Nick Young', 'landscape'] -date: 2020-07-10 -slug: contours-landscape-jul-2020 ---- - -# Contour’s landscape, June 2020 - -Hi everyone, my name is Nick Young, and I’ve not-so-recently taken over from Dave Cheney as Tech Lead for the Contour maintainer team. Thanks very much to Dave for getting Contour started and for everything he’s done in his time with the team. His talent and insight are and will be missed. -![Bon Voyage Dave](https://frinkiac.com/gif/S08E03/1306838/1310375.gif?b64lines=Qm9uIFZveWFnZSBEYXZlIQ== "Bon Voyage Dave") - -As part of coming onboard as Tech Lead, I’ve been spending some time thinking about where Contour is, what it’s about, and where it’s going. Some of that effort has materialized already in things like the new [Philosophy document](https://projectcontour.io/resources/philosophy/), but I’ve also spent a bunch of time reviewing the project with a different lens than my previous maintainer-only one. In this post, I’d like to talk about some things I’ve found as part of that, what I think they mean for Contour’s mission, what we want to achieve, and what we will be doing differently in the future. - -I’m currently aiming for this to be a quarterly retrospective and mission update series. We’ll see how that goes. - -## Big News -Contour has been accepted into the CNCF at the “incubating” level! - -![Woohoo](https://frinkiac.com/gif/S04E17/1281462/1283464.gif?b64lines=V29vaG9v) - -This is a huge testament to the work of the Contour community, and it comes with a few benefits to our community: -- Being part of the CNCF means Contour is more closely associated (and aligned) with our two main dependencies, Envoy and Kubernetes. -- The CNCF offers our project vendor neutral governance to encourage more companies and contributors to join our community, contribute, and help us deliver on the vision of Contour. -- We believe the CNCF's networking community can play a big role in shaping the opinion for ingress controllers and Envoy control planes. -- The CNCF offers access to resources (like DevStats, assistance with user and developer outreach, and centralized functions) that help optimize our growth. - -This is also a good time for a look back at what we, the Contour project, have done, and where we are going. - - -## The Past and Present -### The Good - -Contour is, by most measures I can think of, a reasonably successful open source project. We have good velocity, we’ve released a stable v1.0, the project is being used in production, and we have a healthy stream of incoming feature requests from users. - -When we started, we initially created a custom resource, IngressRoute, which introduced the idea of delegating a URL path, enabling Contour users to split Ingress configuration between teams without risking people inadvertently clobbering each other’s config. This was an improvement to the default Ingress behavior, which had quite a few examples of this creating outages for users. - -When we realized that the delegation model was not capable of managing more dimensions than just path, we rebuilt the model into inclusion inside the new HTTPProxy resource, which, as of Contour 1.0, has been marked as GA by being moved to `v1`. The reason we moved to inclusion was to allow the use of other factors than just the URL path to be used for segmenting the URL space - you can now combine path prefix matching with header matching to make routing decisions in HTTPProxy. - -Since we are using a similar contract as the majority of the Kubernetes ecosystem, moving to v1 means that we will support the currently existing fields, and only make additive changes to this object from now on. If substantial changes are required, we’ll start that process with a `v2alpha1` version, although this is unlikely for other reasons I’ll go into in a bit. We’ve also removed IngressRoute in favor of this new resource, in order to concentrate our efforts on doing one thing well. - -Over time, we’ve also built and maintained a consistent project direction around simplicity and abstracting Envoy pieces away, so that you can use Contour without needing to know a lot about Envoy. This has helped new Contour users get started, but has come at the expense of configurability. - -We’ve made great strides as well in increasing the operability and reliability of Contour and Envoy working together. There have been a great deal of optimizations on how Contour sends updates to Envoy that have helped some large installations with high config churn drop their Envoy memory usage dramatically. We’ve also added observability tools to enable more and better metrics, dashboards, and logging. - -### The Bad - -Deprecating IngressRoute made life hard for the people who were using it. We do provide a tool, ([ir2proxy](https://github.com/projectcontour/ir2proxy)), to help with migrating to HTTPProxy, but the substantial model changes between IngressRoute and HTTPProxy means that we can’t have a fully automated solution, sadly. We won’t be changing the name again without an extremely good reason. In addition, we are confident that we should be able to change HTTPProxy additively to add all the features we can think of right now. So you should use HTTPProxy knowing that Contour will support it for the foreseeable future. - -We’ve still got a long way to go with operability. Contour’s current position on command-line arguments and the configuration file can be hard to understand. We will be moving focus to using the configuration file as the first place to configure the Contour service, rather than command-line flags, as we have more options around versioning configuration files than we do for command-line flags. - -Lastly, while our stance on simplicity has helped Contour work with a small team, and deliver some well-designed features, it’s meant that we’ve moved too slowly in building out new features and in exposing some Envoy functionality that is actually quite necessary in any proxy. - -In understanding what we were building with Contour, we overlooked the extent to which proxies are used as the place to tweak behaviors when you don’t control one end or the other. A great example of this is timeouts, as documented in [contour#2225](https://github.com/projectcontour/contour/issues/2225) and others. In particular, the addition of requestTimeout to HTTPProxy was a user-requested change, but in serving the consumers of HTTPProxy (in our current persona set, the Application Developer), we’ve inadvertently made a problem for the Contour deployment owner (currently the Cluster Administrator), since it’s possible for Application Developers to set the timeout to ‘unlimited’, even when the Cluster Admin may not want to allow that. - -We’ve had a similar problem in the past with the `permitInsecure` option for HTTPProxy, and have a `--disable-permit-insecure` flag to stop that flag working, but this doesn’t seem like the right thing for a more general solution. - -### The Ugly - -Talking to users of Contour, we’ve found that a number of teams have forked Contour and maintain their own patchsets so that they can run it in production. This says to me that we’ve missed something about their use cases, since running a fork is not an insignificant engineering investment, and if that’s considered a better use of engineering resources, then we need to reevaluate how easy it is to bring changes upstream, how we work with people to bring their changes, and what sort of changes we’ll accept. The good side of people forking Contour is that the software is obviously useful to them, and the features that people forked Contour for are a good indicator of just how important those features are for them. - -If you’re in the “We forked Contour” camp, or even if you haven’t, we’d love to hear from you. Please come to our [community meetings](https://projectcontour.io/community/), engage with us on [Slack](https://kubernetes.slack.com/messages/contour), or create issues to bring things to our attention. - -## The Future - -So, while Contour has done a few things really well, there’s also plenty of room for improvement. - -Before we get into what we want to do about improving Contour and our community, I’d like to talk a little bit about supportability. - -Before I was an open-source maintainer, I spent a long time as a sysadmin (as we used to be called), consuming tools like Contour. -So I understand that, sometimes, you just want a little bit of configurability to help you solve the problem you have, or to help you determine what’s causing it. -And that’s exactly what open source is for, so you can request (or make) the changes you need. -But, as maintainers of a project that we need to be able to maintain indefinitely, it’s also on us to make sure that each new thing we add is maintainable and supportable. - -We don't want features in Contour that are difficult to use correctly. To say this another way, if Contour takes configuration, we (the maintainers) should be able to tell you what Contour has done with it, and be able to help you help yourself if a feature doesn't work. - -More concretely, we've found that often, the *code changes* required to enable a feature are much less work than the *design changes* required to make the feature work in a way that makes sense for the future of Contour. - -The thing to remember is that when we’re being cautious, it’s because we want this project to be around to help for a long time. - -With that said, here are some things the Contour team is going to do to try and improve. - -### Building greater configurability - -In order to recognize that a segment of our users really need more configurability, we are going to allow more configuration of a greater set of settings. In the past we’ve tried to set reasonable defaults, and add configurable settings as a last resort. - -We’re going to be building more configurability, and pushing that configurability towards Contour’s configuration file with the aim of exposing whatever complexity we need in there for Contour-level configuration (as opposed to individual-resource level configuration). We’ll be starting with timeouts, putting configuration of the timeouts requested in [contour#2225](https://github.com/projectcontour/contour/issues/2225) into the config file, with some thought put into both how to configure upper and/or lower bounds for those timeouts if necessary, and how to name the timeouts to make sense for people who only know Contour, not Envoy. - -Over time, we’ll try to limit the number of command line flags to Contour, with the aim of eventually paring Contour down to just the flags useful for fast local development (such as `--insecure` to not require TLS certs for xDS serving, or `--debug` to enable debug logging). - -The corollary to accepting greater configurability is that, whatever we do, we need to support. So, the requirement for these timeout settings will be better documentation of the configuration file, and documentation of where in a request chain the timeouts apply. More generally, I’ll be asking that designs that add open-ended configuration include documentation about why the default value was chosen, and what are reasonable values for at least some use cases. - -Other features similar to this include the addition of CORS support to HTTPProxy, and similar tweakables. - -### Exposing more Envoy configuration -We’ve had a few requests for exposing more Envoy-specific configuration settings over Contour’s lifetime, and historically, we’ve been reluctant to break Contour’s abstraction in any substantial way, preferring to expose an abstracted version rather than the Envoy config directly. The exception to this is the bootstrap configuration - we currently supply `contour bootstrap` as a way to automatically generate this config, but it’s always been intended that Contour users could generate their own bootstrap configuration and add additional features if they wish. We’ve not done a great job of communicating this ability in the past. - -All of this is because Envoy is a fast-moving project that often changes both the implementation of features, or directly removes them. I believe that this problem will only be exacerbated with the rapid rate of change for the xDS APIs, so I’d prefer not to completely give up on abstracting things. - -However, it’s increasingly clear that we’re poorly serving those users of Contour who do understand Envoy, so I’m open to talking more about where we draw the line here. For example, we have some requests for us to allow passing Lua filters to Envoy. I don’t think that this is a feature we can easily support in Contour - there’s no way that we could test anything other than “is a basic Lua filter sent to Envoy?”, and we’re not a Lua product, so we can’t really help too much with troubleshooting the Lua filter itself - but if we could find a way to make exactly what we do support clear, I think we could consider it. - -Another, more implementable example is configuring tracing, which requires a global Envoy config, and per-route config, but also comes under the next section, as we’re configuring Envoy to talk to a third service. - -### Configuring Envoy with third-party services -Another closely related set of requests are those for functionality that requires configuring Envoy to talk to another service, either to retrieve information from it, or send to it. Examples here are external authentication, rate limiting, tracing, and Envoy’s ALS logging. - -While each of these needs to be considered on their own, one thing that I think is not negotiable is this: If Contour accepts the configuration for something, then it bears the responsibility for communicating whether that configuration is syntactically valid, accepted by Envoy, and doing what you asked for. - -For each of the examples, we need two things: information on what Contour has configured, and a way to surface that information back to the person who configured it. For some of the features, this is an application-level thing (like ALS and maybe tracing), and we may need to surface the information in Contour’s logs. For other features, this is resource-level config, and should be surfaced back on the resource that configured it (for example in the HTTPProxy status.) I’ve logged [contour#2325](https://github.com/projectcontour/contour/issues/2325) to cover an idea I had for one solution to this. - -In short, we would love to have more support for configuring Envoy with other services. Before we can do that, properly integrating any external service into the overall Contour picture requires foundational work to build the model for if and how Contour interacts with these services. This work has started (see [contour#2325](https://github.com/projectcontour/contour/issues/2325) and [contour#2495](https://github.com/projectcontour/contour/issues/2495) for some example issues), and we would love feedback about our approach and the implementation. Getting this foundational work right is tricky and may take some time, but once we have it done, we should be able to get the actual features out much more easily in the future. - -### Service-APIs and the future of Ingress -As an Ingress controller, we on the Contour team have been watching the upstream work on Ingress v1 and contributing to the [Service-APIs subproject of Kubernetes SIG-Network](https://kubernetes-sigs.github.io/service-apis) (which started out of Ingress V2 work, and has a similar forward looking design to HTTPProxy). Contour is committed to migrating Ingress support to Ingress v1 as soon as support windows allow ([contour#2139](https://github.com/projectcontour/contour/issues/2139)), and are actively contributing to the Service APIs subproject, with the aim of bringing Contour support for the new Service APIs objects as soon as they have enough behavior defined to be implementable. - - -## We want your feedback -Thanks for reading! We’d love to hear from you about these changes to Contour’s direction. Please come to our [community meeting](https://projectcontour.io/community/), join our [Slack channel](https://kubernetes.slack.com/messages/contour), and check out [our roadmap](https://github.com/projectcontour/community/blob/main/ROADMAP.md). diff --git a/site/content/posts/2020-10-07-contour_v190.md b/site/content/posts/2020-10-07-contour_v190.md deleted file mode 100644 index 44f15f9725e..00000000000 --- a/site/content/posts/2020-10-07-contour_v190.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Announcing Contour v1.9.0 -image: /img/posts/contourauth.png -excerpt: This blog post covers External Authorization and Cross-Origin Resource Sharing (CORS) Support in Contour v1.9.0. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team'] -date: 2020-10-07 -slug: contour_v190 ---- - -Contour continues to add new features to help you better manage ingress operations in a cluster. Our latest feature release, Contour 1.9.0, now includes support for external authorization allowing requests to be validated against an authorization server. Contour now also supports presenting a client certificate for TLS for validation to backend services as well as moves to v1 Custom Resource Definitions (CRDs). - -## External Authorization Support -Incoming requests to your ingress resources can now be authorized by utilizing Contour’s new external authorization support. Contour now enables the external authorization network filter in Envoy which calls an external authorization service to check if the incoming request is authorized or not. If the request is deemed unauthorized by the network filter then the connection will be closed. - -Support for this new feature relies on a new Custom Resource Definition (CRD) named ExtensionService. This new API describes how Envoy should connect to the external authorization server. - -![img](/img/posts/contourauth.png) - -### Sequence of Events for External Auth: -1. Deploy an External Authorization Service to your cluster: This service talks to your Authorization Provider and determines if the request should be authorized or not. -2. Create an `ExtensionService` CRD: This CRD allows the External Authorization Service created in the previous step to be available so that Contour can configure Envoy with that gRPC endpoint. -3. Create HTTPProxy resource: The VirtualHost in the ingress object references the ExternalService CRD linking that virtual host to the authorization service. -4. On every client request, Envoy sends an authorization check to the External Auth Service to determine authorization. - -## Demo -Here's a quick video demonstration walking through the setup and configuration of External Authorization with Contour. - -{{< youtube wm_eWO4mZYs >}} - -If you'd like to follow along with the demo in your own environment, here are the files used: -``` -https://projectcontour.io/examples/authdemo/01-prereq.yaml -https://projectcontour.io/examples/authdemo/02-auth-deployment.yaml -https://projectcontour.io/examples/authdemo/02-certsjob.yaml -https://projectcontour.io/examples/authdemo/03-secret.yaml -https://projectcontour.io/examples/authdemo/04-extensionservice.yaml -https://projectcontour.io/examples/authdemo/04-samplapp.yaml -https://projectcontour.io/examples/authdemo/05-proxy.yaml -https://projectcontour.io/examples/authdemo/06-proxy-auth.yaml -``` - -## Cross-Origin Resource Sharing (CORS) Support -Contour’s HTTPProxy API now supports specifying a [CORS policy](https://projectcontour.io/docs/v1.9.0/httpproxy/#cors-policy), which configures Envoy’s [CORS filter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/cors_filter) to allow web applications to request resources from different origins. - -CORS uses additional HTTP headers to tell browsers to give a web application running at one origin access to selected resources from a different origin (domain, protocol, or port) from its own. - -In this example, cross-domain requests will be allowed for any domain (note the * value): - -```yaml -apiVersion: projectcontour.io/v1 -kind: HTTPProxy -spec: - virtualhost: - fqdn: local.projectcontour.io - corsPolicy: - allowCredentials: true - allowOrigin: - - "*" # allows any origin - allowMethods: - - GET - - POST - - OPTIONS - allowHeaders: - - authorization - - cache-control - exposeHeaders: - - Content-Length - - Content-Range - maxAge: "10m" # preflight requests can be cached for 10 minutes. - routes: - - conditions: - - prefix: / - services: - - name: s1 - port: 80 -``` - -Thanks to @aberasarte and @glerchundi for driving the design and implementation of this new feature! - -## Backend TLS Client Authentication -Contour now supports optionally specifying a Kubernetes secret that Envoy should present to upstream clusters as a client certificate for TLS, so the upstream services can validate that the connection is coming from Envoy. - -Thanks to @tsaarni for leading design and implementation of this feature! - -## v1 Custom Resource Definitions -Contour now generates v1 custom resource definitions (CRDs) as part of its example YAML. -This enables Contour to take full advantage of the v1 API’s capabilities around validation, defaulting, API documentation via `kubectl explain`, and more. -CRDs became [generally available in Kubernetes 1.16](https://kubernetes.io/blog/2019/09/18/kubernetes-1-16-release-announcement/#custom-resources-reach-general-availability) over a year ago. - -This change bumps Contour’s minimum supported Kubernetes version to 1.16. - -## Community Thanks! -We’re immensely grateful for all the community contributions that help make Contour even better! For version 1.9, special thanks go out to the following contributors: -- [@aberasarte](https://github.com/aberasarte) -- [@bgagnon](https://github.com/bgagnon) -- [@glerchundi](https://github.com/glerchundi) -- [@mattmoor](https://github.com/mattmoor) -- [@ShaileshSurya](https://github.com/ShaileshSurya) -- [@tong101](https://github.com/tong101) -- [@tsaarni](https://github.com/tsaarni) -- [@zianke](https://github.com/zianke) diff --git a/site/content/posts/2020-11-06-contour_v1100.md b/site/content/posts/2020-11-06-contour_v1100.md deleted file mode 100644 index 8f16ac7263c..00000000000 --- a/site/content/posts/2020-11-06-contour_v1100.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Announcing Contour v1.10.0 -image: /img/posts/contour_xdsv2v3.png -excerpt: This blog post covers xDS Resource Server conversion from v2 to v3 in Contour v1.10.0. -author_name: Steve Sloka -author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Contour Team'] -date: 2020-11-06 -slug: contour_v1100 ---- - -Contour continues to add new features to help you better manage ingress operations in a cluster. -Our latest feature release, Contour 1.10.0, now includes support for Envoy xDS v3 as support for the current v2 version will be deprecated in early 2021. -Contour also adds support for multi-arch images allowing for deployment on multiple platforms as well as extending support for custom JSON logging fields. - -## Envoy xDS v3 Support -Contour is the xDS controller for Envoy providing it with dynamic updates of Listeners, Routes, Clusters, Endpoints and other information over a gRPC connection. -Those objects are defined in the xDS API and are versioned. Currently, Contour supports the v2 xDS API. -The v2 version has been deprecated and has not accepted new features after the end of Q1 2020. Additionally, the v2 API will be removed from Envoy in Q1 of 2021. - -One key component in Envoy which relates to which xDS version is used in the bootstrap configuration file. -This file, provided by an initContainer to Envoy, describes both the transport and resource API versions to use when communicating with Contour. -In Contour v1.9.0 and earlier versions, this bootstrap configuration doesn't’t specify a version, which then defaults to v2. - -New in v1.10.0, there’s now an `--xds-resource-version` flag that can be configured on the `contour bootstrap` command to change the bootstrap xDS resource & transport versions in the configuration file to v3, however, the default will still be v2 for the v1.10.0 release. - -This default means that users have a way to upgrade their instance of Envoy from v2 to v3 in place without any connection loss since Contour will serve both the v2 & v3 versions at the same time. - -![image](/img/posts/contour_xdsv2v3.png) - -It’s important, however, to note that **this is the only version which will support both resource versions**. -Looking forward to Contour v1.11.0, Contour will remove the v2 support entirely and the bootstrap configuration will use v3 by default. -Users needing to perform an in-place upgrade should leverage Contour v1.10.0 as a stepping stone to the new xDS v3 resource version. - -For more information, please visit the [Upgrade Guide][3] as well as the [Migrating from v2-->v3 Guide][2]. - -## Custom Logging - -As more users adopt Contour as their Ingress Controller, we find that they need more information to solve their needs. One such request is the ability to support custom JSON fields in the Envoy access log. - -Contour v1.10.0 now adds support for users to customize their access logs. You can read about this feature in more detail as well as how to configure it in the [structured JSON logging guide][4]. - -Thanks to [@mike1808](https://github.com/mike1808), [@KauzClay](https://github.com/KauzClay), and [@XanderStrike](https://github.com/XanderStrike) for designing and implementing this feature! - -## Multi-arch Images - -Similar to the new access logging features, users also have requested more architectures to run Contour. -Envoy now supports ARM based architectures starting in Envoy v1.16.0 and Contour follows suit by offering multi-arch builds allowing Contour & Envoy to run on non amd64 based systems. - -![image](/img/posts/multiarch.png) - -## Community Thanks! -We’re immensely grateful for all the community contributions that help make Contour even better! For version 1.10, special thanks go out to the following contributors: -- [@narahari92](https://github.com/narahari92) -- [@yoitsro](https://github.com/yoitsro) -- [@mike1808](https://github.com/mike1808) -- [@astrieanna](https://github.com/astrianna) -- [@kauana](https://github.com/kauana) -- [@Glyphack](https://github.com/Glyphack) -- [@danehans](https://github.com/danehans) -- [@KauzClay](https://github.com/KauzClay) -- [@XanderStrike](https://github.com/XanderStrike) - - -[2]: {{< relref "guides/xds-migration.md" >}} -[3]: {{< relref "resources/upgrading.md" >}} -[4]: {{< relref "guides/structured-logs.md" >}} diff --git a/site/content/posts/2020-12-18-contour_v1110.md b/site/content/posts/2020-12-18-contour_v1110.md deleted file mode 100644 index 03c6526f312..00000000000 --- a/site/content/posts/2020-12-18-contour_v1110.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Announcing Contour v1.11.0 -excerpt: This blog post covers the new Contour Operator released in v1.11.0. -author_name: Steve Sloka & Daneyon Hansen -# author_avatar: /img/contributors/steve-sloka.png -categories: [kubernetes] -# Tag should match author to drive author pages -tags: ['Steve Sloka & Daneyon Hansen'] -date: 2020-12-18 -slug: contour_v1110 ---- - -Contour continues to add new features to help you better manage ingress operations in a cluster. -Our latest feature release, Contour 1.11.0, now includes support for a new operator aimed at managing the lifecycle of Contour and its corresponding Envoy instances. - -## Contour Operator - -__FEATURE STATE:__ Contour v1.11.0 [alpha](https://projectcontour.io/resources/deprecation-policy/) - -[Contour Operator](https://github.com/projectcontour/contour-operator/blob/main/README.md) provides a method for packaging, -deploying, and managing Contour. The operator extends the functionality of the Kubernetes API to create, configure, and -manage instances of Contour on behalf of users. -It builds upon the basic Kubernetes resource and controller concepts, but includes domain-specific knowledge to automate the entire lifecycle of Contour. - -In Kubernetes, controllers of the control-plane implement control loops that repeatedly compare the desired state of the cluster to its actual state. -If the cluster's actual state doesn’t match the desired state, then the controller takes action to fix the problem. -Contour Operator is a custom Kubernetes controller that uses the `Contour` custom resource (CR) to manage Contour and its dependent components, i.e. the Envoy DaemonSet. -The `contours.operator.projectcontour.io` Custom Resource Definition (CRD) defines the `Contour` CR. A `Contour` is handled by the Kubernetes API just like built-in objects, including interaction via kubectl and inclusion in role-based access control (RBAC) policies. -The following example runs an instance of Contour in namespace `projectcontour` with 2 Deployment replicas: -``` -cat < {{ end }} diff --git a/site/themes/contour/layouts/partials/footer.html b/site/themes/contour/layouts/partials/footer.html index 39bafafba3a..874c442e283 100644 --- a/site/themes/contour/layouts/partials/footer.html +++ b/site/themes/contour/layouts/partials/footer.html @@ -4,7 +4,6 @@ diff --git a/test/conformance/gatewayapi/gateway_conformance_test.go b/test/conformance/gatewayapi/gateway_conformance_test.go index 361bab69311..48469bac78d 100644 --- a/test/conformance/gatewayapi/gateway_conformance_test.go +++ b/test/conformance/gatewayapi/gateway_conformance_test.go @@ -26,6 +26,7 @@ import ( "github.com/distribution/reference" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + apiextensions_v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/client" @@ -33,12 +34,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayapi_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - conformance_v1alpha1 "sigs.k8s.io/gateway-api/conformance/apis/v1alpha1" + "sigs.k8s.io/gateway-api/conformance" + conformance_v1 "sigs.k8s.io/gateway-api/conformance/apis/v1" "sigs.k8s.io/gateway-api/conformance/tests" "sigs.k8s.io/gateway-api/conformance/utils/flags" "sigs.k8s.io/gateway-api/conformance/utils/suite" - "sigs.k8s.io/yaml" + "sigs.k8s.io/gateway-api/pkg/features" ) func TestGatewayConformance(t *testing.T) { @@ -53,11 +56,13 @@ func TestGatewayConformance(t *testing.T) { clientset, err := kubernetes.NewForConfig(cfg) require.NoError(t, err) - require.NoError(t, gatewayapi_v1alpha2.AddToScheme(client.Scheme())) - require.NoError(t, gatewayapi_v1beta1.AddToScheme(client.Scheme())) - require.NoError(t, gatewayapi_v1.AddToScheme(client.Scheme())) + require.NoError(t, gatewayapi_v1alpha2.Install(client.Scheme())) + require.NoError(t, gatewayapi_v1alpha3.Install(client.Scheme())) + require.NoError(t, gatewayapi_v1beta1.Install(client.Scheme())) + require.NoError(t, gatewayapi_v1.Install(client.Scheme())) + require.NoError(t, apiextensions_v1.AddToScheme(client.Scheme())) - cSuiteOptions := suite.Options{ + options := suite.ConformanceOptions{ Client: client, // This clientset is needed in addition to the client only because // controller-runtime client doesn't support non CRUD sub-resources yet (https://github.com/kubernetes-sigs/controller-runtime/issues/452). @@ -74,26 +79,38 @@ func TestGatewayConformance(t *testing.T) { // See: https://github.com/envoyproxy/envoy/issues/17318 tests.HTTPRouteRedirectPortAndScheme.ShortName, - // Not implemented yet since it's functionally equivalent - // to Timeouts.Request, to be enabled once Gateway API - // supports retries. - // See: https://github.com/projectcontour/contour/issues/6000 - tests.HTTPRouteTimeoutBackendRequest.ShortName, - // Contour supports the positive-case functionality, // but there are some negative cases that aren't fully // implemented plus complications with the test setup itself. // See: https://github.com/projectcontour/contour/issues/5922 tests.GatewayStaticAddresses.ShortName, + + // Skip this test as it uses a Gateway with a name that is too long, + // adding the name in a label value prevents resources to be + // created. + // See: https://github.com/kubernetes-sigs/gateway-api/issues/2592 + tests.HTTPRouteInvalidParentRefSectionNameNotMatchingPort.ShortName, + + // This test currently fails since we do not program any filter chain + // for a Gateway Listener that has no attached routes. The test + // includes a TLS Listener with no hostname specified and the test + // sends a request for an unknown (to Contour/Envoy) host which fails + // instead of returning a 404. + tests.HTTPRouteHTTPSListener.ShortName, }, ExemptFeatures: sets.New( - suite.SupportMesh, + features.SupportMesh, + features.SupportUDPRoute, ), } if os.Getenv("GENERATE_GATEWAY_CONFORMANCE_REPORT") == "true" { reportDir, ok := os.LookupEnv("GATEWAY_CONFORMANCE_REPORT_OUTDIR") require.True(t, ok, "GATEWAY_CONFORMANCE_REPORT_OUTDIR not set") + require.NoError(t, os.MkdirAll(reportDir, 0o755)) + outFile := filepath.Join(reportDir, fmt.Sprintf("projectcontour-contour-%d.yaml", time.Now().UnixNano())) + options.ReportOutputPath = outFile + image, ok := os.LookupEnv("CONTOUR_E2E_IMAGE") require.True(t, ok, "CONTOUR_E2E_IMAGE not set") @@ -103,49 +120,26 @@ func TestGatewayConformance(t *testing.T) { require.True(t, ok) require.NotEmpty(t, taggedImage) - // Workaround since the experimental suite doesn't properly - // exclude tests we don't want to run using the ExemptFeatures - // field. - cSuiteOptions.EnableAllSupportedFeatures = false - cSuiteOptions.SupportedFeatures = suite.AllFeatures.Delete(suite.MeshCoreFeatures.UnsortedList()...) - - cSuite, err := suite.NewExperimentalConformanceTestSuite(suite.ExperimentalConformanceOptions{ - Options: cSuiteOptions, - Implementation: conformance_v1alpha1.Implementation{ - Organization: "projectcontour", - Project: "contour", - URL: "https://projectcontour.io/", - Version: taggedImage.Tag(), - Contact: []string{"@projectcontour/maintainers"}, - }, - ConformanceProfiles: sets.New[suite.ConformanceProfileName]( - suite.HTTPConformanceProfileName, - suite.TLSConformanceProfileName, - ), - }) - require.NoError(t, err) - - cSuite.Setup(t) - require.NoError(t, cSuite.Run(t, tests.ConformanceTests)) - - report, err := cSuite.Report() - require.NoError(t, err, "failed generating conformance report") - - if gwAPIVersion := os.Getenv("GATEWAY_API_VERSION"); gwAPIVersion != "" { - report.GatewayAPIVersion = gwAPIVersion + options.Implementation = conformance_v1.Implementation{ + Organization: "projectcontour", + Project: "contour", + URL: "https://projectcontour.io/", + Version: taggedImage.Tag(), + Contact: []string{"@projectcontour/maintainers"}, } - rawReport, err := yaml.Marshal(report) - require.NoError(t, err) - t.Logf("Conformance report:\n%s", string(rawReport)) + options.ConformanceProfiles = sets.New[suite.ConformanceProfileName]( + suite.GatewayHTTPConformanceProfileName, + suite.GatewayTLSConformanceProfileName, + suite.GatewayGRPCConformanceProfileName, + ) - require.NoError(t, os.MkdirAll(reportDir, 0o755)) - outFile := filepath.Join(reportDir, fmt.Sprintf("projectcontour-contour-%d.yaml", time.Now().UnixNano())) - require.NoError(t, os.WriteFile(outFile, rawReport, 0o600)) - t.Logf("Report written to: %s", outFile) - } else { - cSuite := suite.New(cSuiteOptions) - cSuite.Setup(t) - cSuite.Run(t, tests.ConformanceTests) + // Workaround since the experimental suite doesn't properly + // exclude tests we don't want to run using the ExemptFeatures + // field. + options.EnableAllSupportedFeatures = false + options.SupportedFeatures = features.AllFeatures.Delete(append(features.MeshCoreFeatures.UnsortedList(), features.UDPRouteFeatures.UnsortedList()...)...) } + + conformance.RunConformanceWithOptions(t, options) } diff --git a/test/e2e/certs.go b/test/e2e/certs.go index 028575c9a31..a4d413a6b02 100644 --- a/test/e2e/certs.go +++ b/test/e2e/certs.go @@ -29,7 +29,6 @@ import ( "k8s.io/apimachinery/pkg/api/errors" api_errors "k8s.io/apimachinery/pkg/api/errors" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -84,26 +83,8 @@ func (c *Certs) CreateSelfSignedCert(ns, name, secretName, dnsName string) func( // CreateCertAndWaitFor creates the provided Certificate in the Kubernetes API // and then waits for the specified condition to be true. -func (c *Certs) CreateCertAndWaitFor(cert *certmanagerv1.Certificate, condition func(cert *certmanagerv1.Certificate) bool) (*certmanagerv1.Certificate, bool) { - require.NoError(c.t, c.client.Create(context.TODO(), cert)) - - res := &certmanagerv1.Certificate{} - - if err := wait.PollUntilContextTimeout(context.Background(), c.retryInterval, c.retryTimeout, true, func(ctx context.Context) (bool, error) { - if err := c.client.Get(ctx, client.ObjectKeyFromObject(cert), res); err != nil { - // if there was an error, we want to keep - // retrying, so just return false, not an - // error. - return false, nil - } - - return condition(res), nil - }); err != nil { - // return the last response for logging/debugging purposes - return res, false - } - - return res, true +func (c *Certs) CreateCertAndWaitFor(cert *certmanagerv1.Certificate, condition func(cert *certmanagerv1.Certificate) bool) bool { + return createAndWaitFor(c.t, c.client, cert, condition, c.retryInterval, c.retryTimeout) } // GetTLSCertificate returns a tls.Certificate containing the data in the specified diff --git a/test/e2e/deployment.go b/test/e2e/deployment.go index 6383c78e8f9..6fc95eec9a5 100644 --- a/test/e2e/deployment.go +++ b/test/e2e/deployment.go @@ -561,15 +561,6 @@ func (d *Deployment) mutatePodTemplate(pts core_v1.PodTemplateSpec) core_v1.PodT // Remove shutdown-manager container. pts.Spec.Containers = pts.Spec.Containers[1:] - // Expose the metrics & admin interfaces via host port to test from outside the kind cluster. - pts.Spec.Containers[0].Ports = append(pts.Spec.Containers[0].Ports, - core_v1.ContainerPort{ - Name: "metrics", - ContainerPort: 8002, - HostPort: 8002, - Protocol: core_v1.ProtocolTCP, - }) - return pts } diff --git a/test/e2e/fixtures.go b/test/e2e/fixtures.go index bb8e9bfc0ea..4cc20831bf6 100644 --- a/test/e2e/fixtures.go +++ b/test/e2e/fixtures.go @@ -651,9 +651,9 @@ func XDSServerTypeFromEnv() contour_v1alpha1.XDSServerType { func UseFeatureFlagsFromEnv() []string { flags := make([]string, 0) - _, found := os.LookupEnv("CONTOUR_E2E_USE_ENDPOINT_SLICES") + _, found := os.LookupEnv("CONTOUR_E2E_USE_ENDPOINTS") if found { - flags = append(flags, "useEndpointSlices") + flags = append(flags, "useEndpointSlices=false") } return flags } diff --git a/test/e2e/framework.go b/test/e2e/framework.go index 8a7298c3e2b..b41bf59b02b 100644 --- a/test/e2e/framework.go +++ b/test/e2e/framework.go @@ -48,6 +48,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" @@ -104,8 +105,9 @@ func NewFramework(inClusterTestSuite bool) *Framework { require.NoError(t, kubescheme.AddToScheme(scheme)) require.NoError(t, contour_v1.AddToScheme(scheme)) require.NoError(t, contour_v1alpha1.AddToScheme(scheme)) - require.NoError(t, gatewayapi_v1alpha2.AddToScheme(scheme)) - require.NoError(t, gatewayapi_v1.AddToScheme(scheme)) + require.NoError(t, gatewayapi_v1alpha2.Install(scheme)) + require.NoError(t, gatewayapi_v1alpha3.Install(scheme)) + require.NoError(t, gatewayapi_v1.Install(scheme)) require.NoError(t, certmanagerv1.AddToScheme(scheme)) require.NoError(t, apiextensions_v1.AddToScheme(scheme)) @@ -311,7 +313,7 @@ func (f *Framework) CreateHTTPProxy(proxy *contour_v1.HTTPProxy) error { return f.Client.Create(context.TODO(), proxy) } -func createAndWaitFor[T client.Object](t require.TestingT, client client.Client, obj T, condition func(T) bool, interval, timeout time.Duration) (T, bool) { +func createAndWaitFor[T client.Object](t require.TestingT, client client.Client, obj T, condition func(T) bool, interval, timeout time.Duration) bool { require.NoError(t, client.Create(context.Background(), obj)) key := types.NamespacedName{ @@ -329,11 +331,10 @@ func createAndWaitFor[T client.Object](t require.TestingT, client client.Client, return condition(obj), nil }); err != nil { - // return the last response for logging/debugging purposes - return obj, false + return false } - return obj, true + return true } func updateAndWaitFor[T client.Object](t require.TestingT, cli client.Client, obj T, mutate func(T), condition func(T) bool, interval, timeout time.Duration) (T, bool) { @@ -366,31 +367,37 @@ func updateAndWaitFor[T client.Object](t require.TestingT, cli client.Client, ob // CreateHTTPProxyAndWaitFor creates the provided HTTPProxy in the Kubernetes API // and then waits for the specified condition to be true. -func (f *Framework) CreateHTTPProxyAndWaitFor(proxy *contour_v1.HTTPProxy, condition func(*contour_v1.HTTPProxy) bool) (*contour_v1.HTTPProxy, bool) { +func (f *Framework) CreateHTTPProxyAndWaitFor(proxy *contour_v1.HTTPProxy, condition func(*contour_v1.HTTPProxy) bool) bool { return createAndWaitFor(f.t, f.Client, proxy, condition, f.RetryInterval, f.RetryTimeout) } // CreateHTTPRouteAndWaitFor creates the provided HTTPRoute in the Kubernetes API // and then waits for the specified condition to be true. -func (f *Framework) CreateHTTPRouteAndWaitFor(route *gatewayapi_v1.HTTPRoute, condition func(*gatewayapi_v1.HTTPRoute) bool) (*gatewayapi_v1.HTTPRoute, bool) { +func (f *Framework) CreateHTTPRouteAndWaitFor(route *gatewayapi_v1.HTTPRoute, condition func(*gatewayapi_v1.HTTPRoute) bool) bool { return createAndWaitFor(f.t, f.Client, route, condition, f.RetryInterval, f.RetryTimeout) } // CreateTLSRouteAndWaitFor creates the provided TLSRoute in the Kubernetes API // and then waits for the specified condition to be true. -func (f *Framework) CreateTLSRouteAndWaitFor(route *gatewayapi_v1alpha2.TLSRoute, condition func(*gatewayapi_v1alpha2.TLSRoute) bool) (*gatewayapi_v1alpha2.TLSRoute, bool) { +func (f *Framework) CreateTLSRouteAndWaitFor(route *gatewayapi_v1alpha2.TLSRoute, condition func(*gatewayapi_v1alpha2.TLSRoute) bool) bool { return createAndWaitFor(f.t, f.Client, route, condition, f.RetryInterval, f.RetryTimeout) } // CreateTCPRouteAndWaitFor creates the provided TCPRoute in the Kubernetes API // and then waits for the specified condition to be true. -func (f *Framework) CreateTCPRouteAndWaitFor(route *gatewayapi_v1alpha2.TCPRoute, condition func(*gatewayapi_v1alpha2.TCPRoute) bool) (*gatewayapi_v1alpha2.TCPRoute, bool) { +func (f *Framework) CreateTCPRouteAndWaitFor(route *gatewayapi_v1alpha2.TCPRoute, condition func(*gatewayapi_v1alpha2.TCPRoute) bool) bool { return createAndWaitFor(f.t, f.Client, route, condition, f.RetryInterval, f.RetryTimeout) } // CreateBackendTLSPolicy creates the provided BackendTLSPolicy in the Kubernetes API // and then waits for the specified condition to be true. -func (f *Framework) CreateBackendTLSPolicyAndWaitFor(route *gatewayapi_v1alpha2.BackendTLSPolicy, condition func(*gatewayapi_v1alpha2.BackendTLSPolicy) bool) (*gatewayapi_v1alpha2.BackendTLSPolicy, bool) { +func (f *Framework) CreateBackendTLSPolicyAndWaitFor(route *gatewayapi_v1alpha3.BackendTLSPolicy, condition func(*gatewayapi_v1alpha3.BackendTLSPolicy) bool) bool { + return createAndWaitFor(f.t, f.Client, route, condition, f.RetryInterval, f.RetryTimeout) +} + +// CreateGRPCRouteAndWaitFor creates the provided GRPCRoute in the Kubernetes API +// and then waits for the specified condition to be true. +func (f *Framework) CreateGRPCRouteAndWaitFor(route *gatewayapi_v1.GRPCRoute, condition func(*gatewayapi_v1.GRPCRoute) bool) bool { return createAndWaitFor(f.t, f.Client, route, condition, f.RetryInterval, f.RetryTimeout) } @@ -438,13 +445,13 @@ func (f *Framework) DeleteNamespace(name string, waitForDeletion bool) { // CreateGatewayAndWaitFor creates a gateway in the // Kubernetes API or fails the test if it encounters an error. -func (f *Framework) CreateGatewayAndWaitFor(gateway *gatewayapi_v1.Gateway, condition func(*gatewayapi_v1.Gateway) bool) (*gatewayapi_v1.Gateway, bool) { +func (f *Framework) CreateGatewayAndWaitFor(gateway *gatewayapi_v1.Gateway, condition func(*gatewayapi_v1.Gateway) bool) bool { return createAndWaitFor(f.t, f.Client, gateway, condition, f.RetryInterval, f.RetryTimeout) } // CreateGatewayClassAndWaitFor creates a GatewayClass in the // Kubernetes API or fails the test if it encounters an error. -func (f *Framework) CreateGatewayClassAndWaitFor(gatewayClass *gatewayapi_v1.GatewayClass, condition func(*gatewayapi_v1.GatewayClass) bool) (*gatewayapi_v1.GatewayClass, bool) { +func (f *Framework) CreateGatewayClassAndWaitFor(gatewayClass *gatewayapi_v1.GatewayClass, condition func(*gatewayapi_v1.GatewayClass) bool) bool { return createAndWaitFor(f.t, f.Client, gatewayClass, condition, f.RetryInterval, f.RetryTimeout) } diff --git a/test/e2e/gateway/backend_tls_policy_test.go b/test/e2e/gateway/backend_tls_policy_test.go index 40ea54f2cae..5e75fd0f7d2 100644 --- a/test/e2e/gateway/backend_tls_policy_test.go +++ b/test/e2e/gateway/backend_tls_policy_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" "github.com/projectcontour/contour/internal/gatewayapi" "github.com/projectcontour/contour/test/e2e" @@ -135,23 +136,25 @@ func testBackendTLSPolicy(namespace string, gateway types.NamespacedName) { }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) - backendTLSPolicy := &gatewayapi_v1alpha2.BackendTLSPolicy{ + backendTLSPolicy := &gatewayapi_v1alpha3.BackendTLSPolicy{ ObjectMeta: meta_v1.ObjectMeta{ Name: "echo-secure-backend-tls-policy", Namespace: namespace, }, - Spec: gatewayapi_v1alpha2.BackendTLSPolicySpec{ - TargetRef: gatewayapi_v1alpha2.PolicyTargetReferenceWithSectionName{ - PolicyTargetReference: gatewayapi_v1alpha2.PolicyTargetReference{ - Group: "", - Kind: "Service", - Name: "echo-secure", + Spec: gatewayapi_v1alpha3.BackendTLSPolicySpec{ + TargetRefs: []gatewayapi_v1alpha2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gatewayapi_v1alpha2.LocalPolicyTargetReference{ + Group: "", + Kind: "Service", + Name: "echo-secure", + }, }, }, - TLS: gatewayapi_v1alpha2.BackendTLSPolicyConfig{ - CACertRefs: []gatewayapi_v1.LocalObjectReference{ + Validation: gatewayapi_v1alpha3.BackendTLSPolicyValidation{ + CACertificateRefs: []gatewayapi_v1.LocalObjectReference{ { Group: "", Kind: "Secret", @@ -163,8 +166,7 @@ func testBackendTLSPolicy(namespace string, gateway types.NamespacedName) { }, } - _, ok := f.CreateBackendTLSPolicyAndWaitFor(backendTLSPolicy, e2e.BackendTLSPolicyAccepted) - assert.Truef(t, ok, "expected policy condition accepted on backend tls policy") + require.True(f.T(), f.CreateBackendTLSPolicyAndWaitFor(backendTLSPolicy, e2e.BackendTLSPolicyAccepted)) type responseTLSDetails struct { TLS struct { diff --git a/test/e2e/gateway/gateway_test.go b/test/e2e/gateway/gateway_test.go index c0287e53279..f5cfe470fbd 100644 --- a/test/e2e/gateway/gateway_test.go +++ b/test/e2e/gateway/gateway_test.go @@ -134,8 +134,8 @@ var _ = Describe("Gateway API", func() { // or become valid. gatewayClassCond := func(*gatewayapi_v1.GatewayClass) bool { return true } - f.CreateGatewayClassAndWaitFor(contourGatewayClass, gatewayClassCond) - f.CreateGatewayAndWaitFor(contourGateway, e2e.GatewayProgrammed) + require.True(f.T(), f.CreateGatewayClassAndWaitFor(contourGatewayClass, gatewayClassCond)) + require.True(f.T(), f.CreateGatewayAndWaitFor(contourGateway, e2e.GatewayProgrammed)) }) AfterEach(func() { @@ -181,6 +181,14 @@ var _ = Describe("Gateway API", func() { f.NamespacedTest("gateway-request-redirect-rule", testWithHTTPGateway(testRequestRedirectRule)) f.NamespacedTest("gateway-backend-tls-policy", testWithHTTPGateway(testBackendTLSPolicy)) + + f.NamespacedTest("gateway-httproute-conflict-match", testWithHTTPGateway(testHTTPRouteConflictMatch)) + + f.NamespacedTest("gateway-httproute-partially-conflict-match", testWithHTTPGateway(testHTTPRoutePartiallyConflictMatch)) + + f.NamespacedTest("gateway-grpcroute-conflict-match", testWithHTTPGateway(testGRPCRouteConflictMatch)) + + f.NamespacedTest("gateway-grpcroute-partially-conflict-match", testWithHTTPGateway(testGRPCRoutePartiallyConflictMatch)) }) Describe("Gateway with one HTTP listener and one HTTPS listener", func() { diff --git a/test/e2e/gateway/grpc_route_conflict_match_test.go b/test/e2e/gateway/grpc_route_conflict_match_test.go new file mode 100644 index 00000000000..96797d9b4ce --- /dev/null +++ b/test/e2e/gateway/grpc_route_conflict_match_test.go @@ -0,0 +1,95 @@ +// Copyright Project Contour Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build e2e + +package gateway + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/require" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" + + "github.com/projectcontour/contour/internal/gatewayapi" + "github.com/projectcontour/contour/test/e2e" +) + +func testGRPCRouteConflictMatch(namespace string, gateway types.NamespacedName) { + Specify("Creates two GRPCRoutes, second one has conflict match against the first one, report Accepted: false", func() { + cleanup := f.Fixtures.GRPC.Deploy(namespace, "grpc-echo") + + By("create grpcroute-1 first") + route1 := &gatewayapi_v1.GRPCRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "grpcroute-1", + }, + Spec: gatewayapi_v1.GRPCRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), + }, + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "foo.com.example.service", "Login"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("grpc-echo", 9000, 1), + }}, + }, + } + ok := f.CreateGRPCRouteAndWaitFor(route1, e2e.GRPCRouteAccepted) + require.True(f.T(), ok) + + By("create grpcroute-2 with conflicted matches") + route2 := &gatewayapi_v1.GRPCRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "grpcroute-2", + }, + Spec: gatewayapi_v1.GRPCRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.GRPCRouteRule{ + { + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), + }, + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "bar.com.example.service", "Login"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("grpc-echo", 9000, 1), + }, + }, + }, + } + ok = f.CreateGRPCRouteAndWaitFor(route2, e2e.GRPCRouteNotAcceptedDueToConflict) + require.True(f.T(), ok) + + cleanup() + }) +} diff --git a/test/e2e/gateway/grpc_route_partially_conflict_match_test.go b/test/e2e/gateway/grpc_route_partially_conflict_match_test.go new file mode 100644 index 00000000000..4ca211269b5 --- /dev/null +++ b/test/e2e/gateway/grpc_route_partially_conflict_match_test.go @@ -0,0 +1,95 @@ +// Copyright Project Contour Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build e2e + +package gateway + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/require" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" + + "github.com/projectcontour/contour/internal/gatewayapi" + "github.com/projectcontour/contour/test/e2e" +) + +func testGRPCRoutePartiallyConflictMatch(namespace string, gateway types.NamespacedName) { + Specify("Creates two GRPCRoutes, second one has partial conflict match against the first one, has partially match condition", func() { + cleanup := f.Fixtures.GRPC.Deploy(namespace, "grpc-echo") + + By("create grpcroute-1 first") + route1 := &gatewayapi_v1.GRPCRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "grpcroute-1", + }, + Spec: gatewayapi_v1.GRPCRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), + }, + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "foo.com.example.service", "Login"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("grpc-cho", 9000, 1), + }}, + }, + } + ok := f.CreateGRPCRouteAndWaitFor(route1, e2e.GRPCRouteAccepted) + require.True(f.T(), ok) + + By("create grpcroute-2 with only partially conflicted matches") + route2 := &gatewayapi_v1.GRPCRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "grpcroute-2", + }, + Spec: gatewayapi_v1.GRPCRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.GRPCRouteRule{{ + Matches: []gatewayapi_v1.GRPCRouteMatch{ + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "com.example.service", "Login"), + }, + { + Method: gatewayapi.GRPCMethodMatch(gatewayapi_v1.GRPCMethodMatchExact, "foo.com.example.service", "Login"), + }, + }, + BackendRefs: gatewayapi.GRPCRouteBackendRef("grpc-cho", 9000, 1), + }}, + }, + } + // Partially accepted + f.CreateGRPCRouteAndWaitFor(route2, func(*gatewayapi_v1.GRPCRoute) bool { + return e2e.GRPCRoutePartiallyInvalid(route2) && e2e.GRPCRouteAccepted(route2) + }) + + cleanup() + }) +} diff --git a/test/e2e/gateway/host_rewrite_test.go b/test/e2e/gateway/host_rewrite_test.go index 545c9e5c6a2..085ad145095 100644 --- a/test/e2e/gateway/host_rewrite_test.go +++ b/test/e2e/gateway/host_rewrite_test.go @@ -71,7 +71,7 @@ func testHostRewrite(namespace string, gateway types.NamespacedName) { }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: string(route.Spec.Hostnames[0]), diff --git a/test/e2e/gateway/http_route_conflict_match_test.go b/test/e2e/gateway/http_route_conflict_match_test.go new file mode 100644 index 00000000000..6ee831fb89a --- /dev/null +++ b/test/e2e/gateway/http_route_conflict_match_test.go @@ -0,0 +1,87 @@ +// Copyright Project Contour Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build e2e + +package gateway + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/require" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" + + "github.com/projectcontour/contour/internal/gatewayapi" + "github.com/projectcontour/contour/test/e2e" +) + +func testHTTPRouteConflictMatch(namespace string, gateway types.NamespacedName) { + Specify("Creates two http routes, second one has conflict match against the first one, report Accepted: false", func() { + By("create httproute-1 first") + route1 := &gatewayapi_v1.HTTPRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "httproute-1", + }, + Spec: gatewayapi_v1.HTTPRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.HTTPRouteRule{ + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + {QueryParams: gatewayapi.HTTPQueryParamMatches(map[string]string{"animal": "whale"})}, + }, + BackendRefs: gatewayapi.HTTPBackendRef("echo-1", 80, 1), + }, + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + {QueryParams: gatewayapi.HTTPQueryParamMatches(map[string]string{"animal": "dolphin"})}, + }, + BackendRefs: gatewayapi.HTTPBackendRef("echo-2", 80, 1), + }, + }, + }, + } + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route1, e2e.HTTPRouteAccepted)) + + By("create httproute-2 with conflicted matches") + route2 := &gatewayapi_v1.HTTPRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "httproute-2", + }, + Spec: gatewayapi_v1.HTTPRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.HTTPRouteRule{ + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + {QueryParams: gatewayapi.HTTPQueryParamMatches(map[string]string{"animal": "whale"})}, + }, + BackendRefs: gatewayapi.HTTPBackendRef("echo-1", 80, 1), + }, + }, + }, + } + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route2, e2e.HTTPRouteNotAcceptedDueToConflict)) + }) +} diff --git a/test/e2e/gateway/http_route_partially_conflict_match_test.go b/test/e2e/gateway/http_route_partially_conflict_match_test.go new file mode 100644 index 00000000000..238f7405c4b --- /dev/null +++ b/test/e2e/gateway/http_route_partially_conflict_match_test.go @@ -0,0 +1,96 @@ +// Copyright Project Contour Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build e2e + +package gateway + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/require" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" + + "github.com/projectcontour/contour/internal/gatewayapi" + "github.com/projectcontour/contour/test/e2e" +) + +func testHTTPRoutePartiallyConflictMatch(namespace string, gateway types.NamespacedName) { + Specify("Creates two http routes, second one has partial conflict match against the first one, has partially match condition", func() { + By("create httproute-1 first") + route1 := &gatewayapi_v1.HTTPRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "httproute-1", + }, + Spec: gatewayapi_v1.HTTPRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.HTTPRouteRule{ + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + {QueryParams: gatewayapi.HTTPQueryParamMatches(map[string]string{"animal": "whale"})}, + }, + BackendRefs: gatewayapi.HTTPBackendRef("echo-1", 80, 1), + }, + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + {QueryParams: gatewayapi.HTTPQueryParamMatches(map[string]string{"animal": "dolphin"})}, + }, + BackendRefs: gatewayapi.HTTPBackendRef("echo-2", 80, 1), + }, + }, + }, + } + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route1, e2e.HTTPRouteAccepted)) + + By("create httproute-2 with only partially conflicted matches") + route2 := &gatewayapi_v1.HTTPRoute{ + ObjectMeta: meta_v1.ObjectMeta{ + Namespace: namespace, + Name: "httproute-2", + }, + Spec: gatewayapi_v1.HTTPRouteSpec{ + Hostnames: []gatewayapi_v1.Hostname{"queryparams.gateway.projectcontour.io"}, + CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ + ParentRefs: []gatewayapi_v1.ParentReference{ + gatewayapi.GatewayParentRef(gateway.Namespace, gateway.Name), + }, + }, + Rules: []gatewayapi_v1.HTTPRouteRule{ + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + {QueryParams: gatewayapi.HTTPQueryParamMatches(map[string]string{"animal": "whale"})}, + }, + BackendRefs: gatewayapi.HTTPBackendRef("echo-1", 80, 1), + }, + { + Matches: []gatewayapi_v1.HTTPRouteMatch{ + {QueryParams: gatewayapi.HTTPQueryParamMatches(map[string]string{"no-conflict": "no-joke", "no-conflict-again": "no-joke"})}, + }, + BackendRefs: gatewayapi.HTTPBackendRef("echo-2", 80, 1), + }, + }, + }, + } + // Partially accepted + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route2, func(*gatewayapi_v1.HTTPRoute) bool { + return e2e.HTTPRoutePartiallyInvalid(route2) && e2e.HTTPRouteAccepted(route2) + })) + }) +} diff --git a/test/e2e/gateway/multiple_https_listeners_test.go b/test/e2e/gateway/multiple_https_listeners_test.go index 39bbd786adb..836e6f94952 100644 --- a/test/e2e/gateway/multiple_https_listeners_test.go +++ b/test/e2e/gateway/multiple_https_listeners_test.go @@ -58,8 +58,8 @@ func testMultipleHTTPSListeners(namespace string) { }, }, } - _, ok := f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) - require.True(t, ok, "expected HTTPRoute to be accepted") + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) + } // Make requests to each listener hostname and validate the response diff --git a/test/e2e/gateway/query_param_match_test.go b/test/e2e/gateway/query_param_match_test.go index 3109a2d0e33..821227c2f03 100644 --- a/test/e2e/gateway/query_param_match_test.go +++ b/test/e2e/gateway/query_param_match_test.go @@ -64,7 +64,7 @@ func testGatewayMultipleQueryParamMatch(namespace string, gateway types.Namespac }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) cases := map[string]string{ // These test cases are for documenting Envoy's behavior when diff --git a/test/e2e/gateway/request_header_modifier_test.go b/test/e2e/gateway/request_header_modifier_test.go index f3a824d6711..2b29e4c066d 100644 --- a/test/e2e/gateway/request_header_modifier_test.go +++ b/test/e2e/gateway/request_header_modifier_test.go @@ -80,7 +80,7 @@ func testRequestHeaderModifierBackendRef(namespace string, gateway types.Namespa }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) // Check the route with the RequestHeaderModifier filter. res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ diff --git a/test/e2e/gateway/request_redirect_test.go b/test/e2e/gateway/request_redirect_test.go index 803d2577c02..b7194ac1faf 100644 --- a/test/e2e/gateway/request_redirect_test.go +++ b/test/e2e/gateway/request_redirect_test.go @@ -66,7 +66,7 @@ func testRequestRedirectRule(namespace string, gateway types.NamespacedName) { }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) // /complex-redirect specifies a host name, // scheme, port and response code for the diff --git a/test/e2e/gateway/response_header_modifier_test.go b/test/e2e/gateway/response_header_modifier_test.go index c01a9fe5cee..00aa8f2b33d 100644 --- a/test/e2e/gateway/response_header_modifier_test.go +++ b/test/e2e/gateway/response_header_modifier_test.go @@ -81,7 +81,7 @@ func testResponseHeaderModifierBackendRef(namespace string, gateway types.Namesp }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) // Check the route is available. res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ diff --git a/test/e2e/gateway/tcproute_test.go b/test/e2e/gateway/tcproute_test.go index 033928d0501..51dae2821de 100644 --- a/test/e2e/gateway/tcproute_test.go +++ b/test/e2e/gateway/tcproute_test.go @@ -44,7 +44,7 @@ func testTCPRoute(namespace string, gateway types.NamespacedName) { }, Spec: gatewayapi_v1alpha2.TCPRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + ParentRefs: []gatewayapi_v1.ParentReference{ { Namespace: ptr.To(gatewayapi_v1.Namespace(gateway.Namespace)), Name: gatewayapi_v1.ObjectName(gateway.Name), @@ -58,9 +58,7 @@ func testTCPRoute(namespace string, gateway types.NamespacedName) { }, }, } - route, ok := f.CreateTCPRouteAndWaitFor(route, e2e.TCPRouteAccepted) - require.True(t, ok) - require.NotNil(t, route) + require.True(f.T(), f.CreateTCPRouteAndWaitFor(route, e2e.TCPRouteAccepted)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Condition: e2e.HasStatusCode(200), diff --git a/test/e2e/gateway/tls_gateway_test.go b/test/e2e/gateway/tls_gateway_test.go index 34883d0902e..af582ebec99 100644 --- a/test/e2e/gateway/tls_gateway_test.go +++ b/test/e2e/gateway/tls_gateway_test.go @@ -59,7 +59,7 @@ func testTLSGateway(namespace string, gateway types.NamespacedName) { }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) route = &gatewayapi_v1.HTTPRoute{ ObjectMeta: meta_v1.ObjectMeta{ @@ -85,7 +85,7 @@ func testTLSGateway(namespace string, gateway types.NamespacedName) { }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) // Ensure http (insecure) request routes to echo-insecure. res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ diff --git a/test/e2e/gateway/tls_wildcard_host_test.go b/test/e2e/gateway/tls_wildcard_host_test.go index 54137abe33f..49b36d5e321 100644 --- a/test/e2e/gateway/tls_wildcard_host_test.go +++ b/test/e2e/gateway/tls_wildcard_host_test.go @@ -60,7 +60,7 @@ func testTLSWildcardHost(namespace string, gateway types.NamespacedName) { }, }, } - f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) cases := []struct { hostname string diff --git a/test/e2e/gatewayapi_predicates.go b/test/e2e/gatewayapi_predicates.go index a9ac70d2ee6..64bdf448fbc 100644 --- a/test/e2e/gatewayapi_predicates.go +++ b/test/e2e/gatewayapi_predicates.go @@ -16,9 +16,15 @@ package e2e import ( + "fmt" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" gatewayapi_v1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapi_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gatewayapi_v1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" + + "github.com/projectcontour/contour/internal/dag" + "github.com/projectcontour/contour/internal/status" ) // GatewayClassAccepted returns true if the gateway has a .status.conditions @@ -119,6 +125,40 @@ func HTTPRouteAccepted(route *gatewayapi_v1.HTTPRoute) bool { return false } +// HTTPRouteNotAcceptedDueToConflict returns true if the route has a .status.conditions +// entry of "Accepted: false" && "Reason: RouteMatchConflict" && "Message: HTTPRoute's Match has +// conflict with other HTTPRoute's Match". +func HTTPRouteNotAcceptedDueToConflict(route *gatewayapi_v1.HTTPRoute) bool { + if route == nil { + return false + } + + for _, gw := range route.Status.Parents { + if conditionExistsWithAllKeys(gw.Conditions, string(gatewayapi_v1.RouteConditionAccepted), meta_v1.ConditionFalse, string(status.ReasonRouteRuleMatchConflict), fmt.Sprintf(status.MessageRouteRuleMatchConflict, dag.KindHTTPRoute, dag.KindHTTPRoute)) { + return true + } + } + + return false +} + +// HTTPRoutePartiallyInvalid returns true if the route has a .status.conditions +// entry of "PartiallyInvalid: true" && "Reason: RuleMatchPartiallyConflict" && "Message: +// HTTPRoute's Match has partial conflict with other HTTPRoute's Match". +func HTTPRoutePartiallyInvalid(route *gatewayapi_v1.HTTPRoute) bool { + if route == nil { + return false + } + + for _, gw := range route.Status.Parents { + if conditionExistsWithAllKeys(gw.Conditions, string(gatewayapi_v1.RouteConditionPartiallyInvalid), meta_v1.ConditionTrue, string(status.ReasonRouteRuleMatchPartiallyConflict), fmt.Sprintf(status.MessageRouteRuleMatchPartiallyConflict, dag.KindHTTPRoute, dag.KindHTTPRoute)) { + return true + } + } + + return false +} + // HTTPRouteIgnoredByContour returns true if the route has an empty .status.parents.conditions list func HTTPRouteIgnoredByContour(route *gatewayapi_v1.HTTPRoute) bool { if route == nil { @@ -161,7 +201,57 @@ func TLSRouteAccepted(route *gatewayapi_v1alpha2.TLSRoute) bool { } for _, gw := range route.Status.Parents { - if conditionExists(gw.Conditions, string(gatewayapi_v1alpha2.RouteConditionAccepted), meta_v1.ConditionTrue) { + if conditionExists(gw.Conditions, string(gatewayapi_v1.RouteConditionAccepted), meta_v1.ConditionTrue) { + return true + } + } + + return false +} + +// GRPCRouteAccepted returns true if the route has a .status.conditions +// entry of "Accepted: true". +func GRPCRouteAccepted(route *gatewayapi_v1.GRPCRoute) bool { + if route == nil { + return false + } + + for _, gw := range route.Status.Parents { + if conditionExists(gw.Conditions, string(gatewayapi_v1.RouteConditionAccepted), meta_v1.ConditionTrue) { + return true + } + } + + return false +} + +// GRPCRouteNotAcceptedDueToConflict returns true if the route has a .status.conditions +// entry of "Accepted: false" && "Reason: RouteMatchConflict" && "Message: GRPCRoute's Match has +// conflict with other GRPCRoute's Match". +func GRPCRouteNotAcceptedDueToConflict(route *gatewayapi_v1.GRPCRoute) bool { + if route == nil { + return false + } + + for _, gw := range route.Status.Parents { + if conditionExistsWithAllKeys(gw.Conditions, string(gatewayapi_v1.RouteConditionAccepted), meta_v1.ConditionFalse, string(status.ReasonRouteRuleMatchConflict), fmt.Sprintf(status.MessageRouteRuleMatchConflict, dag.KindGRPCRoute, dag.KindGRPCRoute)) { + return true + } + } + + return false +} + +// GRPCRoutePartiallyInvalid returns true if the route has a .status.conditions +// entry of "PartiallyInvalid: true" && "Reason: RuleMatchPartiallyConflict" && "Message: +// GRPCRoute's Match has partial conflict with other GRPCRoute's Match". +func GRPCRoutePartiallyInvalid(route *gatewayapi_v1.GRPCRoute) bool { + if route == nil { + return false + } + + for _, gw := range route.Status.Parents { + if conditionExistsWithAllKeys(gw.Conditions, string(gatewayapi_v1.RouteConditionPartiallyInvalid), meta_v1.ConditionTrue, string(status.ReasonRouteRuleMatchPartiallyConflict), fmt.Sprintf(status.MessageRouteRuleMatchPartiallyConflict, dag.KindGRPCRoute, dag.KindGRPCRoute)) { return true } } @@ -171,7 +261,7 @@ func TLSRouteAccepted(route *gatewayapi_v1alpha2.TLSRoute) bool { // BackendTLSPolicyAccepted returns true if the backend TLS policy has a .status.conditions // entry of "Accepted: true". -func BackendTLSPolicyAccepted(btp *gatewayapi_v1alpha2.BackendTLSPolicy) bool { +func BackendTLSPolicyAccepted(btp *gatewayapi_v1alpha3.BackendTLSPolicy) bool { if btp == nil { return false } @@ -194,3 +284,13 @@ func conditionExists(conditions []meta_v1.Condition, conditionType string, condi return false } + +func conditionExistsWithAllKeys(conditions []meta_v1.Condition, conditionType string, conditionStatus meta_v1.ConditionStatus, reason, message string) bool { + for _, cond := range conditions { + if cond.Type == conditionType && cond.Status == conditionStatus && cond.Reason == reason && cond.Message == message { + return true + } + } + + return false +} diff --git a/test/e2e/httpproxy/backend_tls_protocol_version_test.go b/test/e2e/httpproxy/backend_tls_protocol_version_test.go index b0de55f0a10..fd91081fc18 100644 --- a/test/e2e/httpproxy/backend_tls_protocol_version_test.go +++ b/test/e2e/httpproxy/backend_tls_protocol_version_test.go @@ -78,7 +78,7 @@ func testBackendTLSProtocolVersion(namespace, protocolVersion string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) type responseTLSDetails struct { TLS struct { diff --git a/test/e2e/httpproxy/backend_tls_test.go b/test/e2e/httpproxy/backend_tls_test.go index de5e7fcda0b..2dc6281b8e8 100644 --- a/test/e2e/httpproxy/backend_tls_test.go +++ b/test/e2e/httpproxy/backend_tls_test.go @@ -81,7 +81,7 @@ func testBackendTLS(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) type responseTLSDetails struct { TLS struct { diff --git a/test/e2e/httpproxy/client_cert_auth_test.go b/test/e2e/httpproxy/client_cert_auth_test.go index 3f3cad87dd0..268aac6ded3 100644 --- a/test/e2e/httpproxy/client_cert_auth_test.go +++ b/test/e2e/httpproxy/client_cert_auth_test.go @@ -289,7 +289,7 @@ func testClientCertAuth(namespace string) { } // Wait for the Cert to be ready since we'll directly download // the secret contents for use as a client cert later on. - f.Certs.CreateCertAndWaitFor(clientCert, certIsReady) + require.True(f.T(), f.Certs.CreateCertAndWaitFor(clientCert, certIsReady)) // Get another client certificate. clientCertInvalid := &certmanagerv1.Certificate{ @@ -313,7 +313,7 @@ func testClientCertAuth(namespace string) { } // Wait for the Cert to be ready since we'll directly download // the secret contents for use as a client cert later on. - f.Certs.CreateCertAndWaitFor(clientCertInvalid, certIsReady) + require.True(f.T(), f.Certs.CreateCertAndWaitFor(clientCertInvalid, certIsReady)) // This proxy does not require client certificate auth. noAuthProxy := &contour_v1.HTTPProxy{ @@ -340,7 +340,7 @@ func testClientCertAuth(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(noAuthProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(noAuthProxy, e2e.HTTPProxyValid)) // This proxy requires client certificate auth. authProxy := &contour_v1.HTTPProxy{ @@ -370,7 +370,7 @@ func testClientCertAuth(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(authProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(authProxy, e2e.HTTPProxyValid)) // This proxy does not verify client certs. authSkipVerifyProxy := &contour_v1.HTTPProxy{ @@ -400,7 +400,7 @@ func testClientCertAuth(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(authSkipVerifyProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(authSkipVerifyProxy, e2e.HTTPProxyValid)) // This proxy requires a client certificate but does not verify it. authSkipVerifyWithCAProxy := &contour_v1.HTTPProxy{ @@ -431,7 +431,7 @@ func testClientCertAuth(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(authSkipVerifyWithCAProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(authSkipVerifyWithCAProxy, e2e.HTTPProxyValid)) // This proxy requests a client certificate but only verifies it if sent. optionalAuthProxy := &contour_v1.HTTPProxy{ @@ -462,7 +462,7 @@ func testClientCertAuth(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(optionalAuthProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(optionalAuthProxy, e2e.HTTPProxyValid)) // This proxy requests a client certificate but doesn't verify it if sent. optionalAuthNoCAProxy := &contour_v1.HTTPProxy{ @@ -493,7 +493,7 @@ func testClientCertAuth(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(optionalAuthNoCAProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(optionalAuthNoCAProxy, e2e.HTTPProxyValid)) // get the valid & invalid client certs validClientCert, _ := f.Certs.GetTLSCertificate(namespace, clientCert.Spec.SecretName) diff --git a/test/e2e/httpproxy/client_cert_crl_test.go b/test/e2e/httpproxy/client_cert_crl_test.go index 108ae50276e..6ef7f076895 100644 --- a/test/e2e/httpproxy/client_cert_crl_test.go +++ b/test/e2e/httpproxy/client_cert_crl_test.go @@ -181,7 +181,7 @@ func testClientCertRevocation(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(proxyWithFullCRLCheck, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxyWithFullCRLCheck, e2e.HTTPProxyValid)) // Create HTTPProxy that does CRL check for leaf-certificates only. proxyWithCRLLeafOnly := &contour_v1.HTTPProxy{ @@ -213,7 +213,7 @@ func testClientCertRevocation(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(proxyWithCRLLeafOnly, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxyWithCRLLeafOnly, e2e.HTTPProxyValid)) // HTTPProxy with full chain revocation but refers to Secret with only partial set of CRLs. proxyWithCRLMissing := &contour_v1.HTTPProxy{ @@ -244,7 +244,7 @@ func testClientCertRevocation(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(proxyWithCRLMissing, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxyWithCRLMissing, e2e.HTTPProxyValid)) cases := map[string]struct { host string @@ -407,7 +407,7 @@ func testClientCertRevocation(namespace string) { } // HTTPProxy should be invalid since CertificateRevocationList refers to non-existent Secret. - f.CreateHTTPProxyAndWaitFor(proxyWithCRLCheck, e2e.HTTPProxyInvalid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxyWithCRLCheck, e2e.HTTPProxyInvalid)) // Create Secret with CRL where client certificate is revoked. require.NoError(t, f.Client.Create(context.TODO(), diff --git a/test/e2e/httpproxy/cookie_rewrite_test.go b/test/e2e/httpproxy/cookie_rewrite_test.go index 46cfb966d00..de8bf09965b 100644 --- a/test/e2e/httpproxy/cookie_rewrite_test.go +++ b/test/e2e/httpproxy/cookie_rewrite_test.go @@ -347,7 +347,7 @@ func testAppCookieRewrite(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // No rewrite rule on route, nothing should change. headers := requestSetCookieHeader(false, p.Spec.VirtualHost.Fqdn, "/no-rewrite", "no-rewrite=foo; Path=/nrw; Domain=nrw.com; SameSite=Strict; Secure") @@ -469,7 +469,7 @@ func testHeaderGlobalRewriteCookieRewrite(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Path: "/global", @@ -608,7 +608,7 @@ func testHeaderRewriteCookieRewrite(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Path: "/cookie-lb", @@ -695,7 +695,7 @@ func testCookieRewriteTLS(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) headers := requestSetCookieHeader(true, p.Spec.VirtualHost.Fqdn, "/", "a-cookie=bar; Domain=cookie-rewrite-tls.projectcontour.io; Path=/; SameSite=Strict; Secure") checkReturnedSetCookieHeader(headers, "a-cookie", "bar", "/", "cookie-rewrite-tls.projectcontour.io", "Strict", true, nil) diff --git a/test/e2e/httpproxy/default_global_rate_limiting_test.go b/test/e2e/httpproxy/default_global_rate_limiting_test.go index 90cb95dd44b..196bb83b343 100644 --- a/test/e2e/httpproxy/default_global_rate_limiting_test.go +++ b/test/e2e/httpproxy/default_global_rate_limiting_test.go @@ -56,7 +56,7 @@ func testDefaultGlobalRateLimitingVirtualHostNonTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 429 from the proxy confirming // that we've exceeded the rate limit. @@ -104,7 +104,7 @@ func testDefaultGlobalRateLimitingVirtualHostNonTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -176,7 +176,7 @@ func testDefaultGlobalRateLimitingVirtualHostNonTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Make requests against the proxy, confirm a 429 response // is now gotten since we've exceeded the rate limit. @@ -220,7 +220,7 @@ func testDefaultGlobalRateLimitingVirtualHostTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 429 from the proxy confirming // that we've exceeded the rate limit. @@ -272,7 +272,7 @@ func testDefaultGlobalRateLimitingVirtualHostTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -349,7 +349,7 @@ func testDefaultGlobalRateLimitingVirtualHostTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Make requests against the proxy, confirm a 429 response // is now gotten since we've exceeded the rate limit. @@ -399,7 +399,7 @@ func testDefaultGlobalRateLimitingWithVhRateLimitsIgnore(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 429 from the proxy confirming // that we've exceeded the rate limit. diff --git a/test/e2e/httpproxy/direct_response_test.go b/test/e2e/httpproxy/direct_response_test.go index cc18c3db604..870996e26f8 100644 --- a/test/e2e/httpproxy/direct_response_test.go +++ b/test/e2e/httpproxy/direct_response_test.go @@ -36,8 +36,7 @@ func testDirectResponseRule(namespace string) { func doDirectTest(namespace string, proxy *contour_v1.HTTPProxy, t GinkgoTInterface) { f.Fixtures.Echo.Deploy(namespace, "echo") - _, ok := f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyValid) - require.True(f.T(), ok) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyValid)) assertDirectResponseRequest(t, proxy.Spec.VirtualHost.Fqdn, "/directresponse-nobody", "", 200) diff --git a/test/e2e/httpproxy/dynamic_headers_test.go b/test/e2e/httpproxy/dynamic_headers_test.go index 0ea2b791ceb..8e11261bc26 100644 --- a/test/e2e/httpproxy/dynamic_headers_test.go +++ b/test/e2e/httpproxy/dynamic_headers_test.go @@ -144,7 +144,7 @@ func testDynamicHeaders(namespace string) { p.Spec.Routes[0].Services[0].ResponseHeadersPolicy.Set = append(p.Spec.Routes[0].Services[0].ResponseHeadersPolicy.Set, hv) } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/exact_path_condition_match_test.go b/test/e2e/httpproxy/exact_path_condition_match_test.go index f1c722997df..87f401a1566 100644 --- a/test/e2e/httpproxy/exact_path_condition_match_test.go +++ b/test/e2e/httpproxy/exact_path_condition_match_test.go @@ -19,6 +19,7 @@ package httpproxy import ( . "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -128,7 +129,7 @@ func testExactPathCondition(namespace string) { }, } - f.CreateHTTPProxyAndWaitFor(serviceProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(serviceProxy, e2e.HTTPProxyValid)) cases := map[string]string{ "/": "echo-default", // Condition matched: "Prefix: /" diff --git a/test/e2e/httpproxy/external_auth_test.go b/test/e2e/httpproxy/external_auth_test.go index c35bfb1226b..89f678c382a 100644 --- a/test/e2e/httpproxy/external_auth_test.go +++ b/test/e2e/httpproxy/external_auth_test.go @@ -17,6 +17,7 @@ package httpproxy import ( "context" + "net/http" . "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" @@ -206,6 +207,25 @@ func testExternalAuth(namespace string) { }, }, }, + { + Conditions: []contour_v1.MatchCondition{ + {Prefix: "/direct-response-auth-enabled"}, + }, + DirectResponsePolicy: &contour_v1.HTTPDirectResponsePolicy{ + StatusCode: http.StatusTeapot, + }, + }, + { + Conditions: []contour_v1.MatchCondition{ + {Prefix: "/direct-response-auth-disabled"}, + }, + DirectResponsePolicy: &contour_v1.HTTPDirectResponsePolicy{ + StatusCode: http.StatusTeapot, + }, + AuthPolicy: &contour_v1.AuthorizationPolicy{ + Disabled: true, + }, + }, { AuthPolicy: &contour_v1.AuthorizationPolicy{ @@ -223,7 +243,7 @@ func testExternalAuth(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // By default requests to /first should not be authorized. res, ok := f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ @@ -283,5 +303,33 @@ func testExternalAuth(namespace string) { body = f.GetEchoResponseBody(res.Body) assert.Equal(t, "default", body.RequestHeaders.Get("Auth-Context-Target")) assert.Equal(t, "externalauth.projectcontour.io", body.RequestHeaders.Get("Auth-Context-Hostname")) + + // Direct response with external auth enabled should get a 401. + res, ok = f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ + Host: p.Spec.VirtualHost.Fqdn, + Path: "/direct-response-auth-enabled", + Condition: e2e.HasStatusCode(401), + }) + require.NotNil(t, res, "request never succeeded") + require.Truef(t, ok, "expected 401 response code, got %d", res.StatusCode) + + // Direct response with external auth enabled with "allow" in the path + // should succeed. + res, ok = f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ + Host: p.Spec.VirtualHost.Fqdn, + Path: "/direct-response-auth-enabled/allow", + Condition: e2e.HasStatusCode(http.StatusTeapot), + }) + require.NotNil(t, res, "request never succeeded") + require.Truef(t, ok, "expected 418 response code, got %d", res.StatusCode) + + // Direct response with external auth disabled should succeed. + res, ok = f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ + Host: p.Spec.VirtualHost.Fqdn, + Path: "/direct-response-auth-disabled", + Condition: e2e.HasStatusCode(http.StatusTeapot), + }) + require.NotNil(t, res, "request never succeeded") + require.Truef(t, ok, "expected 418 response code, got %d", res.StatusCode) }) } diff --git a/test/e2e/httpproxy/external_name_test.go b/test/e2e/httpproxy/external_name_test.go index 20baf86a355..89899d0a2f4 100644 --- a/test/e2e/httpproxy/external_name_test.go +++ b/test/e2e/httpproxy/external_name_test.go @@ -82,10 +82,7 @@ func testExternalNameServiceInsecure(namespace string) { }, }, } - proxy, ok := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - if !ok { - t.Fatalf("The HTTPProxy did not become valid, here are the Valid condition's Errors: %s", e2e.HTTPProxyErrors(proxy)) - } + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -153,10 +150,7 @@ func testExternalNameServiceTLS(namespace string) { }, }, } - proxy, ok := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - if !ok { - t.Fatalf("The HTTPProxy did not become valid, here are the Valid condition's Errors: %s", e2e.HTTPProxyErrors(proxy)) - } + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -225,7 +219,7 @@ func testExternalNameServiceLocalhostInvalid(namespace string) { // The HTTPProxy should be marked invalid due to the service // using localhost.localdomain. - _, invalid := f.CreateHTTPProxyAndWaitFor(p, func(proxy *contour_v1.HTTPProxy) bool { + require.Truef(f.T(), f.CreateHTTPProxyAndWaitFor(p, func(proxy *contour_v1.HTTPProxy) bool { validCond := proxy.Status.GetConditionFor(contour_v1.ValidConditionType) if validCond == nil { return false @@ -243,7 +237,6 @@ func testExternalNameServiceLocalhostInvalid(namespace string) { } return false - }) - require.Truef(t, invalid, "ExternalName with hostname %s was accepted by Contour.", externalNameService.Spec.ExternalName) + }), "ExternalName with hostname %s was accepted by Contour.", externalNameService.Spec.ExternalName) }) } diff --git a/test/e2e/httpproxy/fqdn_test.go b/test/e2e/httpproxy/fqdn_test.go index 4057928f3b2..f640ada3573 100644 --- a/test/e2e/httpproxy/fqdn_test.go +++ b/test/e2e/httpproxy/fqdn_test.go @@ -122,9 +122,9 @@ func testWildcardSubdomainFQDN(namespace string) { }}, }, } - f.CreateHTTPProxyAndWaitFor(proxyWildcard, e2e.HTTPProxyValid) - f.CreateHTTPProxyAndWaitFor(proxyFullFQDN, e2e.HTTPProxyValid) - f.CreateHTTPProxyAndWaitFor(proxyFullFQDNSubdomain, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxyWildcard, e2e.HTTPProxyValid)) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxyFullFQDN, e2e.HTTPProxyValid)) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxyFullFQDNSubdomain, e2e.HTTPProxyValid)) cases := map[string]struct { ServiceName string @@ -240,7 +240,7 @@ func testIngressWildcardSubdomainFQDN(namespace string) { }}, }, } - f.CreateHTTPProxyAndWaitFor(proxySubdomain, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxySubdomain, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: "www.wildcard-override.projectcontour.io", diff --git a/test/e2e/httpproxy/global_external_auth_test.go b/test/e2e/httpproxy/global_external_auth_test.go index c66407f31c1..7e0b49898c7 100644 --- a/test/e2e/httpproxy/global_external_auth_test.go +++ b/test/e2e/httpproxy/global_external_auth_test.go @@ -86,7 +86,7 @@ func testGlobalExternalAuthVirtualHostNonTLS(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // By default requests to /first should not be authorized. res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ @@ -184,7 +184,7 @@ func testGlobalExternalAuthTLS(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // By default requests to /first should not be authorized. res, ok := f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ @@ -275,7 +275,7 @@ func testGlobalExternalAuthNonTLSAuthDisabled(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -367,7 +367,7 @@ func testGlobalExternalAuthTLSAuthDisabled(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/global_rate_limiting_test.go b/test/e2e/httpproxy/global_rate_limiting_test.go index 35526283f70..cb8427c76c3 100644 --- a/test/e2e/httpproxy/global_rate_limiting_test.go +++ b/test/e2e/httpproxy/global_rate_limiting_test.go @@ -55,7 +55,7 @@ func testGlobalRateLimitingVirtualHostNonTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -151,7 +151,7 @@ func testGlobalRateLimitingRouteNonTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -249,7 +249,7 @@ func testGlobalRateLimitingVirtualHostTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -349,7 +349,7 @@ func testGlobalRateLimitingRouteTLS(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -447,7 +447,7 @@ func testDisableVirtualHostGlobalRateLimitingOnRoute(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -549,7 +549,7 @@ func testDisableVirtualHostGlobalRateLimitingOnRoute(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. diff --git a/test/e2e/httpproxy/grpc_test.go b/test/e2e/httpproxy/grpc_test.go index dbac88b887f..95daa84cc45 100644 --- a/test/e2e/httpproxy/grpc_test.go +++ b/test/e2e/httpproxy/grpc_test.go @@ -80,8 +80,7 @@ func testGRPCServicePlaintext(namespace string) { }, }, } - _, ok := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - require.True(t, ok) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) insecureAddr := strings.TrimPrefix(f.HTTP.HTTPURLBase, "http://") secureAddr := strings.TrimPrefix(f.HTTP.HTTPSURLBase, "https://") @@ -93,8 +92,6 @@ func testGRPCServicePlaintext(namespace string) { InsecureSkipVerify: true, }), } { - dialCtx, dialCancel := context.WithTimeout(context.Background(), time.Second*30) - defer dialCancel() retryOpts := []grpc_retry.CallOption{ // Retry if Envoy returns unavailable, the upstream // may not be healthy yet. @@ -106,8 +103,7 @@ func testGRPCServicePlaintext(namespace string) { grpc_retry.WithBackoff(grpc_retry.BackoffExponential(time.Millisecond * 10)), grpc_retry.WithMax(20), } - conn, err := grpc.DialContext(dialCtx, addr, - grpc.WithBlock(), + conn, err := grpc.NewClient(addr, grpc.WithAuthority(p.Spec.VirtualHost.Fqdn), grpc.WithTransportCredentials(transportCreds), grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(retryOpts...)), @@ -159,8 +155,7 @@ func testGRPCWeb(namespace string) { }, }, } - _, ok := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - require.True(t, ok) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // One byte marker that this is a data frame, and 4 bytes // for the length (we can use 0 since the yages.Empty message diff --git a/test/e2e/httpproxy/header_condition_match_test.go b/test/e2e/httpproxy/header_condition_match_test.go index 7b427db3274..b20cff02a25 100644 --- a/test/e2e/httpproxy/header_condition_match_test.go +++ b/test/e2e/httpproxy/header_condition_match_test.go @@ -243,7 +243,7 @@ func testHeaderConditionMatch(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) type scenario struct { headers map[string]string diff --git a/test/e2e/httpproxy/host_header_rewrite_test.go b/test/e2e/httpproxy/host_header_rewrite_test.go index 3ce306b917f..7bc37e828af 100644 --- a/test/e2e/httpproxy/host_header_rewrite_test.go +++ b/test/e2e/httpproxy/host_header_rewrite_test.go @@ -64,7 +64,7 @@ func testHostRewriteLiteral(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -118,7 +118,7 @@ func testHostRewriteHeaderHTTPService(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -177,7 +177,7 @@ func testHostRewriteHeaderHTTPSService(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -251,7 +251,7 @@ func testHostRewriteHeaderExternalNameService(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/http_health_checks_test.go b/test/e2e/httpproxy/http_health_checks_test.go index e743ed3dcf4..c726cadf6f7 100644 --- a/test/e2e/httpproxy/http_health_checks_test.go +++ b/test/e2e/httpproxy/http_health_checks_test.go @@ -55,7 +55,7 @@ func testHTTPHealthChecks(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/https_fallback_certificate_test.go b/test/e2e/httpproxy/https_fallback_certificate_test.go index c9532e1b794..72aa9cb8bea 100644 --- a/test/e2e/httpproxy/https_fallback_certificate_test.go +++ b/test/e2e/httpproxy/https_fallback_certificate_test.go @@ -59,7 +59,7 @@ func testHTTPSFallbackCertificate(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Send a request that includes a valid SNI, confirm a 200 is // returned. diff --git a/test/e2e/httpproxy/https_misdirected_request_test.go b/test/e2e/httpproxy/https_misdirected_request_test.go index 6f13c63af60..0730b7bf472 100644 --- a/test/e2e/httpproxy/https_misdirected_request_test.go +++ b/test/e2e/httpproxy/https_misdirected_request_test.go @@ -58,7 +58,7 @@ func testHTTPSMisdirectedRequest(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/https_sni_enforcement_test.go b/test/e2e/httpproxy/https_sni_enforcement_test.go index dbb0dbc204f..8c4172e075e 100644 --- a/test/e2e/httpproxy/https_sni_enforcement_test.go +++ b/test/e2e/httpproxy/https_sni_enforcement_test.go @@ -58,7 +58,7 @@ func testHTTPSSNIEnforcement(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(echoOneProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(echoOneProxy, e2e.HTTPProxyValid)) res, ok := f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ Host: echoOneProxy.Spec.VirtualHost.Fqdn, @@ -98,7 +98,7 @@ func testHTTPSSNIEnforcement(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(echoTwoProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(echoTwoProxy, e2e.HTTPProxyValid)) res, ok = f.HTTP.SecureRequestUntil(&e2e.HTTPSRequestOpts{ Host: echoTwoProxy.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/include_exact_condition_test.go b/test/e2e/httpproxy/include_exact_condition_test.go index f2f24597c0b..af866bc41ad 100644 --- a/test/e2e/httpproxy/include_exact_condition_test.go +++ b/test/e2e/httpproxy/include_exact_condition_test.go @@ -186,8 +186,8 @@ func testIncludeExactCondition(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(baseProxy, e2e.HTTPProxyValid) - f.CreateHTTPProxyAndWaitFor(invalidRootProxy, e2e.HTTPProxyInvalid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(baseProxy, e2e.HTTPProxyValid)) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(invalidRootProxy, e2e.HTTPProxyInvalid)) cases := map[string]string{ "/app/foo": "echo-app", // Condition matched: "Prefix: /app" + "Exact: /foo" = "Exact: /app/foo" diff --git a/test/e2e/httpproxy/include_prefix_condition_test.go b/test/e2e/httpproxy/include_prefix_condition_test.go index 7536f82f92e..abf1717c326 100644 --- a/test/e2e/httpproxy/include_prefix_condition_test.go +++ b/test/e2e/httpproxy/include_prefix_condition_test.go @@ -118,7 +118,7 @@ func testIncludePrefixCondition(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(baseProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(baseProxy, e2e.HTTPProxyValid)) cases := map[string]string{ "/": "echo-app", diff --git a/test/e2e/httpproxy/include_regex_path_condition_test.go b/test/e2e/httpproxy/include_regex_path_condition_test.go index 24407bc3efa..47c7b3dba35 100644 --- a/test/e2e/httpproxy/include_regex_path_condition_test.go +++ b/test/e2e/httpproxy/include_regex_path_condition_test.go @@ -175,9 +175,8 @@ func testIncludeRegexCondition(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(rootProxy, e2e.HTTPProxyValid) - - f.CreateHTTPProxyAndWaitFor(invalidRootProxy, e2e.HTTPProxyInvalid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(rootProxy, e2e.HTTPProxyValid)) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(invalidRootProxy, e2e.HTTPProxyInvalid)) cases := map[string]string{ "/echo2/": "echo-2", // "Prefix: / with included Prefix: echo2/" diff --git a/test/e2e/httpproxy/internal_redirect_test.go b/test/e2e/httpproxy/internal_redirect_test.go index d16920e8617..3875bd9199d 100644 --- a/test/e2e/httpproxy/internal_redirect_test.go +++ b/test/e2e/httpproxy/internal_redirect_test.go @@ -122,10 +122,7 @@ func doInternalRedirectTest(namespace string, proxy *contour_v1.HTTPProxy, t Gin } require.NoError(t, f.Client.Create(context.TODO(), envoyService)) - p, ok := f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyValid) - if !ok { - t.Fatalf("The HTTPProxy did not become valid, here are the Valid condition's Errors: %s", e2e.HTTPProxyErrors(p)) - } + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyValid)) // /redirect ensure the redirect works as expected. assertInternalRedirectRequest(t, proxy.Spec.VirtualHost.Fqdn, "/redirect", diff --git a/test/e2e/httpproxy/ip_filtering_test.go b/test/e2e/httpproxy/ip_filtering_test.go index 9b3681c488e..fab6e9fb19e 100644 --- a/test/e2e/httpproxy/ip_filtering_test.go +++ b/test/e2e/httpproxy/ip_filtering_test.go @@ -59,7 +59,7 @@ func testIPFilterPolicy(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -171,7 +171,7 @@ func testIPFilterPolicy(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -280,7 +280,7 @@ func testIPFilterPolicy(namespace string) { }, } // root will be missing an include when created - r, _ = f.CreateHTTPProxyAndWaitFor(r, e2e.HTTPProxyInvalid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(r, e2e.HTTPProxyInvalid)) p := &contour_v1.HTTPProxy{ ObjectMeta: meta_v1.ObjectMeta{ @@ -300,7 +300,7 @@ func testIPFilterPolicy(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. diff --git a/test/e2e/httpproxy/local_rate_limiting_test.go b/test/e2e/httpproxy/local_rate_limiting_test.go index c3be6a33804..c4073779f11 100644 --- a/test/e2e/httpproxy/local_rate_limiting_test.go +++ b/test/e2e/httpproxy/local_rate_limiting_test.go @@ -55,7 +55,7 @@ func testLocalRateLimitingVirtualHost(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. @@ -142,7 +142,7 @@ func testLocalRateLimitingRoute(namespace string) { }, }, } - p, _ = f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) // Wait until we get a 200 from the proxy confirming // the pods are up and serving traffic. diff --git a/test/e2e/httpproxy/merge_slash_test.go b/test/e2e/httpproxy/merge_slash_test.go index 41450edbe17..fba8406f146 100644 --- a/test/e2e/httpproxy/merge_slash_test.go +++ b/test/e2e/httpproxy/merge_slash_test.go @@ -84,8 +84,7 @@ func testDisableMergeSlashes(disableMergeSlashes bool) e2e.NamespacedTestBody { }, }, } - _, ok := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - require.True(t, ok) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) var testCases map[string]string if disableMergeSlashes { diff --git a/test/e2e/httpproxy/multiple_ingress_classes_test.go b/test/e2e/httpproxy/multiple_ingress_classes_test.go index 73a2a5518f3..f2d3f667fac 100644 --- a/test/e2e/httpproxy/multiple_ingress_classes_test.go +++ b/test/e2e/httpproxy/multiple_ingress_classes_test.go @@ -56,10 +56,7 @@ func testMultipleIngressClassesField(namespace string) { p.Spec.IngressClassName = class } - proxy, valid := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - if !valid { - t.Fatalf("The HTTPProxy did not become valid: %+v", proxy) - } + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -105,10 +102,7 @@ func testMultipleIngressClassesAnnotation(namespace string) { } } - proxy, valid := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - if !valid { - t.Fatalf("The HTTPProxy did not become valid - %+v", proxy) - } + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/namespaces_test.go b/test/e2e/httpproxy/namespaces_test.go index b8ebd183a86..a17c91bae9e 100644 --- a/test/e2e/httpproxy/namespaces_test.go +++ b/test/e2e/httpproxy/namespaces_test.go @@ -35,7 +35,7 @@ func testWatchNamespaces(namespaces []string) e2e.NamespacedTestBody { for _, ns := range namespaces { deployEchoServer(f.T(), f.Client, ns, "echo") p := newEchoProxy("proxy", ns) - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -68,7 +68,7 @@ func testWatchAndRootNamespaces(rootNamespaces []string, nonRootNamespace string for _, ns := range rootNamespaces { deployEchoServer(f.T(), f.Client, ns, "echo") p := newEchoProxy("root-proxy", ns) - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -82,8 +82,7 @@ func testWatchAndRootNamespaces(rootNamespaces []string, nonRootNamespace string // Root proxy in non-root namespace should fail p := newEchoProxy("root-proxy", nonRootNamespace) - _, ok := f.CreateHTTPProxyAndWaitFor(p, httpProxyRootNotAllowedInNS) - require.Truef(f.T(), ok, "expected HTTPProxy to have status RootNamespaceError") + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, httpProxyRootNotAllowedInNS), "expected HTTPProxy to have status RootNamespaceError") // Leaf proxy in non-root (but watched) namespace should succeed lp := &contour_v1.HTTPProxy{ @@ -123,7 +122,8 @@ func testWatchAndRootNamespaces(rootNamespaces []string, nonRootNamespace string } err := f.CreateHTTPProxy(lp) require.NoError(f.T(), err, "could not create leaf httpproxy") - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) + res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, Condition: e2e.HasStatusCode(200), @@ -154,7 +154,7 @@ func testRootNamespaces(namespaces []string) e2e.NamespacedTestBody { for _, ns := range namespaces { deployEchoServer(f.T(), f.Client, ns, "echo") p := newEchoProxy("root-proxy", ns) - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, @@ -167,8 +167,7 @@ func testRootNamespaces(namespaces []string) e2e.NamespacedTestBody { // Root proxy in non-root namespace should fail deployEchoServer(f.T(), f.Client, nonrootNS, "echo") p := newEchoProxy("root-proxy", nonrootNS) - _, ok := f.CreateHTTPProxyAndWaitFor(p, httpProxyRootNotAllowedInNS) - require.Truef(f.T(), ok, "expected HTTPProxy to have status RootNamespaceError") + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, httpProxyRootNotAllowedInNS), "expected HTTPProxy to have status RootNamespaceError") }) } } diff --git a/test/e2e/httpproxy/path_condition_match_test.go b/test/e2e/httpproxy/path_condition_match_test.go index e9cfa717af0..10ddf248aee 100644 --- a/test/e2e/httpproxy/path_condition_match_test.go +++ b/test/e2e/httpproxy/path_condition_match_test.go @@ -18,6 +18,7 @@ package httpproxy import ( . "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -79,7 +80,7 @@ func testPathConditionMatch(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) cases := map[string]string{ "/": "echo-slash-default", diff --git a/test/e2e/httpproxy/path_rewrite_test.go b/test/e2e/httpproxy/path_rewrite_test.go index 693386e246b..7fa40f67818 100644 --- a/test/e2e/httpproxy/path_rewrite_test.go +++ b/test/e2e/httpproxy/path_rewrite_test.go @@ -18,6 +18,7 @@ package httpproxy import ( . "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -100,7 +101,7 @@ func testPathPrefixRewrite(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) cases := []struct { path string diff --git a/test/e2e/httpproxy/pod_restart_test.go b/test/e2e/httpproxy/pod_restart_test.go index c0106299f2d..b48ab684db1 100644 --- a/test/e2e/httpproxy/pod_restart_test.go +++ b/test/e2e/httpproxy/pod_restart_test.go @@ -58,7 +58,7 @@ func testPodRestart(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/httpproxy/query_parameter_condition_match_test.go b/test/e2e/httpproxy/query_parameter_condition_match_test.go index d3474945ac7..71f72150744 100644 --- a/test/e2e/httpproxy/query_parameter_condition_match_test.go +++ b/test/e2e/httpproxy/query_parameter_condition_match_test.go @@ -20,6 +20,7 @@ import ( . "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -218,7 +219,7 @@ func testQueryParameterConditionMatch(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) type scenario struct { queryParams map[string]string @@ -400,7 +401,7 @@ func testQueryParameterConditionMultiple(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) type scenario struct { path string diff --git a/test/e2e/httpproxy/regex_path_condition_test.go b/test/e2e/httpproxy/regex_path_condition_test.go index ada51205580..5abdc69faad 100644 --- a/test/e2e/httpproxy/regex_path_condition_test.go +++ b/test/e2e/httpproxy/regex_path_condition_test.go @@ -18,6 +18,7 @@ package httpproxy import ( . "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" @@ -127,7 +128,7 @@ func testRegexPathCondition(namespace string) { }, } - f.CreateHTTPProxyAndWaitFor(serviceProxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(serviceProxy, e2e.HTTPProxyValid)) cases := map[string]string{ "/": "echo-1", // Regex Pattern / diff --git a/test/e2e/httpproxy/request_redirect_test.go b/test/e2e/httpproxy/request_redirect_test.go index 972f9eacd21..e1f5a50beca 100644 --- a/test/e2e/httpproxy/request_redirect_test.go +++ b/test/e2e/httpproxy/request_redirect_test.go @@ -47,14 +47,14 @@ func testRequestRedirectRuleInvalid(namespace string) { f.Fixtures.Echo.Deploy(namespace, "echo") proxy := getRedirectHTTPProxyInvalid(namespace) - f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyInvalid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyInvalid)) }) } func doRedirectTest(namespace string, proxy *contour_v1.HTTPProxy, t GinkgoTInterface) { f.Fixtures.Echo.Deploy(namespace, "echo") - f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(proxy, e2e.HTTPProxyValid)) // /basic-redirect only specifies a host name to redirect to. assertRequest(t, proxy.Spec.VirtualHost.Fqdn, "/basic-redirect", diff --git a/test/e2e/httpproxy/tcproute_https_termination_test.go b/test/e2e/httpproxy/tcproute_https_termination_test.go index a52a1baed3d..d5322307bdd 100644 --- a/test/e2e/httpproxy/tcproute_https_termination_test.go +++ b/test/e2e/httpproxy/tcproute_https_termination_test.go @@ -58,7 +58,7 @@ func testTCPRouteHTTPSTermination(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) certSecret := &core_v1.Secret{} key := client.ObjectKey{Namespace: namespace, Name: "echo-cert"} diff --git a/test/e2e/incluster/memory_usage_test.go b/test/e2e/incluster/memory_usage_test.go index a81aa32b798..b99ea426dda 100644 --- a/test/e2e/incluster/memory_usage_test.go +++ b/test/e2e/incluster/memory_usage_test.go @@ -89,8 +89,7 @@ func testHeaderMatchIncludesMemoryUsage(namespace string) { } // Wait for root to be valid. - _, valid := f.CreateHTTPProxyAndWaitFor(root, e2e.HTTPProxyValid) - require.True(f.T(), valid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(root, e2e.HTTPProxyValid)) // Ensure there are no container restarts. require.Never(f.T(), func() bool { diff --git a/test/e2e/incluster/rbac_test.go b/test/e2e/incluster/rbac_test.go index cc4f0cc24f4..35450a02c5a 100644 --- a/test/e2e/incluster/rbac_test.go +++ b/test/e2e/incluster/rbac_test.go @@ -80,8 +80,7 @@ func testProjectcontourResourcesRBAC(namespace string) { }, }, } - _, success := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyInvalid) - assert.True(f.T(), success) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyInvalid)) // Update HTTPProxy to valid service. require.NoError(f.T(), retry.RetryOnConflict(retry.DefaultBackoff, func() error { diff --git a/test/e2e/incluster/smoke_test.go b/test/e2e/incluster/smoke_test.go index 4ab72d216b6..1596284dc0c 100644 --- a/test/e2e/incluster/smoke_test.go +++ b/test/e2e/incluster/smoke_test.go @@ -57,7 +57,7 @@ func testSimpleSmoke(namespace string) { }, }, } - f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ Host: p.Spec.VirtualHost.Fqdn, diff --git a/test/e2e/infra/endpointslice_test.go b/test/e2e/infra/endpointslice_test.go index 8b6591458ee..f56153b8bc5 100644 --- a/test/e2e/infra/endpointslice_test.go +++ b/test/e2e/infra/endpointslice_test.go @@ -60,8 +60,7 @@ func testSimpleEndpointSlice(namespace string) { }, } - _, ok := f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid) - require.True(f.T(), ok) + require.True(f.T(), f.CreateHTTPProxyAndWaitFor(p, e2e.HTTPProxyValid)) require.Eventually(f.T(), func() bool { return IsEnvoyProgrammedWithAllPodIPs(namespace) diff --git a/test/e2e/provisioner/provisioner_test.go b/test/e2e/provisioner/provisioner_test.go index 0847189c68c..8c29f04a834 100644 --- a/test/e2e/provisioner/provisioner_test.go +++ b/test/e2e/provisioner/provisioner_test.go @@ -85,8 +85,7 @@ var _ = BeforeSuite(func() { } } - _, ok := f.CreateGatewayClassAndWaitFor(gc, e2e.GatewayClassAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateGatewayClassAndWaitFor(gc, e2e.GatewayClassAccepted)) paramsEnvoyDeployment := &contour_v1alpha1.ContourDeployment{ ObjectMeta: meta_v1.ObjectMeta{ @@ -116,8 +115,7 @@ var _ = BeforeSuite(func() { }, }, } - _, ok = f.CreateGatewayClassAndWaitFor(gcWithEnvoyDeployment, e2e.GatewayClassAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateGatewayClassAndWaitFor(gcWithEnvoyDeployment, e2e.GatewayClassAccepted)) }) var _ = AfterSuite(func() { @@ -180,8 +178,7 @@ var _ = Describe("Gateway provisioner", func() { }, }, } - _, ok := f.CreateGatewayClassAndWaitFor(gatewayClass, e2e.GatewayClassNotAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateGatewayClassAndWaitFor(gatewayClass, e2e.GatewayClassNotAccepted)) // Create a Gateway using that GatewayClass, it should not be accepted // since the GatewayClass is not accepted. @@ -277,10 +274,9 @@ var _ = Describe("Gateway provisioner", func() { }, } - gateway, ok := f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { + require.True(f.T(), f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { return e2e.GatewayProgrammed(gw) && e2e.GatewayHasAddress(gw) - }) - require.True(f.T(), ok) + })) f.Fixtures.Echo.Deploy(namespace, "echo") @@ -304,8 +300,7 @@ var _ = Describe("Gateway provisioner", func() { }, }, } - _, ok = f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ OverrideURL: "http://" + net.JoinHostPort(gateway.Status.Addresses[0].Value, "80"), @@ -385,7 +380,7 @@ var _ = Describe("Gateway provisioner", func() { }, } - gateway, ok := f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { + require.True(f.T(), f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { if !(e2e.GatewayProgrammed(gw) && e2e.GatewayHasAddress(gw)) { return false } @@ -397,8 +392,7 @@ var _ = Describe("Gateway provisioner", func() { } return true - }) - require.True(f.T(), ok) + })) f.Fixtures.Echo.Deploy(namespace, "echo") @@ -422,8 +416,7 @@ var _ = Describe("Gateway provisioner", func() { }, }, } - _, ok = f.CreateHTTPRouteAndWaitFor(httpRoute, e2e.HTTPRouteAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(httpRoute, e2e.HTTPRouteAccepted)) for _, tc := range []struct { name string @@ -471,7 +464,7 @@ var _ = Describe("Gateway provisioner", func() { }, Spec: gatewayapi_v1alpha2.TCPRouteSpec{ CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + ParentRefs: []gatewayapi_v1.ParentReference{ { Namespace: ptr.To(gatewayapi_v1.Namespace(gateway.Namespace)), Name: gatewayapi_v1.ObjectName(gateway.Name), @@ -485,8 +478,7 @@ var _ = Describe("Gateway provisioner", func() { }, }, } - _, ok = f.CreateTCPRouteAndWaitFor(tcpRoute, e2e.TCPRouteAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateTCPRouteAndWaitFor(tcpRoute, e2e.TCPRouteAccepted)) for _, tc := range []struct { name string @@ -533,8 +525,7 @@ var _ = Describe("Gateway provisioner", func() { }, }, } - _, ok := f.CreateGatewayClassAndWaitFor(gatewayClass, e2e.GatewayClassNotAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateGatewayClassAndWaitFor(gatewayClass, e2e.GatewayClassNotAccepted)) // Now create the ContourDeployment to match the parametersRef. params := &contour_v1alpha1.ContourDeployment{ @@ -595,10 +586,10 @@ var _ = Describe("Gateway provisioner", func() { }, } - gateway, ok := f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { + require.True(f.T(), f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { return e2e.GatewayProgrammed(gw) && e2e.GatewayHasAddress(gw) - }) - require.True(f.T(), ok, fmt.Sprintf("gateway is %v", gateway)) + })) + type testObj struct { expectReconcile bool namespace string @@ -650,9 +641,8 @@ var _ = Describe("Gateway provisioner", func() { route.Spec.Hostnames = []gatewayapi_v1.Hostname{gatewayapi_v1.Hostname("provisioner.projectcontour.io." + t.namespace)} By(fmt.Sprintf("Expect namespace %s to be watched by contour", t.namespace)) - hr, ok := f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted) - By(fmt.Sprintf("Expect httproute under namespace %s is accepted", t.namespace)) - require.True(f.T(), ok, fmt.Sprintf("httproute is %v", hr)) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteAccepted)) + res, ok := f.HTTP.RequestUntil(&e2e.HTTPRequestOpts{ OverrideURL: "http://" + net.JoinHostPort(gateway.Status.Addresses[0].Value, "80"), Host: string(route.Spec.Hostnames[0]), @@ -668,17 +658,16 @@ var _ = Describe("Gateway provisioner", func() { } else { // Root proxy in non-watched namespace should fail By(fmt.Sprintf("Expect namespace %s not to be watched by contour", t.namespace)) - hr, ok := f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteIgnoredByContour) - require.True(f.T(), ok, fmt.Sprintf("httproute's is %v", hr)) + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(route, e2e.HTTPRouteIgnoredByContour)) By(fmt.Sprintf("Expect httproute under namespace %s is not accepted for a period of time", t.namespace)) require.Never(f.T(), func() bool { - hr = &gatewayapi_v1.HTTPRoute{} - if err := f.Client.Get(context.Background(), k8s.NamespacedNameOf(hr), hr); err != nil { + hr := &gatewayapi_v1.HTTPRoute{} + if err := f.Client.Get(context.Background(), k8s.NamespacedNameOf(route), hr); err != nil { return false } return e2e.HTTPRouteAccepted(hr) - }, 20*time.Second, time.Second, hr) + }, 20*time.Second, time.Second) } } }) @@ -701,8 +690,7 @@ var _ = Describe("Gateway provisioner", func() { }, }, } - _, ok := f.CreateGatewayClassAndWaitFor(gatewayClass, e2e.GatewayClassNotAccepted) - require.True(f.T(), ok) + require.True(f.T(), f.CreateGatewayClassAndWaitFor(gatewayClass, e2e.GatewayClassNotAccepted)) // Now create the ContourDeployment to match the parametersRef. params := &contour_v1alpha1.ContourDeployment{ @@ -763,10 +751,9 @@ var _ = Describe("Gateway provisioner", func() { }, } - gateway, ok := f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { + require.True(f.T(), f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { return e2e.GatewayProgrammed(gw) && e2e.GatewayHasAddress(gw) - }) - require.True(f.T(), ok, fmt.Sprintf("gateway is %v", gateway)) + })) By("Skip reconciling the TLSRoute if disabledFeatures includes it") f.Fixtures.EchoSecure.Deploy(namespace, "echo-secure", nil) @@ -776,12 +763,12 @@ var _ = Describe("Gateway provisioner", func() { Name: "tlsroute-1", }, Spec: gatewayapi_v1alpha2.TLSRouteSpec{ - Hostnames: []gatewayapi_v1alpha2.Hostname{"provisioner.projectcontour.io"}, + Hostnames: []gatewayapi_v1.Hostname{"provisioner.projectcontour.io"}, CommonRouteSpec: gatewayapi_v1.CommonRouteSpec{ - ParentRefs: []gatewayapi_v1alpha2.ParentReference{ + ParentRefs: []gatewayapi_v1.ParentReference{ { - Namespace: ptr.To(gatewayapi_v1alpha2.Namespace(gateway.Namespace)), - Name: gatewayapi_v1alpha2.ObjectName(gateway.Name), + Namespace: ptr.To(gatewayapi_v1.Namespace(gateway.Namespace)), + Name: gatewayapi_v1.ObjectName(gateway.Name), }, }, }, @@ -792,16 +779,16 @@ var _ = Describe("Gateway provisioner", func() { }, }, } - tr, ok := f.CreateTLSRouteAndWaitFor(route, e2e.TLSRouteIgnoredByContour) - require.True(f.T(), ok, fmt.Sprintf("tlsroute's is %v", tr)) + require.True(f.T(), f.CreateTLSRouteAndWaitFor(route, e2e.TLSRouteIgnoredByContour)) + By("Expect tlsroute not to be accepted") require.Never(f.T(), func() bool { - tr = &gatewayapi_v1alpha2.TLSRoute{} - if err := f.Client.Get(context.Background(), k8s.NamespacedNameOf(tr), tr); err != nil { + tr := &gatewayapi_v1alpha2.TLSRoute{} + if err := f.Client.Get(context.Background(), k8s.NamespacedNameOf(route), tr); err != nil { return false } return e2e.TLSRouteAccepted(tr) - }, 20*time.Second, time.Second, tr) + }, 20*time.Second, time.Second) }) }) }) diff --git a/test/e2e/upgrade/upgrade_test.go b/test/e2e/upgrade/upgrade_test.go index f9c86d03e9b..3f779df1ade 100644 --- a/test/e2e/upgrade/upgrade_test.go +++ b/test/e2e/upgrade/upgrade_test.go @@ -144,20 +144,16 @@ var _ = Describe("When upgrading", func() { cmd := exec.Command("../../scripts/install-provisioner-release.sh", contourUpgradeFromVersion) sess, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) require.NoError(f.T(), err) - Eventually(sess, f.RetryTimeout, f.RetryInterval).Should(gexec.Exit(0)) - gc, ok := f.CreateGatewayClassAndWaitFor(&gatewayapi_v1.GatewayClass{ + require.True(f.T(), f.CreateGatewayClassAndWaitFor(&gatewayapi_v1.GatewayClass{ ObjectMeta: meta_v1.ObjectMeta{ Name: gatewayClassName, }, Spec: gatewayapi_v1.GatewayClassSpec{ ControllerName: gatewayapi_v1.GatewayController("projectcontour.io/gateway-controller"), }, - }, e2e.GatewayClassAccepted) - - require.True(f.T(), ok) - require.NotNil(f.T(), gc) + }, e2e.GatewayClassAccepted)) }) AfterEach(func() { @@ -178,7 +174,7 @@ var _ = Describe("When upgrading", func() { appHost := "upgrade.provisioner.projectcontour.io" - gateway, ok := f.CreateGatewayAndWaitFor(&gatewayapi_v1.Gateway{ + gateway := &gatewayapi_v1.Gateway{ ObjectMeta: meta_v1.ObjectMeta{ Namespace: namespace, Name: "upgrade-gateway", @@ -194,17 +190,19 @@ var _ = Describe("When upgrading", func() { }, }, }, - }, func(gw *gatewayapi_v1.Gateway) bool { + } + + require.True(f.T(), f.CreateGatewayAndWaitFor(gateway, func(gw *gatewayapi_v1.Gateway) bool { return e2e.GatewayProgrammed(gw) && e2e.GatewayHasAddress(gw) - }) - require.True(t, ok) - require.NotNil(t, gateway) + })) + + require.NoError(f.T(), f.Client.Get(context.Background(), k8s.NamespacedNameOf(gateway), gateway)) f.HTTP.HTTPURLBase = "http://" + gateway.Status.Addresses[0].Value f.Fixtures.Echo.DeployN(namespace, "echo", 2) - f.CreateHTTPRouteAndWaitFor(&gatewayapi_v1.HTTPRoute{ + require.True(f.T(), f.CreateHTTPRouteAndWaitFor(&gatewayapi_v1.HTTPRoute{ ObjectMeta: meta_v1.ObjectMeta{ Namespace: namespace, Name: "echo", @@ -243,7 +241,7 @@ var _ = Describe("When upgrading", func() { }, }, }, - }, e2e.HTTPRouteAccepted) + }, e2e.HTTPRouteAccepted)) By("ensuring it is routable") checkRoutability(appHost) @@ -251,6 +249,20 @@ var _ = Describe("When upgrading", func() { poller, err := e2e.StartAppPoller(f.HTTP.HTTPURLBase, appHost, http.StatusOK, GinkgoWriter) require.NoError(f.T(), err) + By("updating gateway-api CRDs to latest") + // Delete existing BackendTLSPolicy CRD. + // TODO: remove this hack once BackendTLSPolicy v1alpha3 or + // above is available in multiple consecutive releases. + cmd := exec.Command("kubectl", "delete", "crd", "backendtlspolicies.gateway.networking.k8s.io") + sess, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + require.NoError(f.T(), err) + Eventually(sess, f.RetryTimeout, f.RetryInterval).Should(gexec.Exit(0)) + + cmd = exec.Command("kubectl", "apply", "-f", "../../../examples/gateway/00-crds.yaml") + sess, err = gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + require.NoError(f.T(), err) + Eventually(sess, f.RetryTimeout, f.RetryInterval).Should(gexec.Exit(0)) + By("deploying updated provisioner") require.NoError(f.T(), f.Provisioner.EnsureResourcesForInclusterProvisioner()) diff --git a/test/scripts/make-kind-cluster.sh b/test/scripts/make-kind-cluster.sh index e08da8cbee2..3731ffdba5f 100755 --- a/test/scripts/make-kind-cluster.sh +++ b/test/scripts/make-kind-cluster.sh @@ -27,7 +27,7 @@ readonly KUBECTL=${KUBECTL:-kubectl} readonly MULTINODE_CLUSTER=${MULTINODE_CLUSTER:-"false"} readonly IPV6_CLUSTER=${IPV6_CLUSTER:-"false"} readonly SKIP_GATEWAY_API_INSTALL=${SKIP_GATEWAY_API_INSTALL:-"false"} -readonly NODEIMAGE=${NODEIMAGE:-"kindest/node:v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245"} +readonly NODEIMAGE=${NODEIMAGE:-"kindest/node:v1.31.0@sha256:53df588e04085fd41ae12de0c3fe4c72f7013bba32a20e7325357a1ac94ba865"} readonly CLUSTERNAME=${CLUSTERNAME:-contour-e2e} readonly WAITTIME=${WAITTIME:-5m} diff --git a/test/scripts/run-gateway-conformance.sh b/test/scripts/run-gateway-conformance.sh index f8b54d995b6..bdf77b7bc2a 100755 --- a/test/scripts/run-gateway-conformance.sh +++ b/test/scripts/run-gateway-conformance.sh @@ -58,7 +58,7 @@ GO_MOD_GATEWAY_API_VERSION=$(grep "sigs.k8s.io/gateway-api" go.mod | awk '{print if [ "$GATEWAY_API_VERSION" = "$GO_MOD_GATEWAY_API_VERSION" ]; then go test -timeout=40m -tags conformance ./test/conformance/gatewayapi --gateway-class=contour -else +else cd $(mktemp -d) git clone https://github.com/kubernetes-sigs/gateway-api cd gateway-api @@ -67,5 +67,5 @@ else # test/conformance/gatewayapi/gateway_conformance_test.go. go test -timeout=40m ./conformance -run TestConformance -gateway-class=contour -all-features \ -exempt-features=Mesh \ - -skip-tests=HTTPRouteRedirectPortAndScheme,HTTPRouteTimeoutBackendRequest,GatewayStaticAddresses + -skip-tests=HTTPRouteRedirectPortAndScheme,GatewayStaticAddresses fi diff --git a/versions.yaml b/versions.yaml index 6c933d858f6..bb309987206 100644 --- a/versions.yaml +++ b/versions.yaml @@ -7,15 +7,95 @@ versions: - version: main supported: "false" dependencies: - envoy: "1.29.2" + envoy: "1.32.0" + kubernetes: + - "1.30" + - "1.29" + - "1.28" + gateway-api: + - "1.1.0" + - version: v1.30.0 + supported: "true" + dependencies: + envoy: "1.31.0" + kubernetes: + - "1.30" + - "1.29" + - "1.28" + gateway-api: + - "1.1.0" + - version: v1.29.2 + supported: "true" + dependencies: + envoy: "1.30.4" kubernetes: - "1.29" - "1.28" - "1.27" gateway-api: - "1.0.0" - - version: v1.28.2 + - version: v1.29.1 + supported: "false" + dependencies: + envoy: "1.30.2" + kubernetes: + - "1.29" + - "1.28" + - "1.27" + gateway-api: + - "1.0.0" + - version: v1.29.0 + supported: "false" + dependencies: + envoy: "1.30.1" + kubernetes: + - "1.29" + - "1.28" + - "1.27" + gateway-api: + - "1.0.0" + - version: v1.28.6 supported: "true" + dependencies: + envoy: "1.29.7" + kubernetes: + - "1.29" + - "1.28" + - "1.27" + gateway-api: + - "1.0.0" + - version: v1.28.5 + supported: "false" + dependencies: + envoy: "1.29.5" + kubernetes: + - "1.29" + - "1.28" + - "1.27" + gateway-api: + - "1.0.0" + - version: v1.28.4 + supported: "false" + dependencies: + envoy: "1.29.4" + kubernetes: + - "1.29" + - "1.28" + - "1.27" + gateway-api: + - "1.0.0" + - version: v1.28.3 + supported: "false" + dependencies: + envoy: "1.29.3" + kubernetes: + - "1.29" + - "1.28" + - "1.27" + gateway-api: + - "1.0.0" + - version: v1.28.2 + supported: "false" dependencies: envoy: "1.29.2" kubernetes: @@ -44,8 +124,38 @@ versions: - "1.27" gateway-api: - "1.0.0" + - version: v1.27.4 + supported: "false" + dependencies: + envoy: "1.28.4" + kubernetes: + - "1.28" + - "1.27" + - "1.26" + gateway-api: + - "0.8.1" + - version: v1.27.3 + supported: "false" + dependencies: + envoy: "1.28.3" + kubernetes: + - "1.28" + - "1.27" + - "1.26" + gateway-api: + - "0.8.1" + - version: v1.27.2 + supported: "false" + dependencies: + envoy: "1.28.2" + kubernetes: + - "1.28" + - "1.27" + - "1.26" + gateway-api: + - "0.8.1" - version: v1.27.1 - supported: "true" + supported: "false" dependencies: envoy: "1.28.1" kubernetes: @@ -64,8 +174,18 @@ versions: - "1.26" gateway-api: - "0.8.1" + - version: v1.26.3 + supported: "false" + dependencies: + envoy: "1.27.4" + kubernetes: + - "1.28" + - "1.27" + - "1.26" + gateway-api: + - "0.8.1" - version: v1.26.2 - supported: "true" + supported: "false" dependencies: envoy: "1.27.3" kubernetes: @@ -706,4 +826,3 @@ versions: gateway-api: - NA contour-operator: NA -