diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 677037e699a..00000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,166 +0,0 @@ -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: -# main branch targets -- target-branch: main - package-ecosystem: "gomod" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - labels: - - area/dependency - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - k8s-dependencies: - patterns: - - "k8s.io/*" -- target-branch: main - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - labels: - - area/tooling - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - artifact-actions: - patterns: - - "actions/upload-artifact" - - "actions/download-artifact" - -# release branch N targets -- target-branch: release-1.30 - package-ecosystem: "gomod" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - ignore: - - dependency-name: "*" - update-types: - - "version-update:semver-major" - - "version-update:semver-minor" - labels: - - area/dependency - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - k8s-dependencies: - patterns: - - "k8s.io/*" -- target-branch: release-1.30 - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - ignore: - - dependency-name: "*" - update-types: - - "version-update:semver-major" - - "version-update:semver-minor" - labels: - - area/tooling - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - artifact-actions: - patterns: - - "actions/upload-artifact" - - "actions/download-artifact" - -# release branch N-1 targets -- target-branch: release-1.29 - package-ecosystem: "gomod" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - ignore: - - dependency-name: "*" - update-types: - - "version-update:semver-major" - - "version-update:semver-minor" - labels: - - area/dependency - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - k8s-dependencies: - patterns: - - "k8s.io/*" -- target-branch: release-1.29 - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - ignore: - - dependency-name: "*" - update-types: - - "version-update:semver-major" - - "version-update:semver-minor" - labels: - - area/tooling - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - artifact-actions: - patterns: - - "actions/upload-artifact" - - "actions/download-artifact" - -# release branch N-2 targets -- target-branch: release-1.28 - package-ecosystem: "gomod" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - ignore: - - dependency-name: "*" - update-types: - - "version-update:semver-major" - - "version-update:semver-minor" - labels: - - area/dependency - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - k8s-dependencies: - patterns: - - "k8s.io/*" -- target-branch: release-1.28 - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - day: "sunday" - ignore: - - dependency-name: "*" - update-types: - - "version-update:semver-major" - - "version-update:semver-minor" - labels: - - area/tooling - - release-note/none-required - reviewers: - - projectcontour/maintainers - groups: - artifact-actions: - patterns: - - "actions/upload-artifact" - - "actions/download-artifact" diff --git a/.github/reviewers.yaml b/.github/reviewers.yaml deleted file mode 100644 index a42a3554aea..00000000000 --- a/.github/reviewers.yaml +++ /dev/null @@ -1,7 +0,0 @@ -reviewers: - defaults: - - team:contour-reviewers - -options: - ignore_draft: true - number_of_reviewers: 1 diff --git a/.github/workflows/build_daily.yaml b/.github/workflows/build_daily.yaml deleted file mode 100644 index e98ff77a068..00000000000 --- a/.github/workflows/build_daily.yaml +++ /dev/null @@ -1,140 +0,0 @@ -name: Daily build - -on: - # Run every day - schedule: - - cron: '0 12 * * *' - # Allow manual runs - workflow_dispatch: - -permissions: - contents: read - -env: - GOPROXY: https://proxy.golang.org/ - GO_VERSION: 1.23.2 - -jobs: - e2e-contour-xds: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - # * Module download cache - # * Build cache (Linux) - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - - name: add deps to path - run: | - ./hack/actions/install-kubernetes-toolchain.sh $GITHUB_WORKSPACE/bin - echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - - name: e2e tests - env: - CONTOUR_E2E_IMAGE: ghcr.io/projectcontour/contour:main - CONTOUR_E2E_XDS_SERVER_TYPE: contour - run: | - make setup-kind-cluster run-e2e cleanup-kind - e2e-envoy-deployment: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - # * Module download cache - # * Build cache (Linux) - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - - name: add deps to path - run: | - ./hack/actions/install-kubernetes-toolchain.sh $GITHUB_WORKSPACE/bin - echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - - name: e2e tests - env: - CONTOUR_E2E_IMAGE: ghcr.io/projectcontour/contour:main - CONTOUR_E2E_ENVOY_DEPLOYMENT_MODE: deployment - run: | - make setup-kind-cluster run-e2e cleanup-kind - e2e-ipv6: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - # * Module download cache - # * Build cache (Linux) - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - - name: add deps to path - run: | - ./hack/actions/install-kubernetes-toolchain.sh $GITHUB_WORKSPACE/bin - echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - - name: e2e tests - env: - CONTOUR_E2E_IMAGE: ghcr.io/projectcontour/contour:main - IPV6_CLUSTER: "true" - run: | - # Set up cluster to ensure we have a docker bridge network to find a non-local ip from. - make setup-kind-cluster - export CONTOUR_E2E_LOCAL_HOST=$(ifconfig | grep inet6 | grep global | head -n1 | awk '{print $2}') - make run-e2e cleanup-kind - e2e-endpoints: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - # * Module download cache - # * Build cache (Linux) - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - - name: add deps to path - run: | - ./hack/actions/install-kubernetes-toolchain.sh $GITHUB_WORKSPACE/bin - echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - - name: e2e tests - env: - CONTOUR_E2E_IMAGE: ghcr.io/projectcontour/contour:main - CONTOUR_E2E_USE_ENDPOINTS: true - run: | - make setup-kind-cluster run-e2e cleanup-kind diff --git a/.github/workflows/build_main.yaml b/.github/workflows/build_main.yaml deleted file mode 100644 index ecf0917579d..00000000000 --- a/.github/workflows/build_main.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build and push :main image - -on: - push: - branches: - - main - -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-latest - permissions: - packages: write - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - with: - version: latest - - name: Log in to GHCR - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and Push to GHCR - env: - REGISTRY: ghcr.io/${{ github.repository_owner }} - VERSION: main - TAG_LATEST: "false" - PUSH_IMAGE: "true" - run: | - make multiarch-build diff --git a/.github/workflows/build_tag.yaml b/.github/workflows/build_tag.yaml deleted file mode 100644 index 78385ee471b..00000000000 --- a/.github/workflows/build_tag.yaml +++ /dev/null @@ -1,83 +0,0 @@ -name: Build and push a release - -on: - push: - tags: - # Although these *look* like regex matches, they're not! - # They are Go path.Match() expressions. - # See https://golang.org/pkg/path/#Match for details. - - 'v[0-9]*.[0-9]*.[0-9]' - - 'v[0-9]*.[0-9]*.[0-9][0-9]' - - 'v[0-9]*.[0-9]*.[0-9][0-9][0-9]' - - 'v[0-9]*.[0-9]*.[0-9]*beta*' - - 'v[0-9]*.[0-9]*.[0-9]*alpha*' - - 'v[0-9]*.[0-9]*.[0-9]*rc*' - -permissions: - contents: read - -env: - GOPROXY: https://proxy.golang.org/ - GO_VERSION: 1.23.2 - -jobs: - build: - runs-on: ubuntu-latest - permissions: - packages: write - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - with: - version: latest - - name: Log in to GHCR - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and Push to GHCR - env: - REGISTRY: ghcr.io/${{ github.repository_owner }} - TAG_LATEST: "false" - run: | - ./hack/actions/build-and-push-release-images.sh - gateway-conformance-report: - runs-on: ubuntu-latest - needs: [build] - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - # * Module download cache - # * Build cache (Linux) - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 - with: - go-version: ${{ env.GO_VERSION }} - cache: false - - name: add deps to path - run: | - ./hack/actions/install-kubernetes-toolchain.sh $GITHUB_WORKSPACE/bin - echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - - name: Gateway API conformance tests - env: - GENERATE_GATEWAY_CONFORMANCE_REPORT: "true" - run: | - 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@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: gateway-conformance-report - path: gateway-conformance-report/projectcontour-contour-*.yaml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 0593983143f..00000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: "Code scanning - action" - -on: - push: - branches: [main] - pull_request: - # The branches below must be a subset of the branches above - branches: [main] - schedule: - - cron: '0 10 * * 1' - -permissions: - contents: read - -env: - GOPROXY: https://proxy.golang.org/ - GO_VERSION: 1.23.2 - -jobs: - CodeQL-Build: - runs-on: ubuntu-latest - permissions: - security-events: write - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - # * Module download cache - # * Build cache (Linux) - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}-go- - - 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@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6 - with: - languages: go - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - - name: Autobuild - uses: github/codeql-action/autobuild@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6 - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6 diff --git a/.github/workflows/label_check.yaml b/.github/workflows/label_check.yaml deleted file mode 100644 index 4a65be13857..00000000000 --- a/.github/workflows/label_check.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: Release Note Label Check - -# Trigger the workflow on pull requests only -on: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - branches: [main] - -permissions: - contents: read - -env: - GOPROXY: https://proxy.golang.org/ - -jobs: - # Ensures correct release-note labels are set: - # - At least one label - # - At most one of the main category labels - # - A deprecation label alone or with something other than "none-required" - # Ensures you can have a change that is just a deprecation, or include a - # deprecation with another release note. - check-label: - name: Check release-note label set - runs-on: ubuntu-latest - steps: - - uses: mheap/github-action-required-labels@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5.5 - 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@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5.5 - 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@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5.5 - with: - mode: maximum - count: 1 - labels: "release-note/deprecation, release-note/none-required" - check-changelog: - name: Check for changelog file - needs: [check-label] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - # * Module download cache - # * Build cache (Linux) - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-${{ github.job }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-${{ github.job }}-go- - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 - with: - go-version: 'stable' - cache: false - - run: go run ./hack/actions/check-changefile-exists.go - env: - PR_NUMBER: ${{ github.event.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/openssf-scorecard.yaml b/.github/workflows/openssf-scorecard.yaml deleted file mode 100644 index 7d20d2b8f20..00000000000 --- a/.github/workflows/openssf-scorecard.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: OpenSSF Scorecard - -on: - branch_protection_rule: - # Run weekly - schedule: - - cron: '0 12 * * 1' - push: - branches: - - "main" - # Allow manual runs - workflow_dispatch: - -permissions: - contents: read - -jobs: - analysis: - name: Scorecard analysis - runs-on: ubuntu-latest - permissions: - security-events: write - id-token: write - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - - name: "Run analysis" - 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@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: SARIF file - path: results.sarif - - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6 - with: - sarif_file: results.sarif diff --git a/.github/workflows/request-reviews.yaml b/.github/workflows/request-reviews.yaml deleted file mode 100644 index 467d23c7d73..00000000000 --- a/.github/workflows/request-reviews.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Request Reviews - -on: - pull_request_target: - types: [opened, ready_for_review, reopened] - -permissions: - contents: read - -jobs: - request-reviews: - runs-on: ubuntu-latest - steps: - - uses: necojackarc/auto-request-review@e89da1a8cd7c8c16d9de9c6e763290b6b0e3d424 # v0.13.0 - with: - token: ${{ secrets.PAT_FOR_AUTO_REQUEST_REVIEW }} - config: .github/reviewers.yaml diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml deleted file mode 100644 index 4ac20ef2668..00000000000 --- a/.github/workflows/stale.yaml +++ /dev/null @@ -1,92 +0,0 @@ -# Stale issue and PR management -# See https://github.com/marketplace/actions/close-stale-issues - -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0 * * *" - -permissions: - contents: read - -jobs: - stale: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - exempt-all-milestones: true - days-before-pr-stale: 14 - days-before-pr-close: 30 - stale-pr-label: 'lifecycle/stale' - stale-pr-message: | - The Contour project currently lacks enough contributors to adequately respond to all PRs. - - This bot triages PRs according to the following rules: - - - After 14d of inactivity, lifecycle/stale is applied - - After 30d of inactivity since lifecycle/stale was applied, the PR is closed - - You can: - - - *Ensure your PR is passing all CI checks.* PRs that are fully green are more likely to be reviewed. If you are having trouble with CI checks, reach out to the #contour channel in the Kubernetes Slack workspace. - - Mark this PR as fresh by commenting or pushing a commit - - Close this PR - - Offer to help out with triage - - Please send feedback to the #contour channel in the Kubernetes Slack - close-pr-message: | - The Contour project currently lacks enough contributors to adequately respond to all PRs. - - This bot triages PRs according to the following rules: - - - After 14d of inactivity, lifecycle/stale is applied - - After 30d of inactivity since lifecycle/stale was applied, the PR is closed - - You can: - - - *Ensure your PR is passing all CI checks.* PRs that are fully green are more likely to be reviewed. If you are having trouble with CI checks, reach out to the #contour channel in the Kubernetes Slack workspace. - - Mark this PR as fresh by commenting or pushing a commit - - Close this PR - - Offer to help out with triage - - Please send feedback to the #contour channel in the Kubernetes Slack - days-before-issue-stale: 60 - days-before-issue-close: 30 - stale-issue-label: 'lifecycle/stale' - exempt-issue-labels: 'help wanted,good first issue,priority/important-soon,kind/flake' - stale-issue-message: | - The Contour project currently lacks enough contributors to adequately respond to all Issues. - - This bot triages Issues according to the following rules: - - - After 60d of inactivity, lifecycle/stale is applied - - After 30d of inactivity since lifecycle/stale was applied, the Issue is closed - - You can: - - - Mark this Issue as fresh by commenting - - Close this Issue - - Offer to help out with triage - - Please send feedback to the #contour channel in the Kubernetes Slack - close-issue-message: | - The Contour project currently lacks enough contributors to adequately respond to all Issues. - - This bot triages Issues according to the following rules: - - - After 60d of inactivity, lifecycle/stale is applied - - After 30d of inactivity since lifecycle/stale was applied, the Issue is closed - - You can: - - - Mark this Issue as fresh by commenting - - Close this Issue - - Offer to help out with triage - - Please send feedback to the #contour channel in the Kubernetes Slack diff --git a/.github/workflows/trivy-scan.yaml b/.github/workflows/trivy-scan.yaml deleted file mode 100644 index 732aad1e486..00000000000 --- a/.github/workflows/trivy-scan.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: Trivy Scan - -on: - # Run weekly - schedule: - - cron: '0 12 * * 1' - # Allow manual runs - workflow_dispatch: - -permissions: - contents: read - -jobs: - trivy-scan: - strategy: - matrix: - branch: - - main - - release-1.30 - - release-1.29 - - release-1.28 - runs-on: ubuntu-latest - permissions: - security-events: write - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: false - ref: ${{ matrix.branch }} - - uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0 # 0.29.0 - with: - scanners: vuln - scan-type: 'fs' - format: 'sarif' - output: 'trivy-results.sarif' - ignore-unfixed: true - severity: 'HIGH,CRITICAL' - - uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6 - with: - sarif_file: 'trivy-results.sarif' diff --git a/.github/workflows/welcome-new-contributors.yaml b/.github/workflows/welcome-new-contributors.yaml deleted file mode 100644 index 4e9fb0d5c5c..00000000000 --- a/.github/workflows/welcome-new-contributors.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: 'Welcome New Contributors' - -on: - issues: - types: [opened] - # Workloads with pull_request_target and the GitHub Token secret should never include executing untrusted code - # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target - # And https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ - pull_request_target: - types: [opened] - -permissions: - contents: read - -jobs: - welcome-new-contributor: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - name: 'Greet the contributor' - uses: garg3133/welcome-new-contributors@a38583ed8282e23d63d7bf919ca2d9fb95300ca6 # v1.2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - issue-message: > - Hey @contributor_name! Thanks for opening your first issue. We appreciate your contribution and welcome you to our community! - We are glad to have you here and to have your input on Contour. - You can also join us on [our mailing list](https://groups.google.com/g/project-contour) and [in our channel](https://kubernetes.slack.com/archives/C8XRH2R4J) - in the [Kubernetes Slack Workspace](https://communityinviter.com/apps/kubernetes/community) - pr-message: > - Hi @contributor_name! Welcome to our community and thank you for opening your first Pull Request. - Someone will review it soon. Thank you for committing to making Contour better. - You can also join us on [our mailing list](https://groups.google.com/g/project-contour) and [in our channel](https://kubernetes.slack.com/archives/C8XRH2R4J) - in the [Kubernetes Slack Workspace](https://communityinviter.com/apps/kubernetes/community) diff --git a/apis/projectcontour/v1/httpproxy.go b/apis/projectcontour/v1/httpproxy.go index 1978f8667f1..c16a20bf577 100644 --- a/apis/projectcontour/v1/httpproxy.go +++ b/apis/projectcontour/v1/httpproxy.go @@ -18,6 +18,10 @@ import ( meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// HTTPVersion is an alias to enforce validation +// +kubebuilder:validation:Enum=h2;http/1.1 +type HTTPVersion string + // HTTPProxySpec defines the spec of the CRD. type HTTPProxySpec struct { // Virtualhost appears at most once. If it is present, the object is considered @@ -40,6 +44,11 @@ type HTTPProxySpec struct { // is given precedence over this field. // +optional IngressClassName string `json:"ingressClassName,omitempty"` + + // HTTPVersions specify the http versions to offer for this HTTPProxy. + // If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. + // It is ignored when TCPProxy is set. + HTTPVersions []HTTPVersion `json:"httpVersions,omitempty"` } // Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label. @@ -239,6 +248,14 @@ type ExtensionServiceReference struct { Name string `json:"name,omitempty" protobuf:"bytes,3,opt,name=name"` } +// AuthorizationServiceAPIType is an alias to enforce validation +type AuthorizationServiceAPIType string + +const ( + AuthorizationGRPCService AuthorizationServiceAPIType = "grpc" + AuthorizationHTTPService AuthorizationServiceAPIType = "http" +) + // 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). @@ -248,6 +265,20 @@ type AuthorizationServer struct { // +optional ExtensionServiceRef ExtensionServiceReference `json:"extensionRef,omitempty"` + // ServiceAPIType defines the external authorization service API type. + // It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + // or a gRPC authorization server. + // + // +optional + // +kubebuilder:validation:Enum=http;grpc + // +kubebuilder:default=grpc + ServiceAPIType AuthorizationServiceAPIType `json:"serviceAPIType,omitempty"` + + // HTTPServerSettings defines configurations for interacting with an external HTTP authorization server. + // + // +optional + HTTPServerSettings *HTTPAuthorizationServerSettings `json:"httpSettings,omitempty"` + // AuthPolicy sets a default authorization policy for client requests. // This policy will be used unless overridden by individual routes. // @@ -276,6 +307,75 @@ type AuthorizationServer struct { WithRequestBody *AuthorizationServerBufferSettings `json:"withRequestBody,omitempty"` } +// HTTPAuthorizationServerSettings defines configurations for interacting with an external HTTP authorization server. +type HTTPAuthorizationServerSettings struct { + // PathPrefix Sets a prefix to the value of authorization request header Path. + // + // +optional + PathPrefix string `json:"pathPrefix,omitempty"` + + // Note: This field is not used by Envoy + // https://github.com/envoyproxy/envoy/issues/5357 + // + // ServerURI sets the URI of the external HTTP authorization server to which authorization requests must be sent. + // + // // +required + // // +kubebuilder:validation:Pattern=`^https?://[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*(\/[^\s]*)?$` + // ServerURI string `json:"serverURI"` + + // AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + // Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + // + // +optional + AllowedAuthorizationHeaders []HTTPAuthorizationServerAllowedHeaders `json:"allowedAuthorizationHeaders,omitempty"` + + // AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + // Note that coexistent headers will be overridden. + // + // +optional + AllowedUpstreamHeaders []HTTPAuthorizationServerAllowedHeaders `json:"allowedUpstreamHeaders,omitempty"` +} + +// HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers +// in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, +// Contains, and IgnoreCase to customize header matching criteria. However, regex support +// is intentionally excluded to simplify the user experience and prevent potential issues. +// One of Prefix, Exact, Suffix or Contains must be provided. +type HTTPAuthorizationServerAllowedHeaders struct { + // Exact specifies a string that the header name must be equal to. + // + // +optional + Exact string `json:"exact,omitempty"` + + // Prefix defines a prefix match for the header name. + // + // +optional + Prefix string `json:"prefix,omitempty"` + + // Suffix defines a suffix match for a header name. + // + // +optional + Suffix string `json:"suffix,omitempty"` + + // To streamline user experience and mitigate potential issues, we do not support regex. + // Additionally, it's essential to ensure that any regex patterns adhere to the configured runtime key, re2.max_program_size.error_level + // by verifying that the program size is smaller than the specified value. + // This necessitates thorough validation of user input. + // + // Regex string `json:"regex,omitempty"` + + // Contains specifies a substring that must be present in the header name. + // + // +optional + Contains string `json:"contains,omitempty"` + + // IgnoreCase specifies that string matching should be case insensitive. + // Note that this has no effect on the Regex parameter. + // + // +optional + IgnoreCase bool `json:"ignoreCase,omitempty"` +} + // AuthorizationServerBufferSettings enables ExtAuthz filter to buffer client request data and send it as part of authorization request type AuthorizationServerBufferSettings struct { // MaxRequestBytes sets the maximum size of message body ExtAuthz filter will hold in-memory. diff --git a/apis/projectcontour/v1/zz_generated.deepcopy.go b/apis/projectcontour/v1/zz_generated.deepcopy.go index 3207fef641a..776c46e0264 100644 --- a/apis/projectcontour/v1/zz_generated.deepcopy.go +++ b/apis/projectcontour/v1/zz_generated.deepcopy.go @@ -50,6 +50,11 @@ func (in *AuthorizationPolicy) DeepCopy() *AuthorizationPolicy { func (in *AuthorizationServer) DeepCopyInto(out *AuthorizationServer) { *out = *in out.ExtensionServiceRef = in.ExtensionServiceRef + if in.HTTPServerSettings != nil { + in, out := &in.HTTPServerSettings, &out.HTTPServerSettings + *out = new(HTTPAuthorizationServerSettings) + (*in).DeepCopyInto(*out) + } if in.AuthPolicy != nil { in, out := &in.AuthPolicy, &out.AuthPolicy *out = new(AuthorizationPolicy) @@ -320,6 +325,46 @@ func (in *GlobalRateLimitPolicy) DeepCopy() *GlobalRateLimitPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPAuthorizationServerAllowedHeaders) DeepCopyInto(out *HTTPAuthorizationServerAllowedHeaders) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPAuthorizationServerAllowedHeaders. +func (in *HTTPAuthorizationServerAllowedHeaders) DeepCopy() *HTTPAuthorizationServerAllowedHeaders { + if in == nil { + return nil + } + out := new(HTTPAuthorizationServerAllowedHeaders) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPAuthorizationServerSettings) DeepCopyInto(out *HTTPAuthorizationServerSettings) { + *out = *in + if in.AllowedAuthorizationHeaders != nil { + in, out := &in.AllowedAuthorizationHeaders, &out.AllowedAuthorizationHeaders + *out = make([]HTTPAuthorizationServerAllowedHeaders, len(*in)) + copy(*out, *in) + } + if in.AllowedUpstreamHeaders != nil { + in, out := &in.AllowedUpstreamHeaders, &out.AllowedUpstreamHeaders + *out = make([]HTTPAuthorizationServerAllowedHeaders, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPAuthorizationServerSettings. +func (in *HTTPAuthorizationServerSettings) DeepCopy() *HTTPAuthorizationServerSettings { + if in == nil { + return nil + } + out := new(HTTPAuthorizationServerSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPDirectResponsePolicy) DeepCopyInto(out *HTTPDirectResponsePolicy) { *out = *in @@ -461,6 +506,11 @@ func (in *HTTPProxySpec) DeepCopyInto(out *HTTPProxySpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.HTTPVersions != nil { + in, out := &in.HTTPVersions, &out.HTTPVersions + *out = make([]HTTPVersion, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPProxySpec. diff --git a/apis/projectcontour/v1alpha1/contourconfig.go b/apis/projectcontour/v1alpha1/contourconfig.go index 0af7a50e08a..cac2bf35627 100644 --- a/apis/projectcontour/v1alpha1/contourconfig.go +++ b/apis/projectcontour/v1alpha1/contourconfig.go @@ -82,7 +82,7 @@ type ContourConfigurationSpec struct { // +optional Metrics *MetricsConfig `json:"metrics,omitempty"` - // Tracing defines properties for exporting trace data to OpenTelemetry. + // Tracing defines properties for exporting trace data to the OpenTelemetry. Tracing *TracingConfig `json:"tracing,omitempty"` // FeatureFlags defines toggle to enable new contour features. @@ -323,6 +323,10 @@ type EnvoyConfig struct { // Network holds various configurable Envoy network values. // +optional Network *NetworkParameters `json:"network,omitempty"` + + // Set StatPrefix on envoy routes + // +optional + EnableStatPrefix *bool `json:"enableStatPrefix"` } // DebugConfig contains Contour specific troubleshooting options. @@ -441,6 +445,13 @@ type EnvoyListenerConfig struct { // +kubebuilder:validation:Minimum=1 // +optional MaxConnectionsPerListener *uint32 `json:"maxConnectionsPerListener,omitempty"` + + // MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + // connections Envoy will accept per socket event. + // + // +kubebuilder:validation:Minimum=1 + // +optional + MaxConnectionsToAcceptPerSocketEvent *uint32 `json:"maxConnectionsToAcceptPerSocketEvent,omitempty"` } // SocketOptions defines configurable socket options for Envoy listeners. diff --git a/apis/projectcontour/v1alpha1/contourconfig_helpers.go b/apis/projectcontour/v1alpha1/contourconfig_helpers.go index 4969279bc65..0603a2281f5 100644 --- a/apis/projectcontour/v1alpha1/contourconfig_helpers.go +++ b/apis/projectcontour/v1alpha1/contourconfig_helpers.go @@ -97,6 +97,7 @@ func (t *TracingConfig) Validate() error { } customTagNames = append(customTagNames, customTag.TagName) } + return nil } diff --git a/apis/projectcontour/v1alpha1/extensionservice.go b/apis/projectcontour/v1alpha1/extensionservice.go index c074de546e7..c936f98c786 100644 --- a/apis/projectcontour/v1alpha1/extensionservice.go +++ b/apis/projectcontour/v1alpha1/extensionservice.go @@ -62,7 +62,7 @@ type ExtensionServiceTarget struct { // ExtensionServiceSpec defines the desired state of an ExtensionService resource. type ExtensionServiceSpec struct { // Services specifies the set of Kubernetes Service resources that - // receive GRPC extension API requests. + // receive 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. @@ -78,15 +78,15 @@ type ExtensionServiceSpec struct { UpstreamValidation *contour_v1.UpstreamValidation `json:"validation,omitempty"` // 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. + // Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations. // // +optional - // +kubebuilder:validation:Enum=h2;h2c + // +kubebuilder:validation:Enum=http/1.1;h2;h2c Protocol *string `json:"protocol,omitempty"` - // The policy for load balancing GRPC service requests. Note that the + // The policy for load balancing service requests. Note that the // `Cookie` and `RequestHash` load balancing strategies cannot be used - // here. + // here for GRPC service requests. // // +optional LoadBalancerPolicy *contour_v1.LoadBalancerPolicy `json:"loadBalancerPolicy,omitempty"` diff --git a/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go b/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go index ba974b98aa0..048a838d160 100644 --- a/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go +++ b/apis/projectcontour/v1alpha1/zz_generated.deepcopy.go @@ -557,6 +557,11 @@ func (in *EnvoyConfig) DeepCopyInto(out *EnvoyConfig) { *out = new(NetworkParameters) (*in).DeepCopyInto(*out) } + if in.EnableStatPrefix != nil { + in, out := &in.EnableStatPrefix, &out.EnableStatPrefix + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyConfig. @@ -637,6 +642,11 @@ func (in *EnvoyListenerConfig) DeepCopyInto(out *EnvoyListenerConfig) { *out = new(uint32) **out = **in } + if in.MaxConnectionsToAcceptPerSocketEvent != nil { + in, out := &in.MaxConnectionsToAcceptPerSocketEvent, &out.MaxConnectionsToAcceptPerSocketEvent + *out = new(uint32) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyListenerConfig. diff --git a/changelogs/unreleased/5535-therealak12-small.md b/changelogs/unreleased/5535-therealak12-small.md new file mode 100644 index 00000000000..54be51bbdb6 --- /dev/null +++ b/changelogs/unreleased/5535-therealak12-small.md @@ -0,0 +1 @@ +Adds `stat_prefix` support. if `envoy.enableStatPrefix` configuration is true, contour will automatically set `stat_prefix` on each route. diff --git a/changelogs/unreleased/5802-therealak12-small.md b/changelogs/unreleased/5802-therealak12-small.md new file mode 100644 index 00000000000..43fadbe9fbe --- /dev/null +++ b/changelogs/unreleased/5802-therealak12-small.md @@ -0,0 +1 @@ +Adds HTTPVersions field to HTTPProxy spec. The field is used to specify ALPNProtocols on the corresponding tls context. diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go index 1c48f9fce88..abb801f96fe 100644 --- a/cmd/contour/serve.go +++ b/cmd/contour/serve.go @@ -447,28 +447,29 @@ func (s *Server) doServe() error { } listenerConfig := xdscache_v3.ListenerConfig{ - UseProxyProto: *contourConfiguration.Envoy.Listener.UseProxyProto, - HTTPAccessLog: contourConfiguration.Envoy.HTTPListener.AccessLog, - HTTPSAccessLog: contourConfiguration.Envoy.HTTPSListener.AccessLog, - AccessLogType: contourConfiguration.Envoy.Logging.AccessLogFormat, - AccessLogJSONFields: contourConfiguration.Envoy.Logging.AccessLogJSONFields, - AccessLogLevel: contourConfiguration.Envoy.Logging.AccessLogLevel, - AccessLogFormatString: contourConfiguration.Envoy.Logging.AccessLogFormatString, - AccessLogFormatterExtensions: contourConfiguration.Envoy.Logging.AccessLogFormatterExtensions(), - MinimumTLSVersion: annotation.TLSVersion(contourConfiguration.Envoy.Listener.TLS.MinimumProtocolVersion, "1.2"), - MaximumTLSVersion: annotation.TLSVersion(contourConfiguration.Envoy.Listener.TLS.MaximumProtocolVersion, "1.3"), - CipherSuites: contourConfiguration.Envoy.Listener.TLS.SanitizedCipherSuites(), - Timeouts: timeouts, - DefaultHTTPVersions: parseDefaultHTTPVersions(contourConfiguration.Envoy.DefaultHTTPVersions), - AllowChunkedLength: !*contourConfiguration.Envoy.Listener.DisableAllowChunkedLength, - MergeSlashes: !*contourConfiguration.Envoy.Listener.DisableMergeSlashes, - ServerHeaderTransformation: contourConfiguration.Envoy.Listener.ServerHeaderTransformation, - XffNumTrustedHops: *contourConfiguration.Envoy.Network.XffNumTrustedHops, - ConnectionBalancer: contourConfiguration.Envoy.Listener.ConnectionBalancer, - MaxRequestsPerConnection: contourConfiguration.Envoy.Listener.MaxRequestsPerConnection, - HTTP2MaxConcurrentStreams: contourConfiguration.Envoy.Listener.HTTP2MaxConcurrentStreams, - PerConnectionBufferLimitBytes: contourConfiguration.Envoy.Listener.PerConnectionBufferLimitBytes, - SocketOptions: contourConfiguration.Envoy.Listener.SocketOptions, + UseProxyProto: *contourConfiguration.Envoy.Listener.UseProxyProto, + HTTPAccessLog: contourConfiguration.Envoy.HTTPListener.AccessLog, + HTTPSAccessLog: contourConfiguration.Envoy.HTTPSListener.AccessLog, + AccessLogType: contourConfiguration.Envoy.Logging.AccessLogFormat, + AccessLogJSONFields: contourConfiguration.Envoy.Logging.AccessLogJSONFields, + AccessLogLevel: contourConfiguration.Envoy.Logging.AccessLogLevel, + AccessLogFormatString: contourConfiguration.Envoy.Logging.AccessLogFormatString, + AccessLogFormatterExtensions: contourConfiguration.Envoy.Logging.AccessLogFormatterExtensions(), + MinimumTLSVersion: annotation.TLSVersion(contourConfiguration.Envoy.Listener.TLS.MinimumProtocolVersion, "1.2"), + MaximumTLSVersion: annotation.TLSVersion(contourConfiguration.Envoy.Listener.TLS.MaximumProtocolVersion, "1.3"), + CipherSuites: contourConfiguration.Envoy.Listener.TLS.SanitizedCipherSuites(), + Timeouts: timeouts, + DefaultHTTPVersions: parseDefaultHTTPVersions(contourConfiguration.Envoy.DefaultHTTPVersions), + AllowChunkedLength: !*contourConfiguration.Envoy.Listener.DisableAllowChunkedLength, + MergeSlashes: !*contourConfiguration.Envoy.Listener.DisableMergeSlashes, + ServerHeaderTransformation: contourConfiguration.Envoy.Listener.ServerHeaderTransformation, + XffNumTrustedHops: *contourConfiguration.Envoy.Network.XffNumTrustedHops, + ConnectionBalancer: contourConfiguration.Envoy.Listener.ConnectionBalancer, + MaxRequestsPerConnection: contourConfiguration.Envoy.Listener.MaxRequestsPerConnection, + HTTP2MaxConcurrentStreams: contourConfiguration.Envoy.Listener.HTTP2MaxConcurrentStreams, + PerConnectionBufferLimitBytes: contourConfiguration.Envoy.Listener.PerConnectionBufferLimitBytes, + SocketOptions: contourConfiguration.Envoy.Listener.SocketOptions, + MaxConnectionsToAcceptPerSocketEvent: contourConfiguration.Envoy.Listener.MaxConnectionsToAcceptPerSocketEvent, } if listenerConfig.TracingConfig, err = s.setupTracingService(contourConfiguration.Tracing); err != nil { @@ -574,6 +575,7 @@ func (s *Server) doServe() error { globalRateLimitService: contourConfiguration.RateLimitService, maxRequestsPerConnection: contourConfiguration.Envoy.Cluster.MaxRequestsPerConnection, perConnectionBufferLimitBytes: contourConfiguration.Envoy.Cluster.PerConnectionBufferLimitBytes, + enableStatPrefix: *contourConfiguration.Envoy.EnableStatPrefix, globalCircuitBreakerDefaults: contourConfiguration.Envoy.Cluster.GlobalCircuitBreakerDefaults, upstreamTLS: &dag.UpstreamTLS{ MinimumProtocolVersion: annotation.TLSVersion(contourConfiguration.Envoy.Cluster.UpstreamTLS.MinimumProtocolVersion, "1.2"), @@ -876,6 +878,35 @@ func (s *Server) setupGlobalExternalAuthentication(contourConfiguration contour_ Context: context, } + switch contourConfiguration.GlobalExternalAuthorization.ServiceAPIType { + case contour_v1.AuthorizationGRPCService: + globalExternalAuthConfig.ServiceAPIType = contour_v1.AuthorizationGRPCService + case contour_v1.AuthorizationHTTPService: + globalExternalAuthConfig.ServiceAPIType = contour_v1.AuthorizationHTTPService + + if contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings != nil { + globalExternalAuthConfig.HTTPPathPrefix = contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings.PathPrefix + + // globalExternalAuthConfig.HttpServerURI = contourConfiguration.GlobalExternalAuthorization.HttpServerSettings.ServerURI + + if len(contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings.AllowedAuthorizationHeaders) > 0 { + if err := dag.ExternalAuthAllowedHeadersValid(contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings.AllowedAuthorizationHeaders); err != nil { + return nil, err + } + + globalExternalAuthConfig.HTTPAllowedAuthorizationHeaders = contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings.AllowedAuthorizationHeaders + } + + if len(contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings.AllowedUpstreamHeaders) > 0 { + if err := dag.ExternalAuthAllowedHeadersValid(contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings.AllowedUpstreamHeaders); err != nil { + return nil, err + } + + globalExternalAuthConfig.HTTPAllowedUpstreamHeaders = contourConfiguration.GlobalExternalAuthorization.HTTPServerSettings.AllowedUpstreamHeaders + } + } + } + if contourConfiguration.GlobalExternalAuthorization.WithRequestBody != nil { globalExternalAuthConfig.WithRequestBody = &dag.AuthorizationServerBufferSettings{ PackAsBytes: contourConfiguration.GlobalExternalAuthorization.WithRequestBody.PackAsBytes, @@ -1069,6 +1100,7 @@ type dagBuilderConfig struct { perConnectionBufferLimitBytes *uint32 globalRateLimitService *contour_v1alpha1.RateLimitServiceConfig globalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers + enableStatPrefix bool upstreamTLS *dag.UpstreamTLS } @@ -1140,6 +1172,7 @@ func (s *Server) getDAGBuilder(dbc dagBuilderConfig) *dag.Builder { PerConnectionBufferLimitBytes: dbc.perConnectionBufferLimitBytes, GlobalCircuitBreakerDefaults: dbc.globalCircuitBreakerDefaults, SetSourceMetadataOnRoutes: true, + EnableStatPrefix: dbc.enableStatPrefix, UpstreamTLS: dbc.upstreamTLS, }, &dag.ExtensionServiceProcessor{ @@ -1164,6 +1197,7 @@ func (s *Server) getDAGBuilder(dbc dagBuilderConfig) *dag.Builder { GlobalRateLimitService: dbc.globalRateLimitService, PerConnectionBufferLimitBytes: dbc.perConnectionBufferLimitBytes, SetSourceMetadataOnRoutes: true, + EnableStatPrefix: dbc.enableStatPrefix, GlobalCircuitBreakerDefaults: dbc.globalCircuitBreakerDefaults, UpstreamTLS: dbc.upstreamTLS, }, @@ -1177,6 +1211,7 @@ func (s *Server) getDAGBuilder(dbc dagBuilderConfig) *dag.Builder { MaxRequestsPerConnection: dbc.maxRequestsPerConnection, PerConnectionBufferLimitBytes: dbc.perConnectionBufferLimitBytes, SetSourceMetadataOnRoutes: true, + EnableStatPrefix: dbc.enableStatPrefix, GlobalCircuitBreakerDefaults: dbc.globalCircuitBreakerDefaults, UpstreamTLS: dbc.upstreamTLS, }) diff --git a/cmd/contour/servecontext.go b/cmd/contour/servecontext.go index 51a6c3a726a..aca4820b03a 100644 --- a/cmd/contour/servecontext.go +++ b/cmd/contour/servecontext.go @@ -391,6 +391,7 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co RequestHeaderName: customTag.RequestHeaderName, }) } + tracingConfig = &contour_v1alpha1.TracingConfig{ IncludePodDetail: ctx.Config.Tracing.IncludePodDetail, ServiceName: ctx.Config.Tracing.ServiceName, @@ -439,10 +440,15 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co Name: nsedName.Name, Namespace: nsedName.Namespace, }, + ServiceAPIType: ctx.Config.GlobalExternalAuthorization.ServiceAPIType, ResponseTimeout: ctx.Config.GlobalExternalAuthorization.ResponseTimeout, FailOpen: ctx.Config.GlobalExternalAuthorization.FailOpen, } + if ctx.Config.GlobalExternalAuthorization.HTTPServerSettings != nil { + globalExtAuth.HTTPServerSettings = ctx.Config.GlobalExternalAuthorization.HTTPServerSettings + } + if ctx.Config.GlobalExternalAuthorization.AuthPolicy != nil { globalExtAuth.AuthPolicy = &contour_v1.AuthorizationPolicy{ Disabled: ctx.Config.GlobalExternalAuthorization.AuthPolicy.Disabled, @@ -520,16 +526,17 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_v1alpha1.Co }, Envoy: &contour_v1alpha1.EnvoyConfig{ Listener: &contour_v1alpha1.EnvoyListenerConfig{ - UseProxyProto: &ctx.useProxyProto, - DisableAllowChunkedLength: &ctx.Config.DisableAllowChunkedLength, - DisableMergeSlashes: &ctx.Config.DisableMergeSlashes, - ServerHeaderTransformation: serverHeaderTransformation, - ConnectionBalancer: ctx.Config.Listener.ConnectionBalancer, - PerConnectionBufferLimitBytes: ctx.Config.Listener.PerConnectionBufferLimitBytes, - MaxRequestsPerConnection: ctx.Config.Listener.MaxRequestsPerConnection, - MaxRequestsPerIOCycle: ctx.Config.Listener.MaxRequestsPerIOCycle, - HTTP2MaxConcurrentStreams: ctx.Config.Listener.HTTP2MaxConcurrentStreams, - MaxConnectionsPerListener: ctx.Config.Listener.MaxConnectionsPerListener, + UseProxyProto: &ctx.useProxyProto, + DisableAllowChunkedLength: &ctx.Config.DisableAllowChunkedLength, + DisableMergeSlashes: &ctx.Config.DisableMergeSlashes, + ServerHeaderTransformation: serverHeaderTransformation, + ConnectionBalancer: ctx.Config.Listener.ConnectionBalancer, + PerConnectionBufferLimitBytes: ctx.Config.Listener.PerConnectionBufferLimitBytes, + MaxRequestsPerConnection: ctx.Config.Listener.MaxRequestsPerConnection, + MaxRequestsPerIOCycle: ctx.Config.Listener.MaxRequestsPerIOCycle, + HTTP2MaxConcurrentStreams: ctx.Config.Listener.HTTP2MaxConcurrentStreams, + MaxConnectionsPerListener: ctx.Config.Listener.MaxConnectionsPerListener, + MaxConnectionsToAcceptPerSocketEvent: ctx.Config.Listener.MaxConnectionsToAcceptPerSocketEvent, TLS: &contour_v1alpha1.EnvoyTLS{ MinimumProtocolVersion: ctx.Config.TLS.MinimumProtocolVersion, MaximumProtocolVersion: ctx.Config.TLS.MaximumProtocolVersion, diff --git a/design/external-authorization-design.md b/design/external-authorization-design.md index 8a298bfc914..1f9fe6051be 100644 --- a/design/external-authorization-design.md +++ b/design/external-authorization-design.md @@ -34,7 +34,7 @@ This document describes a design for performing request authorization for virtua A new `ExtensionService` CRD adds a way to represent and track an authorization service. This CRD is relatively generic, so that it can be reused for Envoy rate limiting and logging services. The core of the `ExtensionService` CRD is subset of the `projectcontour.v1.HTTPProxy` `Service` specification. -Re-using the `Service` type allows the operator to specify configuration in familiar and consistent terms, especially TLS configuration. +Reusing the `Service` type allows the operator to specify configuration in familiar and consistent terms, especially TLS configuration. Note that only the Envoy [GRPC authorization protocol][2] will be supported. The GRPC protocol is a superset of the HTTP protocol and requires less configuration. diff --git a/examples/contour/01-crds.yaml b/examples/contour/01-crds.yaml index c1f6eacc65b..3421a7b2982 100644 --- a/examples/contour/01-crds.yaml +++ b/examples/contour/01-crds.yaml @@ -230,6 +230,9 @@ spec: version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -323,6 +326,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -690,6 +700,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for interacting + with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of authorization + request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -698,6 +787,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -1054,7 +1153,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data to - OpenTelemetry. + the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with unique @@ -4032,6 +4131,9 @@ spec: HTTP version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -4125,6 +4227,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -4492,6 +4601,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -4500,6 +4688,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -4857,7 +5055,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data - to OpenTelemetry. + to the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with @@ -5124,9 +5322,9 @@ spec: type: object loadBalancerPolicy: description: |- - The policy for load balancing GRPC service requests. Note that the + The policy for load balancing service requests. Note that the `Cookie` and `RequestHash` load balancing strategies cannot be used - here. + here for GRPC service requests. properties: requestHashPolicies: description: |- @@ -5200,8 +5398,9 @@ spec: protocol: description: |- 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. + Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations. enum: + - http/1.1 - h2 - h2c type: string @@ -5217,7 +5416,7 @@ spec: services: description: |- Services specifies the set of Kubernetes Service resources that - receive GRPC extension API requests. + receive 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. @@ -5581,6 +5780,18 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: |- + HTTPVersions specify the http versions to offer for this HTTPProxy. + If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. + It is ignored when TCPProxy is set. + items: + description: HTTPVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: |- Includes allow for specific routing configuration to be included from another HTTPProxy, @@ -7473,6 +7684,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -7481,6 +7771,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. diff --git a/examples/render/contour-deployment.yaml b/examples/render/contour-deployment.yaml index 1b89dcd4a1c..6eda90e44b9 100644 --- a/examples/render/contour-deployment.yaml +++ b/examples/render/contour-deployment.yaml @@ -450,6 +450,9 @@ spec: version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -543,6 +546,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -910,6 +920,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for interacting + with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of authorization + request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -918,6 +1007,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -1274,7 +1373,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data to - OpenTelemetry. + the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with unique @@ -4252,6 +4351,9 @@ spec: HTTP version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -4345,6 +4447,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -4712,6 +4821,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -4720,6 +4908,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -5077,7 +5275,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data - to OpenTelemetry. + to the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with @@ -5344,9 +5542,9 @@ spec: type: object loadBalancerPolicy: description: |- - The policy for load balancing GRPC service requests. Note that the + The policy for load balancing service requests. Note that the `Cookie` and `RequestHash` load balancing strategies cannot be used - here. + here for GRPC service requests. properties: requestHashPolicies: description: |- @@ -5420,8 +5618,9 @@ spec: protocol: description: |- 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. + Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations. enum: + - http/1.1 - h2 - h2c type: string @@ -5437,7 +5636,7 @@ spec: services: description: |- Services specifies the set of Kubernetes Service resources that - receive GRPC extension API requests. + receive 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. @@ -5801,6 +6000,18 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: |- + HTTPVersions specify the http versions to offer for this HTTPProxy. + If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. + It is ignored when TCPProxy is set. + items: + description: HTTPVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: |- Includes allow for specific routing configuration to be included from another HTTPProxy, @@ -7693,6 +7904,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -7701,6 +7991,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. diff --git a/examples/render/contour-gateway-provisioner.yaml b/examples/render/contour-gateway-provisioner.yaml index 31b631cca9a..46e1ee7a729 100644 --- a/examples/render/contour-gateway-provisioner.yaml +++ b/examples/render/contour-gateway-provisioner.yaml @@ -241,6 +241,9 @@ spec: version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -334,6 +337,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -701,6 +711,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for interacting + with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of authorization + request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -709,6 +798,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -1065,7 +1164,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data to - OpenTelemetry. + the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with unique @@ -4043,6 +4142,9 @@ spec: HTTP version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -4136,6 +4238,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -4503,6 +4612,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -4511,6 +4699,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -4868,7 +5066,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data - to OpenTelemetry. + to the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with @@ -5135,9 +5333,9 @@ spec: type: object loadBalancerPolicy: description: |- - The policy for load balancing GRPC service requests. Note that the + The policy for load balancing service requests. Note that the `Cookie` and `RequestHash` load balancing strategies cannot be used - here. + here for GRPC service requests. properties: requestHashPolicies: description: |- @@ -5211,8 +5409,9 @@ spec: protocol: description: |- 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. + Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations. enum: + - http/1.1 - h2 - h2c type: string @@ -5228,7 +5427,7 @@ spec: services: description: |- Services specifies the set of Kubernetes Service resources that - receive GRPC extension API requests. + receive 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. @@ -5592,6 +5791,18 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: |- + HTTPVersions specify the http versions to offer for this HTTPProxy. + If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. + It is ignored when TCPProxy is set. + items: + description: HTTPVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: |- Includes allow for specific routing configuration to be included from another HTTPProxy, @@ -7484,6 +7695,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -7492,6 +7782,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. diff --git a/examples/render/contour-gateway.yaml b/examples/render/contour-gateway.yaml index f37bdc1a9b5..64f89054abb 100644 --- a/examples/render/contour-gateway.yaml +++ b/examples/render/contour-gateway.yaml @@ -266,6 +266,9 @@ spec: version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -359,6 +362,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -726,6 +736,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for interacting + with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of authorization + request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -734,6 +823,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -1090,7 +1189,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data to - OpenTelemetry. + the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with unique @@ -4068,6 +4167,9 @@ spec: HTTP version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -4161,6 +4263,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -4528,6 +4637,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -4536,6 +4724,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -4893,7 +5091,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data - to OpenTelemetry. + to the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with @@ -5160,9 +5358,9 @@ spec: type: object loadBalancerPolicy: description: |- - The policy for load balancing GRPC service requests. Note that the + The policy for load balancing service requests. Note that the `Cookie` and `RequestHash` load balancing strategies cannot be used - here. + here for GRPC service requests. properties: requestHashPolicies: description: |- @@ -5236,8 +5434,9 @@ spec: protocol: description: |- 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. + Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations. enum: + - http/1.1 - h2 - h2c type: string @@ -5253,7 +5452,7 @@ spec: services: description: |- Services specifies the set of Kubernetes Service resources that - receive GRPC extension API requests. + receive 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. @@ -5617,6 +5816,18 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: |- + HTTPVersions specify the http versions to offer for this HTTPProxy. + If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. + It is ignored when TCPProxy is set. + items: + description: HTTPVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: |- Includes allow for specific routing configuration to be included from another HTTPProxy, @@ -7509,6 +7720,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -7517,6 +7807,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. diff --git a/examples/render/contour.yaml b/examples/render/contour.yaml index 5361950a894..304cb658009 100644 --- a/examples/render/contour.yaml +++ b/examples/render/contour.yaml @@ -450,6 +450,9 @@ spec: version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -543,6 +546,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -910,6 +920,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for interacting + with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that must + be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the header + name. + type: string + suffix: + description: Suffix defines a suffix match for a header + name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of authorization + request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -918,6 +1007,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -1274,7 +1373,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data to - OpenTelemetry. + the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with unique @@ -4252,6 +4351,9 @@ spec: HTTP version. type: string type: array + enableStatPrefix: + description: Set StatPrefix on envoy routes + type: boolean health: description: |- Health defines the endpoint Envoy uses to serve health checks. @@ -4345,6 +4447,13 @@ spec: format: int32 minimum: 1 type: integer + maxConnectionsToAcceptPerSocketEvent: + description: |- + MaxConnectionsToAcceptPerSocketEvent defines the maximum number of + connections Envoy will accept per socket event. + format: int32 + minimum: 1 + type: integer maxRequestsPerConnection: description: |- Defines the maximum requests for downstream connections. If not specified, there is no limit. @@ -4712,6 +4821,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -4720,6 +4908,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. @@ -5077,7 +5275,7 @@ spec: type: object tracing: description: Tracing defines properties for exporting trace data - to OpenTelemetry. + to the OpenTelemetry. properties: customTags: description: CustomTags defines a list of custom tags with @@ -5344,9 +5542,9 @@ spec: type: object loadBalancerPolicy: description: |- - The policy for load balancing GRPC service requests. Note that the + The policy for load balancing service requests. Note that the `Cookie` and `RequestHash` load balancing strategies cannot be used - here. + here for GRPC service requests. properties: requestHashPolicies: description: |- @@ -5420,8 +5618,9 @@ spec: protocol: description: |- 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. + Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations. enum: + - http/1.1 - h2 - h2c type: string @@ -5437,7 +5636,7 @@ spec: services: description: |- Services specifies the set of Kubernetes Service resources that - receive GRPC extension API requests. + receive 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. @@ -5801,6 +6000,18 @@ spec: spec: description: HTTPProxySpec defines the spec of the CRD. properties: + httpVersions: + description: |- + HTTPVersions specify the http versions to offer for this HTTPProxy. + If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. + It is ignored when TCPProxy is set. + items: + description: HTTPVersion is an alias to enforce validation + enum: + - h2 + - http/1.1 + type: string + type: array includes: description: |- Includes allow for specific routing configuration to be included from another HTTPProxy, @@ -7693,6 +7904,85 @@ spec: set in most cases. It is intended for use only while migrating applications from internal authorization to Contour external authorization. type: boolean + httpSettings: + description: HTTPServerSettings defines configurations for + interacting with an external HTTP authorization server. + properties: + allowedAuthorizationHeaders: + description: |- + AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + allowedUpstreamHeaders: + description: |- + AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + Note that coexistent headers will be overridden. + items: + description: |- + HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers + in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, + Contains, and IgnoreCase to customize header matching criteria. However, regex support + is intentionally excluded to simplify the user experience and prevent potential issues. + One of Prefix, Exact, Suffix or Contains must be provided. + properties: + contains: + description: Contains specifies a substring that + must be present in the header name. + type: string + exact: + description: Exact specifies a string that the header + name must be equal to. + type: string + ignoreCase: + description: |- + IgnoreCase specifies that string matching should be case insensitive. + Note that this has no effect on the Regex parameter. + type: boolean + prefix: + description: Prefix defines a prefix match for the + header name. + type: string + suffix: + description: Suffix defines a suffix match for a + header name. + type: string + type: object + type: array + pathPrefix: + description: PathPrefix Sets a prefix to the value of + authorization request header Path. + type: string + type: object responseTimeout: description: |- ResponseTimeout configures maximum time to wait for a check response from the authorization server. @@ -7701,6 +7991,16 @@ spec: The string "infinity" is also a valid input and specifies no timeout. pattern: ^(((\d*(\.\d*)?h)|(\d*(\.\d*)?m)|(\d*(\.\d*)?s)|(\d*(\.\d*)?ms)|(\d*(\.\d*)?us)|(\d*(\.\d*)?µs)|(\d*(\.\d*)?ns))+|infinity|infinite)$ type: string + serviceAPIType: + default: grpc + description: |- + ServiceAPIType defines the external authorization service API type. + It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + or a gRPC authorization server. + enum: + - http + - grpc + type: string withRequestBody: description: WithRequestBody specifies configuration for sending the client request's body to authorization server. diff --git a/internal/contourconfig/contourconfiguration.go b/internal/contourconfig/contourconfiguration.go index 0c369f170cb..a987e73637a 100644 --- a/internal/contourconfig/contourconfiguration.go +++ b/internal/contourconfig/contourconfiguration.go @@ -131,6 +131,7 @@ func Defaults() contour_v1alpha1.ContourConfigurationSpec { XffNumTrustedHops: ptr.To(uint32(0)), EnvoyAdminPort: ptr.To(9001), }, + EnableStatPrefix: ptr.To(false), }, Gateway: nil, HTTPProxy: &contour_v1alpha1.HTTPProxyConfig{ diff --git a/internal/contourconfig/contourconfiguration_test.go b/internal/contourconfig/contourconfiguration_test.go index bb13b8229da..c2edbd1f9a8 100644 --- a/internal/contourconfig/contourconfiguration_test.go +++ b/internal/contourconfig/contourconfiguration_test.go @@ -134,6 +134,7 @@ func TestOverlayOnDefaults(t *testing.T) { XffNumTrustedHops: ptr.To(uint32(77)), EnvoyAdminPort: ptr.To(9997), }, + EnableStatPrefix: ptr.To(false), }, Gateway: &contour_v1alpha1.GatewayConfig{ GatewayRef: contour_v1alpha1.NamespacedName{ diff --git a/internal/dag/conditions.go b/internal/dag/conditions.go index 8b4f542ce9c..2fb2e154649 100644 --- a/internal/dag/conditions.go +++ b/internal/dag/conditions.go @@ -407,6 +407,56 @@ func queryParameterMatchConditionsValid(conditions []contour_v1.MatchCondition) return nil } +// ExternalAuthAllowedHeadersValid validates that the allowed header conditions within a +// slice of HttpAuthorizationServerAllowedHeaders are valid. Specifically, it returns an error for +// any of the following scenarios: +// - no conditions are set +// - more than one condition is set in the same allowed header condition branch +// - invalid regular expression is specified for the Regex condition +func ExternalAuthAllowedHeadersValid(allowedHeaders []contour_v1.HTTPAuthorizationServerAllowedHeaders) error { + for _, allowedHeader := range allowedHeaders { + sum := 0 + + // To streamline user experience and mitigate potential issues, we do not support regex. + // Additionally, it's essential to ensure that any regex patterns adhere to the configured runtime key, re2.max_program_size.error_level + // by verifying that the program size is smaller than the specified value. + // This necessitates thorough validation of user input. + // + // if allowedHeader.Regex != "" { + // if err := ValidateRegex(allowedHeader.Regex); err != nil { + // return errors.New("the RE2 regex syntax is invalid") + // } + // sum++ + // } + + if allowedHeader.Exact != "" { + sum++ + } + + if allowedHeader.Prefix != "" { + sum++ + } + + if allowedHeader.Suffix != "" { + sum++ + } + + if allowedHeader.Contains != "" { + sum++ + } + + if sum == 0 { + return errors.New("one of prefix, suffix, exact or contains is required for each allowedHeader") + } + + if sum > 1 { + return errors.New("more than one prefix, suffix, exact or contains is not allowed in an allowedHeader") + } + } + + return nil +} + // ValidateRegex returns an error if the supplied // RE2 regex syntax is invalid. func ValidateRegex(regex string) error { diff --git a/internal/dag/dag.go b/internal/dag/dag.go index d5832c7e051..a26f1c375d2 100644 --- a/internal/dag/dag.go +++ b/internal/dag/dag.go @@ -27,6 +27,7 @@ import ( core_v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" + contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" "github.com/projectcontour/contour/internal/status" "github.com/projectcontour/contour/internal/timeout" ) @@ -374,6 +375,9 @@ type Route struct { Kind string Namespace string Name string + + // The stat_prefix to set on envoy route + StatPrefix *string } // HasPathPrefix returns whether this route has a PrefixPathCondition. @@ -814,6 +818,9 @@ type SecureVirtualHost struct { // JWTProviders specify how to verify JWTs. JWTProviders []JWTProvider + + // AlpnProtos specify the HTTP version to offer for this vhost + HTTPVersions []string } type JWTProvider struct { @@ -866,6 +873,29 @@ type ExternalAuthorization struct { // authorization is enabled for this host. AuthorizationService *ExtensionCluster + // ServiceAPIType defines the external authorization service API type. + // It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + // or a gRPC authorization server. + ServiceAPIType contour_v1.AuthorizationServiceAPIType + + // HTTPAllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. + // Note that in addition to the the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list. + HTTPAllowedAuthorizationHeaders []contour_v1.HTTPAuthorizationServerAllowedHeaders + + // HTTPAllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. + // Note that coexistent headers will be overridden. + HTTPAllowedUpstreamHeaders []contour_v1.HTTPAuthorizationServerAllowedHeaders + + // HTTPPathPrefix Sets a prefix to the value of authorization request header Path. + HTTPPathPrefix string + + // Note: This field is not used by Envoy + // https://github.com/envoyproxy/envoy/issues/5357 + // + // HttpServerURI sets the URI of the external HTTP authorization server to which authorization requests must be sent. + // Only required for http services. + // HttpServerURI string + // AuthorizationResponseTimeout sets how long the proxy should wait // for authorization server responses. AuthorizationResponseTimeout timeout.Setting diff --git a/internal/dag/gatewayapi_processor.go b/internal/dag/gatewayapi_processor.go index e28dc845a17..b6df957c88c 100644 --- a/internal/dag/gatewayapi_processor.go +++ b/internal/dag/gatewayapi_processor.go @@ -75,6 +75,9 @@ type GatewayAPIProcessor struct { // without requiring all existing test cases to change. SetSourceMetadataOnRoutes bool + // Whether to set StatPrefix on envoy routes or not + EnableStatPrefix bool + // GlobalCircuitBreakerDefaults defines global circuit breaker defaults. GlobalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers @@ -2405,6 +2408,10 @@ func (p *GatewayAPIProcessor) clusterRoutes( route.Name = name } + if p.EnableStatPrefix { + route.StatPrefix = ptr.To(fmt.Sprintf("%s_%s", namespace, name)) + } + routes = append(routes, route) } @@ -2473,6 +2480,10 @@ func (p *GatewayAPIProcessor) redirectRoutes( route.Name = name } + if p.EnableStatPrefix { + route.StatPrefix = ptr.To(fmt.Sprintf("%s_%s", namespace, name)) + } + routes = append(routes, route) } diff --git a/internal/dag/httpproxy_processor.go b/internal/dag/httpproxy_processor.go index f1d0741ab49..658704aa1e6 100644 --- a/internal/dag/httpproxy_processor.go +++ b/internal/dag/httpproxy_processor.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/utils/ptr" contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" @@ -113,6 +114,9 @@ type HTTPProxyProcessor struct { // without requiring all existing test cases to change. SetSourceMetadataOnRoutes bool + // Whether to set StatPrefix on envoy routes or not + EnableStatPrefix bool + // GlobalCircuitBreakerDefaults defines global circuit breaker defaults. GlobalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers @@ -270,6 +274,7 @@ func (p *HTTPProxyProcessor) computeHTTPProxy(proxy *contour_v1.HTTPProxy) { svhost.Secret = sec svhost.MinTLSVersion = minTLSVer svhost.MaxTLSVersion = maxTLSVer + svhost.HTTPVersions = p.getSortedHTTPVersions(proxy) // Check if FallbackCertificate && ClientValidation are both enabled in the same vhost if tls.EnableFallbackCertificate && tls.ClientValidation != nil { @@ -643,6 +648,10 @@ func (p *HTTPProxyProcessor) addStatusBadGatewayRoute(routes []*Route, conds []c route.Name = proxy.Name } + if p.EnableStatPrefix { + route.StatPrefix = ptr.To(fmt.Sprintf("%s_%s", proxy.Namespace, proxy.Name)) + } + routes = append(routes, route) } return routes @@ -848,6 +857,14 @@ func (p *HTTPProxyProcessor) computeRoutes( r.Name = proxy.Name } + if p.EnableStatPrefix { + path := "_" + if len(route.Conditions) > 0 && route.Conditions[0].Prefix != "" { + path = strings.TrimPrefix(route.Conditions[0].Prefix, "/") + } + r.StatPrefix = ptr.To(fmt.Sprintf("%s_httpproxy_%s_path_%s", proxy.Namespace, proxy.Name, path)) + } + // If the enclosing root proxy enabled authorization, // enable it on the route and propagate defaults // downwards. @@ -1403,6 +1420,41 @@ func (p *HTTPProxyProcessor) computeVirtualHostAuthorization(auth *contour_v1.Au AuthorizationResponseTimeout: *respTimeout, } + switch auth.ServiceAPIType { + case contour_v1.AuthorizationGRPCService: + globalExternalAuthorization.ServiceAPIType = contour_v1.AuthorizationGRPCService + case contour_v1.AuthorizationHTTPService: + globalExternalAuthorization.ServiceAPIType = contour_v1.AuthorizationHTTPService + + if auth.HTTPServerSettings != nil { + globalExternalAuthorization.HTTPPathPrefix = auth.HTTPServerSettings.PathPrefix + + // globalExternalAuthorization.HttpServerURI = auth.HttpServerSettings.ServerURI + + if len(auth.HTTPServerSettings.AllowedAuthorizationHeaders) > 0 { + if err := ExternalAuthAllowedHeadersValid(auth.HTTPServerSettings.AllowedAuthorizationHeaders); err != nil { + validCond.AddErrorf(contour_v1.ConditionTypeAuthError, "AuthBadAllowedHeader", + "allowed authorization headers validation failed: %v", err) + + return nil + } + + globalExternalAuthorization.HTTPAllowedAuthorizationHeaders = auth.HTTPServerSettings.AllowedAuthorizationHeaders + } + + if len(auth.HTTPServerSettings.AllowedUpstreamHeaders) > 0 { + if err := ExternalAuthAllowedHeadersValid(auth.HTTPServerSettings.AllowedUpstreamHeaders); err != nil { + validCond.AddErrorf(contour_v1.ConditionTypeAuthError, "AuthBadAllowedHeader", + "allowed upstream headers validation failed: %v", err) + + return nil + } + + globalExternalAuthorization.HTTPAllowedUpstreamHeaders = auth.HTTPServerSettings.AllowedUpstreamHeaders + } + } + } + if auth.WithRequestBody != nil { maxRequestBytes := defaultMaxRequestBytes if auth.WithRequestBody.MaxRequestBytes != 0 { @@ -1539,6 +1591,21 @@ func (p *HTTPProxyProcessor) peerValidationContext(validCond *contour_v1.Detaile return uv } +// getSortedHTTPVersions returns and empty slice or ["h2", "http/1.1"] or ["http/1.1"]. +// This is done to conform with how envoy expects AlpnProtocols in tlsv3.CommonTlsContext. +func (p *HTTPProxyProcessor) getSortedHTTPVersions(proxy *contour_v1.HTTPProxy) []string { + proxyHTTPVersions := proxy.Spec.HTTPVersions + if len(proxyHTTPVersions) == 0 { + return nil + } + for _, httpVersion := range proxyHTTPVersions { + if httpVersion == "h2" { + return []string{"h2", "http/1.1"} + } + } + return []string{"http/1.1"} +} + // expandPrefixMatches adds new Routes to account for the difference // between prefix replacement when matching on '/foo' and '/foo/'. // diff --git a/internal/dag/ingress_processor.go b/internal/dag/ingress_processor.go index 63639e22712..3bbee5fa66a 100644 --- a/internal/dag/ingress_processor.go +++ b/internal/dag/ingress_processor.go @@ -14,6 +14,7 @@ package dag import ( + "fmt" "strconv" "strings" "time" @@ -67,6 +68,9 @@ type IngressProcessor struct { // without requiring all existing test cases to change. SetSourceMetadataOnRoutes bool + // Whether to set StatPrefix on envoy routes or not + EnableStatPrefix bool + // GlobalCircuitBreakerDefaults defines global circuit breaker defaults. GlobalCircuitBreakerDefaults *contour_v1alpha1.CircuitBreakers @@ -290,6 +294,7 @@ func (p *IngressProcessor) route(ingress *networking_v1.Ingress, host, path stri } r := &Route{ + AuthDisabled: true, HTTPSUpgrade: annotation.TLSRequired(ingress), Websocket: annotation.WebsocketRoutes(ingress)[path], TimeoutPolicy: ingressTimeoutPolicy(ingress, log), @@ -313,6 +318,10 @@ func (p *IngressProcessor) route(ingress *networking_v1.Ingress, host, path stri r.Name = ingress.Name } + if p.EnableStatPrefix { + r.StatPrefix = ptr.To(fmt.Sprintf("%s_%s", ingress.Namespace, ingress.Name)) + } + switch pathType { case networking_v1.PathTypePrefix: prefixMatchType := PrefixMatchSegment diff --git a/internal/envoy/cluster.go b/internal/envoy/cluster.go index 60afe0d8e29..21871c6df79 100644 --- a/internal/envoy/cluster.go +++ b/internal/envoy/cluster.go @@ -67,7 +67,7 @@ func Clustername(cluster *dag.Cluster) string { ns := service.Weighted.ServiceNamespace name := service.Weighted.ServiceName - return Hashname(60, ns, name, strconv.Itoa(int(service.Weighted.ServicePort.Port)), fmt.Sprintf("%x", hash[:5])) + return Hashname(120, ns, name, strconv.Itoa(int(service.Weighted.ServicePort.Port)), fmt.Sprintf("%x", hash[:5])) } // AltStatName generates an alternative stat name for the service diff --git a/internal/envoy/secret.go b/internal/envoy/secret.go index d85e8a2c920..83e1b4fbca7 100644 --- a/internal/envoy/secret.go +++ b/internal/envoy/secret.go @@ -26,5 +26,5 @@ func Secretname(s *dag.Secret) string { hash := sha1.Sum(s.Cert()) // nolint:gosec ns := s.Namespace() name := s.Name() - return Hashname(60, ns, name, fmt.Sprintf("%x", hash[:5])) + return Hashname(120, ns, name, fmt.Sprintf("%x", hash[:5])) } diff --git a/internal/envoy/v3/cluster.go b/internal/envoy/v3/cluster.go index 24346c48421..c85b8e7b57f 100644 --- a/internal/envoy/v3/cluster.go +++ b/internal/envoy/v3/cluster.go @@ -162,10 +162,10 @@ func ExtensionCluster(ext *dag.ExtensionCluster) *envoy_config_cluster_v3.Cluste // TODO(jpeach): Externalname service support in https://github.com/projectcontour/contour/issues/2875 - http2Version := HTTPVersionAuto + httpVersion := HTTPVersionAuto switch ext.Protocol { case "h2": - http2Version = HTTPVersion2 + httpVersion = HTTPVersion2 cluster.TransportSocket = UpstreamTLSTransportSocket( UpstreamTLSContext( ext.UpstreamValidation, @@ -176,13 +176,15 @@ func ExtensionCluster(ext *dag.ExtensionCluster) *envoy_config_cluster_v3.Cluste ), ) case "h2c": - http2Version = HTTPVersion2 + httpVersion = HTTPVersion2 + case "http/1.1": + httpVersion = HTTPVersion1 } if ext.ClusterTimeoutPolicy.ConnectTimeout > time.Duration(0) { cluster.ConnectTimeout = durationpb.New(ext.ClusterTimeoutPolicy.ConnectTimeout) } - cluster.TypedExtensionProtocolOptions = protocolOptions(http2Version, ext.ClusterTimeoutPolicy.IdleConnectionTimeout, nil) + cluster.TypedExtensionProtocolOptions = protocolOptions(httpVersion, ext.ClusterTimeoutPolicy.IdleConnectionTimeout, nil) applyCircuitBreakers(cluster, ext.CircuitBreakers) diff --git a/internal/envoy/v3/cluster_test.go b/internal/envoy/v3/cluster_test.go index cc9f64bcec5..88dac73ecb9 100644 --- a/internal/envoy/v3/cluster_test.go +++ b/internal/envoy/v3/cluster_test.go @@ -1119,7 +1119,7 @@ func TestClustername(t *testing.T) { }, }, }, - want: "it-is-a--dea8b0/must-be--dea8b0/9999/da39a3ee5e", + want: "it-is-a-truth-universal-dea8b0/must-be-in-want-of-a-wife/9999/da39a3ee5e", }) run(t, "various healthcheck params", testcase{ diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go index 213a71af9bf..aafec252e7f 100644 --- a/internal/envoy/v3/listener.go +++ b/internal/envoy/v3/listener.go @@ -39,11 +39,13 @@ import ( envoy_filter_network_http_connection_manager_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" envoy_filter_network_tcp_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/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" envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/wrapperspb" + contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" "github.com/projectcontour/contour/internal/dag" "github.com/projectcontour/contour/internal/envoy" @@ -61,7 +63,7 @@ const ( HTTPVersion3 HTTPVersionType = envoy_filter_network_http_connection_manager_v3.HttpConnectionManager_HTTP3 ) -// ProtoNamesForVersions returns the slice of ALPN protocol names for the give HTTP versions. +// ProtoNamesForVersions returns the slice of ALPN protocol names for the given HTTP versions. func ProtoNamesForVersions(versions ...HTTPVersionType) []string { protocols := map[HTTPVersionType]string{ HTTPVersion1: "http/1.1", @@ -789,13 +791,61 @@ end } } +// ExternalAuthzAllowedHeaders returns the slice of StringMatcher for a given slice of HttpAuthorizationServerAllowedHeaders. +func ExternalAuthzAllowedHeaders(allowedHeaders []contour_v1.HTTPAuthorizationServerAllowedHeaders) []*envoy_matcher_v3.StringMatcher { + var allowedHeaderPatterns []*envoy_matcher_v3.StringMatcher + + for _, allowedHeader := range allowedHeaders { + switch { + case allowedHeader.Exact != "": + allowedHeaderPatterns = append(allowedHeaderPatterns, &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ + Exact: allowedHeader.Exact, + }, + IgnoreCase: allowedHeader.IgnoreCase, + }) + case allowedHeader.Prefix != "": + allowedHeaderPatterns = append(allowedHeaderPatterns, &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{ + Prefix: allowedHeader.Prefix, + }, + IgnoreCase: allowedHeader.IgnoreCase, + }) + case allowedHeader.Suffix != "": + allowedHeaderPatterns = append(allowedHeaderPatterns, &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Suffix{ + Suffix: allowedHeader.Suffix, + }, + IgnoreCase: allowedHeader.IgnoreCase, + }) + // To streamline user experience and mitigate potential issues, we do not support regex. + // Additionally, it's essential to ensure that any regex patterns adhere to the configured runtime key, re2.max_program_size.error_level + // by verifying that the program size is smaller than the specified value. + // This necessitates thorough validation of user input. + // + // case allowedHeader.Regex != "": + // allowedHeaderPatterns = append(allowedHeaderPatterns, &envoy_matcher.StringMatcher{ + // MatchPattern: &envoy_matcher.StringMatcher_SafeRegex{ + // SafeRegex: SafeRegexMatch(allowedHeader.Regex), + // }, + // }) + case allowedHeader.Contains != "": + allowedHeaderPatterns = append(allowedHeaderPatterns, &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Contains{ + Contains: allowedHeader.Contains, + }, + IgnoreCase: allowedHeader.IgnoreCase, + }) + } + } + + return allowedHeaderPatterns +} + // FilterExternalAuthz returns an `ext_authz` filter configured with the // requested parameters. func FilterExternalAuthz(externalAuthorization *dag.ExternalAuthorization) *envoy_filter_network_http_connection_manager_v3.HttpFilter { authConfig := envoy_filter_http_ext_authz_v3.ExtAuthz{ - Services: &envoy_filter_http_ext_authz_v3.ExtAuthz_GrpcService{ - GrpcService: GrpcService(externalAuthorization.AuthorizationService.Name, externalAuthorization.AuthorizationService.SNI, externalAuthorization.AuthorizationResponseTimeout), - }, // Pretty sure we always want this. Why have an // external auth service if it is not going to affect // routing decisions? @@ -804,11 +854,52 @@ func FilterExternalAuthz(externalAuthorization *dag.ExternalAuthorization) *envo StatusOnError: &envoy_type_v3.HttpStatus{ Code: envoy_type_v3.StatusCode_Forbidden, }, - MetadataContextNamespaces: []string{}, - IncludePeerCertificate: true, // TODO(jpeach): When we move to the Envoy v4 API, propagate the // `transport_api_version` from ExtensionServiceSpec ProtocolVersion. - TransportApiVersion: envoy_config_core_v3.ApiVersion_V3, + TransportApiVersion: envoy_config_core_v3.ApiVersion_V3, + IncludePeerCertificate: true, + } + + switch externalAuthorization.ServiceAPIType { + case contour_v1.AuthorizationGRPCService: + authConfig.Services = &envoy_filter_http_ext_authz_v3.ExtAuthz_GrpcService{ + GrpcService: GrpcService(externalAuthorization.AuthorizationService.Name, externalAuthorization.AuthorizationService.SNI, externalAuthorization.AuthorizationResponseTimeout), + } + authConfig.MetadataContextNamespaces = []string{} + + case contour_v1.AuthorizationHTTPService: + extAuthzService := &envoy_filter_http_ext_authz_v3.ExtAuthz_HttpService{ + HttpService: &envoy_filter_http_ext_authz_v3.HttpService{ + ServerUri: &envoy_config_core_v3.HttpUri{ + // Uri: externalAuthorization.HttpServerURI, + Uri: "http://dummy/", + HttpUpstreamType: &envoy_config_core_v3.HttpUri_Cluster{ + Cluster: externalAuthorization.AuthorizationService.Name, + }, + Timeout: envoy.Timeout(externalAuthorization.AuthorizationResponseTimeout), + }, + }, + } + + if externalAuthorization.HTTPPathPrefix != "" { + extAuthzService.HttpService.PathPrefix = externalAuthorization.HTTPPathPrefix + } + + if len(externalAuthorization.HTTPAllowedAuthorizationHeaders) > 0 { + authConfig.AllowedHeaders = &envoy_matcher_v3.ListStringMatcher{ + Patterns: ExternalAuthzAllowedHeaders(externalAuthorization.HTTPAllowedAuthorizationHeaders), + } + } + + if len(externalAuthorization.HTTPAllowedUpstreamHeaders) > 0 { + extAuthzService.HttpService.AuthorizationResponse = &envoy_filter_http_ext_authz_v3.AuthorizationResponse{ + AllowedUpstreamHeaders: &envoy_matcher_v3.ListStringMatcher{ + Patterns: ExternalAuthzAllowedHeaders(externalAuthorization.HTTPAllowedUpstreamHeaders), + }, + } + } + + authConfig.Services = extAuthzService } if externalAuthorization.AuthorizationServerWithRequestBody != nil { diff --git a/internal/envoy/v3/route.go b/internal/envoy/v3/route.go index 4cd4ea75425..2adf35c5d22 100644 --- a/internal/envoy/v3/route.go +++ b/internal/envoy/v3/route.go @@ -114,6 +114,16 @@ func buildRoute(dagRoute *dag.Route, vhostName string, secure bool) *envoy_confi Metadata: getRouteMetadata(dagRoute), } + if dagRoute.Name != "" { + route.Decorator = &envoy_config_route_v3.Decorator{ + Operation: dagRoute.Name, + } + } + + if dagRoute.StatPrefix != nil { + route.StatPrefix = *dagRoute.StatPrefix + } + switch { case dagRoute.HTTPSUpgrade && !secure: // TODO(dfc) if we ensure the builder never returns a dag.Route connected @@ -139,6 +149,14 @@ func buildRoute(dagRoute *dag.Route, vhostName string, secure bool) *envoy_confi case dagRoute.Redirect != nil: // TODO request/response headers? route.Action = routeRedirect(dagRoute.Redirect) + + route.TypedPerFilterConfig = map[string]*anypb.Any{} + // Apply per-route authorization policy modifications. + if dagRoute.AuthDisabled { + route.TypedPerFilterConfig[ExtAuthzFilterName] = routeAuthzDisabled() + } else if len(dagRoute.AuthContext) > 0 { + route.TypedPerFilterConfig[ExtAuthzFilterName] = routeAuthzContext(dagRoute.AuthContext) + } default: route.Action = routeRoute(dagRoute) @@ -682,7 +700,7 @@ func weightedClusters(route *dag.Route) *envoy_config_route_v3.WeightedCluster { // VirtualHost creates a new route.VirtualHost. func VirtualHost(hostname string, routes ...*envoy_config_route_v3.Route) *envoy_config_route_v3.VirtualHost { return &envoy_config_route_v3.VirtualHost{ - Name: envoy.Hashname(60, hostname), + Name: envoy.Hashname(120, hostname), Domains: []string{hostname}, Routes: routes, } diff --git a/internal/envoy/v3/secret_test.go b/internal/envoy/v3/secret_test.go index 17a5cdc64b1..2d3b2f09d2f 100644 --- a/internal/envoy/v3/secret_test.go +++ b/internal/envoy/v3/secret_test.go @@ -106,7 +106,7 @@ func TestSecretname(t *testing.T) { }, }, }, - want: "it-is-a-truth-7e164b/must-be-in-wa-7e164b/cd1b506996", + want: "it-is-a-truth-universally-acknowl-7e164b/must-be-in-want-of-a-wife/cd1b506996", }, } diff --git a/internal/envoy/v3/tracing.go b/internal/envoy/v3/tracing.go index f66ca8b3ba8..05bbc615eec 100644 --- a/internal/envoy/v3/tracing.go +++ b/internal/envoy/v3/tracing.go @@ -44,8 +44,9 @@ func TracingConfig(tracing *EnvoyTracingConfig) *envoy_filter_network_http_conne OverallSampling: &envoy_type_v3.Percent{ Value: tracing.OverallSampling, }, - MaxPathTagLength: wrapperspb.UInt32(tracing.MaxPathTagLength), - CustomTags: customTags, + MaxPathTagLength: wrapperspb.UInt32(tracing.MaxPathTagLength), + CustomTags: customTags, + SpawnUpstreamSpan: wrapperspb.Bool(true), Provider: &envoy_config_trace_v3.Tracing_Http{ Name: "envoy.tracers.opentelemetry", ConfigType: &envoy_config_trace_v3.Tracing_Http_TypedConfig{ @@ -55,7 +56,6 @@ func TracingConfig(tracing *EnvoyTracingConfig) *envoy_filter_network_http_conne }), }, }, - SpawnUpstreamSpan: wrapperspb.Bool(true), } } diff --git a/internal/featuretests/v3/authorization_test.go b/internal/featuretests/v3/authorization_test.go index db9e76e3236..271e8a1ded5 100644 --- a/internal/featuretests/v3/authorization_test.go +++ b/internal/featuretests/v3/authorization_test.go @@ -24,6 +24,7 @@ import ( envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" envoy_filter_http_ext_authz_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_authz/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" envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" "google.golang.org/protobuf/types/known/durationpb" core_v1 "k8s.io/api/core/v1" @@ -51,6 +52,20 @@ func grpcCluster(name string) *envoy_filter_http_ext_authz_v3.ExtAuthz_GrpcServi } } +func httpCluster(name string) *envoy_filter_http_ext_authz_v3.ExtAuthz_HttpService { + return &envoy_filter_http_ext_authz_v3.ExtAuthz_HttpService{ + HttpService: &envoy_filter_http_ext_authz_v3.HttpService{ + ServerUri: &envoy_config_core_v3.HttpUri{ + Uri: "http://dummy/", + HttpUpstreamType: &envoy_config_core_v3.HttpUri_Cluster{ + Cluster: name, + }, + Timeout: durationpb.New(defaultResponseTimeout), + }, + }, + } +} + func authzResponseTimeout(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { const fqdn = "failopen.projectcontour.io" @@ -62,6 +77,7 @@ func authzResponseTimeout(t *testing.T, rh ResourceEventHandlerWrapper, c *Conto Namespace: "auth", Name: "extension", }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, ResponseTimeout: "10m", }). WithSpec(contour_v1.HTTPProxySpec{ @@ -120,6 +136,7 @@ func authzInvalidResponseTimeout(t *testing.T, rh ResourceEventHandlerWrapper, c Namespace: "auth", Name: "extension", }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, ResponseTimeout: "invalid-timeout", }). WithSpec(contour_v1.HTTPProxySpec{ @@ -147,7 +164,8 @@ func authzFailOpen(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { Namespace: "auth", Name: "extension", }, - FailOpen: true, + ServiceAPIType: contour_v1.AuthorizationGRPCService, + FailOpen: true, }). WithSpec(contour_v1.HTTPProxySpec{ Routes: []contour_v1.Route{{ @@ -199,6 +217,7 @@ func authzFallbackIncompat(t *testing.T, rh ResourceEventHandlerWrapper, c *Cont Namespace: "auth", Name: "extension", }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, }). WithSpec(contour_v1.HTTPProxySpec{ Routes: []contour_v1.Route{{ @@ -230,6 +249,7 @@ func authzOverrideDisabled(t *testing.T, rh ResourceEventHandlerWrapper, c *Cont WithCertificate("certificate"). WithAuthServer(contour_v1.AuthorizationServer{ ExtensionServiceRef: extensionRef, + ServiceAPIType: contour_v1.AuthorizationGRPCService, AuthPolicy: &contour_v1.AuthorizationPolicy{Disabled: false}, }). WithSpec(contour_v1.HTTPProxySpec{ @@ -249,6 +269,7 @@ func authzOverrideDisabled(t *testing.T, rh ResourceEventHandlerWrapper, c *Cont WithCertificate("certificate"). WithAuthServer(contour_v1.AuthorizationServer{ ExtensionServiceRef: extensionRef, + ServiceAPIType: contour_v1.AuthorizationGRPCService, AuthPolicy: &contour_v1.AuthorizationPolicy{Disabled: true}, }). WithSpec(contour_v1.HTTPProxySpec{ @@ -340,6 +361,7 @@ func authzMergeRouteContext(t *testing.T, rh ResourceEventHandlerWrapper, c *Con Namespace: "auth", Name: "extension", }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, AuthPolicy: &contour_v1.AuthorizationPolicy{ Context: map[string]string{ "root-element": "root", @@ -419,7 +441,9 @@ func authzInvalidReference(t *testing.T, rh ResourceEventHandlerWrapper, c *Cont invalid := fixture.NewProxy("proxy"). WithFQDN(fqdn). WithCertificate("certificate"). - WithAuthServer(contour_v1.AuthorizationServer{}). + WithAuthServer(contour_v1.AuthorizationServer{ + ServiceAPIType: contour_v1.AuthorizationGRPCService, + }). WithSpec(contour_v1.HTTPProxySpec{ Routes: []contour_v1.Route{{ Services: []contour_v1.Service{{ @@ -509,7 +533,8 @@ func authzWithRequestBodyBufferSettings(t *testing.T, rh ResourceEventHandlerWra Namespace: "auth", Name: "extension", }, - FailOpen: true, + ServiceAPIType: contour_v1.AuthorizationGRPCService, + FailOpen: true, WithRequestBody: &contour_v1.AuthorizationServerBufferSettings{ MaxRequestBytes: 100, AllowPartialMessage: true, @@ -562,16 +587,440 @@ func authzWithRequestBodyBufferSettings(t *testing.T, rh ResourceEventHandlerWra }).Status(p).IsValid() } +func AuthzTypeGRPC(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + const fqdn = "typegrpc.projectcontour.io" + + p := fixture.NewProxy("proxy"). + WithFQDN(fqdn). + WithCertificate("certificate"). + WithAuthServer(contour_v1.AuthorizationServer{ + ExtensionServiceRef: contour_v1.ExtensionServiceReference{ + Namespace: "auth", + Name: "extension", + }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, + }). + WithSpec(contour_v1.HTTPProxySpec{ + Routes: []contour_v1.Route{{ + Services: []contour_v1.Service{{ + Name: "app-server", + Port: 80, + }}, + }}, + }) + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, + defaultHTTPListener(), + &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(fqdn, featuretests.TLSSecret(t, "certificate", &featuretests.ServerCertificate), + authzFilterFor( + fqdn, + &envoy_filter_http_ext_authz_v3.ExtAuthz{ + Services: grpcCluster("extension/auth/extension"), + ClearRouteCache: true, + FailureModeAllow: false, + 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(), + }, + statsListener()), + }).Status(p).IsValid() +} + +func authzTypeHTTP(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + const fqdn = "typehttp.projectcontour.io" + + p := fixture.NewProxy("proxy"). + WithFQDN(fqdn). + WithCertificate("certificate"). + WithAuthServer(contour_v1.AuthorizationServer{ + ExtensionServiceRef: contour_v1.ExtensionServiceReference{ + Namespace: "auth", + Name: "extension", + }, + ServiceAPIType: contour_v1.AuthorizationHTTPService, + }). + WithSpec(contour_v1.HTTPProxySpec{ + Routes: []contour_v1.Route{{ + Services: []contour_v1.Service{{ + Name: "app-server", + Port: 80, + }}, + }}, + }) + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, + defaultHTTPListener(), + &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(fqdn, featuretests.TLSSecret(t, "certificate", &featuretests.ServerCertificate), + authzFilterFor( + fqdn, + &envoy_filter_http_ext_authz_v3.ExtAuthz{ + Services: httpCluster("extension/auth/extension"), + ClearRouteCache: true, + FailureModeAllow: false, + 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(), + }, + statsListener()), + }).Status(p).IsValid() +} + +func AuthzTypeHTTPWithPathPrefix(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + const fqdn = "typehttp.projectcontour.io" + + p := fixture.NewProxy("proxy"). + WithFQDN(fqdn). + WithCertificate("certificate"). + WithAuthServer(contour_v1.AuthorizationServer{ + ExtensionServiceRef: contour_v1.ExtensionServiceReference{ + Namespace: "auth", + Name: "extension", + }, + ServiceAPIType: contour_v1.AuthorizationHTTPService, + HTTPServerSettings: &contour_v1.HTTPAuthorizationServerSettings{ + PathPrefix: "/auth?", + }, + }). + WithSpec(contour_v1.HTTPProxySpec{ + Routes: []contour_v1.Route{{ + Services: []contour_v1.Service{{ + Name: "app-server", + Port: 80, + }}, + }}, + }) + + rh.OnDelete(p) + rh.OnAdd(p) + + cluster := httpCluster("extension/auth/extension") + cluster.HttpService.PathPrefix = "/auth?" + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, + defaultHTTPListener(), + &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(fqdn, featuretests.TLSSecret(t, "certificate", &featuretests.ServerCertificate), + authzFilterFor( + fqdn, + &envoy_filter_http_ext_authz_v3.ExtAuthz{ + Services: cluster, + ClearRouteCache: true, + FailureModeAllow: false, + 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(), + }, + statsListener()), + }).Status(p).IsValid() +} + +func AuthzTypeHTTPWithAllowedAuthorizationHeaders(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + const fqdn = "typehttp.projectcontour.io" + + p := fixture.NewProxy("proxy"). + WithFQDN(fqdn). + WithCertificate("certificate"). + WithAuthServer(contour_v1.AuthorizationServer{ + ExtensionServiceRef: contour_v1.ExtensionServiceReference{ + Namespace: "auth", + Name: "extension", + }, + ServiceAPIType: contour_v1.AuthorizationHTTPService, + }). + WithSpec(contour_v1.HTTPProxySpec{ + Routes: []contour_v1.Route{{ + Services: []contour_v1.Service{{ + Name: "app-server", + Port: 80, + }}, + }}, + }) + + p.Spec.VirtualHost.Authorization.HTTPServerSettings = &contour_v1.HTTPAuthorizationServerSettings{ + AllowedAuthorizationHeaders: []contour_v1.HTTPAuthorizationServerAllowedHeaders{ + {IgnoreCase: false}, + }, + } + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, statsListener()), + }).Status(p).HasError(contour_v1.ConditionTypeAuthError, "AuthBadAllowedHeader", `one of prefix, suffix, exact or contains is required for each allowedHeader`) + + p.Spec.VirtualHost.Authorization.HTTPServerSettings = &contour_v1.HTTPAuthorizationServerSettings{ + AllowedAuthorizationHeaders: []contour_v1.HTTPAuthorizationServerAllowedHeaders{ + {Exact: "test", Prefix: "test", IgnoreCase: false}, + }, + } + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, statsListener()), + }).Status(p).HasError(contour_v1.ConditionTypeAuthError, "AuthBadAllowedHeader", `more than one prefix, suffix, exact or contains is not allowed in an allowedHeader`) + + p.Spec.VirtualHost.Authorization.HTTPServerSettings = &contour_v1.HTTPAuthorizationServerSettings{ + AllowedAuthorizationHeaders: []contour_v1.HTTPAuthorizationServerAllowedHeaders{ + {Prefix: "test1", IgnoreCase: false}, + {Exact: "test2", IgnoreCase: true}, + }, + } + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, + defaultHTTPListener(), + &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(fqdn, featuretests.TLSSecret(t, "certificate", &featuretests.ServerCertificate), + authzFilterFor( + fqdn, + &envoy_filter_http_ext_authz_v3.ExtAuthz{ + Services: httpCluster("extension/auth/extension"), + AllowedHeaders: &envoy_matcher_v3.ListStringMatcher{ + Patterns: []*envoy_matcher_v3.StringMatcher{ + {MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{Prefix: "test1"}, IgnoreCase: false}, + {MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{Exact: "test2"}, IgnoreCase: true}, + }, + }, + ClearRouteCache: true, + FailureModeAllow: false, + 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(), + }, + statsListener()), + }).Status(p).IsValid() +} + +func AuthzTypeHTTPWithAllowedUpstreamHeaders(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + const fqdn = "typehttp.projectcontour.io" + + p := fixture.NewProxy("proxy"). + WithFQDN(fqdn). + WithCertificate("certificate"). + WithAuthServer(contour_v1.AuthorizationServer{ + ExtensionServiceRef: contour_v1.ExtensionServiceReference{ + Namespace: "auth", + Name: "extension", + }, + ServiceAPIType: contour_v1.AuthorizationHTTPService, + }). + WithSpec(contour_v1.HTTPProxySpec{ + Routes: []contour_v1.Route{{ + Services: []contour_v1.Service{{ + Name: "app-server", + Port: 80, + }}, + }}, + }) + + p.Spec.VirtualHost.Authorization.HTTPServerSettings = &contour_v1.HTTPAuthorizationServerSettings{ + AllowedUpstreamHeaders: []contour_v1.HTTPAuthorizationServerAllowedHeaders{ + {IgnoreCase: false}, + }, + } + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, statsListener()), + }).Status(p).HasError(contour_v1.ConditionTypeAuthError, "AuthBadAllowedHeader", `one of prefix, suffix, exact or contains is required for each allowedHeader`) + + p.Spec.VirtualHost.Authorization.HTTPServerSettings = &contour_v1.HTTPAuthorizationServerSettings{ + AllowedUpstreamHeaders: []contour_v1.HTTPAuthorizationServerAllowedHeaders{ + {Exact: "test", Prefix: "test", IgnoreCase: false}, + }, + } + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, statsListener()), + }).Status(p).HasError(contour_v1.ConditionTypeAuthError, "AuthBadAllowedHeader", `more than one prefix, suffix, exact or contains is not allowed in an allowedHeader`) + + p.Spec.VirtualHost.Authorization.HTTPServerSettings = &contour_v1.HTTPAuthorizationServerSettings{ + AllowedUpstreamHeaders: []contour_v1.HTTPAuthorizationServerAllowedHeaders{ + {Prefix: "test1", IgnoreCase: false}, + {Exact: "test2", IgnoreCase: true}, + }, + } + + rh.OnDelete(p) + rh.OnAdd(p) + + cluster := httpCluster("extension/auth/extension") + cluster.HttpService.AuthorizationResponse = &envoy_filter_http_ext_authz_v3.AuthorizationResponse{ + AllowedUpstreamHeaders: &envoy_matcher_v3.ListStringMatcher{ + Patterns: []*envoy_matcher_v3.StringMatcher{ + {MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{Prefix: "test1"}, IgnoreCase: false}, + {MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{Exact: "test2"}, IgnoreCase: true}, + }, + }, + } + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, + defaultHTTPListener(), + &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(fqdn, featuretests.TLSSecret(t, "certificate", &featuretests.ServerCertificate), + authzFilterFor( + fqdn, + &envoy_filter_http_ext_authz_v3.ExtAuthz{ + Services: cluster, + ClearRouteCache: true, + FailureModeAllow: false, + 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(), + }, + statsListener()), + }).Status(p).IsValid() +} + +func AuthzTypeHTTPWithContext(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { + const fqdn = "typehttp.projectcontour.io" + + p := fixture.NewProxy("proxy"). + WithFQDN(fqdn). + WithCertificate("certificate"). + WithAuthServer(contour_v1.AuthorizationServer{ + ExtensionServiceRef: contour_v1.ExtensionServiceReference{ + Namespace: "auth", + Name: "extension", + }, + ServiceAPIType: contour_v1.AuthorizationHTTPService, + AuthPolicy: &contour_v1.AuthorizationPolicy{ + Context: map[string]string{ + "k1": "v1", + "k2": "v2", + }, + }, + }). + WithSpec(contour_v1.HTTPProxySpec{ + Routes: []contour_v1.Route{{ + Services: []contour_v1.Service{{ + Name: "app-server", + Port: 80, + }}, + }}, + }) + + rh.OnDelete(p) + rh.OnAdd(p) + + c.Request(listenerType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: listenerType, + Resources: resources(t, statsListener()), + }).Status(p).HasError(contour_v1.ConditionTypeAuthError, "AuthContextForHTTP", `Spec.Virtualhost.Authorization.AuthPolicy.Context are only applied to grpc service type`) +} + func TestAuthorization(t *testing.T) { subtests := map[string]func(*testing.T, ResourceEventHandlerWrapper, *Contour){ - "MissingExtension": authzInvalidReference, - "MergeRouteContext": authzMergeRouteContext, - "OverrideDisabled": authzOverrideDisabled, - "FallbackIncompat": authzFallbackIncompat, - "FailOpen": authzFailOpen, - "ResponseTimeout": authzResponseTimeout, - "InvalidResponseTimeout": authzInvalidResponseTimeout, - "AuthzWithRequestBodyBufferSettings": authzWithRequestBodyBufferSettings, + "MissingExtension": authzInvalidReference, + "MergeRouteContext": authzMergeRouteContext, + "OverrideDisabled": authzOverrideDisabled, + "FallbackIncompat": authzFallbackIncompat, + "FailOpen": authzFailOpen, + "ResponseTimeout": authzResponseTimeout, + "InvalidResponseTimeout": authzInvalidResponseTimeout, + "AuthzWithRequestBodyBufferSettings": authzWithRequestBodyBufferSettings, + "AuthzTypeGRPC": AuthzTypeGRPC, + "AuthzTypeHTTP": authzTypeHTTP, + "AuthzTypeHTTPWithPathPrefix": AuthzTypeHTTPWithPathPrefix, + "AuthzTypeHTTPWithAllowedAuthorizationHeaders": AuthzTypeHTTPWithAllowedAuthorizationHeaders, + "AuthzTypeHTTPWithAllowedUpstreamHeaders": AuthzTypeHTTPWithAllowedUpstreamHeaders, } for n, f := range subtests { diff --git a/internal/featuretests/v3/cluster_test.go b/internal/featuretests/v3/cluster_test.go index 2680585ba4b..ccb5a6a34a0 100644 --- a/internal/featuretests/v3/cluster_test.go +++ b/internal/featuretests/v3/cluster_test.go @@ -63,7 +63,7 @@ func TestClusterLongServiceName(t *testing.T) { // check that it's been translated correctly. c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ Resources: resources(t, - cluster("default/kbujbkuh-c83ceb/8080/da39a3ee5e", "default/kbujbkuhdod66gjdmwmijz8xzgsx1nkfbrloezdjiulquzk4x3p0nnvpzi8r", "default_kbujbkuhdod66gjdmwmijz8xzgsx1nkfbrloezdjiulquzk4x3p0nnvpzi8r_8080"), + cluster("default/kbujbkuhdod66gjdmwmijz8xzgsx1nkfbrloezdjiulquzk4x3p0nnvpzi8r/8080/da39a3ee5e", "default/kbujbkuhdod66gjdmwmijz8xzgsx1nkfbrloezdjiulquzk4x3p0nnvpzi8r", "default_kbujbkuhdod66gjdmwmijz8xzgsx1nkfbrloezdjiulquzk4x3p0nnvpzi8r_8080"), ), TypeUrl: clusterType, }) diff --git a/internal/featuretests/v3/envoy.go b/internal/featuretests/v3/envoy.go index 7b4d1ca8501..a4700a9ffc0 100644 --- a/internal/featuretests/v3/envoy.go +++ b/internal/featuretests/v3/envoy.go @@ -243,6 +243,20 @@ func h2cCluster(c *envoy_config_cluster_v3.Cluster) *envoy_config_cluster_v3.Clu return c } +func http1Cluster(c *envoy_config_cluster_v3.Cluster) *envoy_config_cluster_v3.Cluster { + c.TypedExtensionProtocolOptions = map[string]*anypb.Any{ + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": protobuf.MustMarshalAny( + &envoy_upstream_http_v3.HttpProtocolOptions{ + UpstreamProtocolOptions: &envoy_upstream_http_v3.HttpProtocolOptions_ExplicitHttpConfig_{ + ExplicitHttpConfig: &envoy_upstream_http_v3.HttpProtocolOptions_ExplicitHttpConfig{ + ProtocolConfig: &envoy_upstream_http_v3.HttpProtocolOptions_ExplicitHttpConfig_HttpProtocolOptions{}, + }, + }, + }), + } + return c +} + func withConnectionTimeout(c *envoy_config_cluster_v3.Cluster, timeout time.Duration, httpVersion envoy_v3.HTTPVersionType) *envoy_config_cluster_v3.Cluster { var config *envoy_upstream_http_v3.HttpProtocolOptions_ExplicitHttpConfig diff --git a/internal/featuretests/v3/extensionservice_test.go b/internal/featuretests/v3/extensionservice_test.go index b341882e4d7..f039894099d 100644 --- a/internal/featuretests/v3/extensionservice_test.go +++ b/internal/featuretests/v3/extensionservice_test.go @@ -78,7 +78,7 @@ func extBasic(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { } func extCleartext(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { - rh.OnAdd(&contour_v1alpha1.ExtensionService{ + es := &contour_v1alpha1.ExtensionService{ ObjectMeta: fixture.ObjectMeta("ns/ext"), Spec: contour_v1alpha1.ExtensionServiceSpec{ Protocol: ptr.To("h2c"), @@ -87,7 +87,9 @@ func extCleartext(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { {Name: "svc2", Port: 8082}, }, }, - }) + } + + rh.OnAdd(es) c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ TypeUrl: clusterType, @@ -97,6 +99,20 @@ func extCleartext(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { ), ), }) + + es.Spec.Protocol = ptr.To("http/1.1") + + rh.OnDelete(es) + rh.OnAdd(es) + + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, + Resources: resources(t, + DefaultCluster( + http1Cluster(cluster("extension/ns/ext", "extension/ns/ext", "extension_ns_ext")), + ), + ), + }) } func extUpstreamValidation(t *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { @@ -313,7 +329,7 @@ func extInvalidTimeout(_ *testing.T, rh ResourceEventHandlerWrapper, c *Contour) } func extInconsistentProto(_ *testing.T, rh ResourceEventHandlerWrapper, c *Contour) { - rh.OnAdd(&contour_v1alpha1.ExtensionService{ + es := &contour_v1alpha1.ExtensionService{ ObjectMeta: fixture.ObjectMeta("ns/ext"), Spec: contour_v1alpha1.ExtensionServiceSpec{ Services: []contour_v1alpha1.ExtensionServiceTarget{ @@ -325,8 +341,20 @@ func extInconsistentProto(_ *testing.T, rh ResourceEventHandlerWrapper, c *Conto SubjectName: "ext.projectcontour.io", }, }, + } + + rh.OnAdd(es) + + // Should have no clusters because Protocol and UpstreamValidation is inconsistent. + c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ + TypeUrl: clusterType, }) + es.Spec.Protocol = ptr.To("h1") + + rh.OnDelete(es) + rh.OnAdd(es) + // Should have no clusters because Protocol and UpstreamValidation is inconsistent. c.Request(clusterType).Equals(&envoy_service_discovery_v3.DiscoveryResponse{ TypeUrl: clusterType, diff --git a/internal/featuretests/v3/global_authorization_test.go b/internal/featuretests/v3/global_authorization_test.go index b5ad014d377..ed881181097 100644 --- a/internal/featuretests/v3/global_authorization_test.go +++ b/internal/featuretests/v3/global_authorization_test.go @@ -47,6 +47,7 @@ var ( Name: "extension", Namespace: "auth", }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, FailOpen: false, ResponseTimeout: defaultResponseTimeout.String(), AuthPolicy: &contour_v1.AuthorizationPolicy{ @@ -62,6 +63,7 @@ var ( Name: "extension", Namespace: "auth", }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, FailOpen: false, ResponseTimeout: defaultResponseTimeout.String(), AuthPolicy: &contour_v1.AuthorizationPolicy{ @@ -580,6 +582,7 @@ func globalExternalAuthorizationWithTLSAuthOverride(t *testing.T, rh ResourceEve Namespace: "auth", Name: "extension", }, + ServiceAPIType: contour_v1.AuthorizationGRPCService, ResponseTimeout: defaultResponseTimeout.String(), FailOpen: true, WithRequestBody: &contour_v1.AuthorizationServerBufferSettings{ @@ -800,7 +803,8 @@ func TestGlobalAuthorization(t *testing.T) { ExtensionService: k8s.NamespacedNameFrom("auth/extension"), Timeout: timeout.DurationSetting(defaultResponseTimeout), }, - FailOpen: false, + ServiceAPIType: contour_v1.AuthorizationGRPCService, + FailOpen: false, Context: map[string]string{ "header_type": "root_config", "header_1": "message_1", diff --git a/internal/featuretests/v3/routesourcemetadata_test.go b/internal/featuretests/v3/routesourcemetadata_test.go index e03305851a6..6505e334a92 100644 --- a/internal/featuretests/v3/routesourcemetadata_test.go +++ b/internal/featuretests/v3/routesourcemetadata_test.go @@ -95,6 +95,9 @@ func TestRouteSourceMetadataIsSet(t *testing.T) { }, }, }, + Decorator: &envoy_config_route_v3.Decorator{ + Operation: "ingress-kuard", + }, }), ), ), @@ -140,6 +143,9 @@ func TestRouteSourceMetadataIsSet(t *testing.T) { }, }, }, + Decorator: &envoy_config_route_v3.Decorator{ + Operation: "httpproxy-kuard", + }, }), ), ), @@ -192,6 +198,9 @@ func TestRouteSourceMetadataIsSet(t *testing.T) { }, }, }, + Decorator: &envoy_config_route_v3.Decorator{ + Operation: "httproute-kuard", + }, }), ), ), diff --git a/internal/xdscache/v3/cluster_test.go b/internal/xdscache/v3/cluster_test.go index b370948c6e8..4f0113e15b6 100644 --- a/internal/xdscache/v3/cluster_test.go +++ b/internal/xdscache/v3/cluster_test.go @@ -306,7 +306,7 @@ func TestClusterVisit(t *testing.T) { }, want: clustermap( &envoy_config_cluster_v3.Cluster{ - Name: "beurocra-7fe4b4/tiny-cog-7fe4b4/443/da39a3ee5e", + Name: "beurocratic-company-test-domain-1/tiny-cog-department-test-instance/443/da39a3ee5e", AltStatName: "beurocratic-company-test-domain-1_tiny-cog-department-test-instance_443", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_config_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_config_cluster_v3.Cluster_EdsClusterConfig{ diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go index 6176fdcaad0..d3196ee766b 100644 --- a/internal/xdscache/v3/listener.go +++ b/internal/xdscache/v3/listener.go @@ -23,8 +23,10 @@ import ( envoy_transport_socket_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" resource "github.com/envoyproxy/go-control-plane/pkg/resource/v3" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/wrapperspb" "k8s.io/apimachinery/pkg/types" + contour_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" contour_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" "github.com/projectcontour/contour/internal/contour" "github.com/projectcontour/contour/internal/contourconfig" @@ -150,6 +152,9 @@ type ListenerConfig struct { // SocketOptions configures socket options HTTP and HTTPS listeners. SocketOptions *contour_v1alpha1.SocketOptions + + // MaxConnectionsToAcceptPerSocketEvent defines how many new connections to accept per socket event loop iteration. + MaxConnectionsToAcceptPerSocketEvent *uint32 } type ExtensionServiceConfig struct { @@ -196,9 +201,13 @@ type RateLimitConfig struct { type GlobalExternalAuthConfig struct { ExtensionServiceConfig - FailOpen bool - Context map[string]string - WithRequestBody *dag.AuthorizationServerBufferSettings + FailOpen bool + Context map[string]string + ServiceAPIType contour_v1.AuthorizationServiceAPIType + HTTPAllowedAuthorizationHeaders []contour_v1.HTTPAuthorizationServerAllowedHeaders + HTTPAllowedUpstreamHeaders []contour_v1.HTTPAuthorizationServerAllowedHeaders + HTTPPathPrefix string + WithRequestBody *dag.AuthorizationServerBufferSettings } // httpAccessLog returns the access log for the HTTP (non TLS) @@ -493,7 +502,11 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { filters = envoy_v3.Filters(cm) - alpnProtos = envoy_v3.ProtoNamesForVersions(cfg.DefaultHTTPVersions...) + if len(vh.HTTPVersions) != 0 { + alpnProtos = vh.HTTPVersions + } else { + alpnProtos = envoy_v3.ProtoNamesForVersions(cfg.DefaultHTTPVersions...) + } } else { filters = envoy_v3.Filters(envoy_v3.TCPProxy(listener.Name, vh.TCPProxy, cfg.newSecureAccessLog())) @@ -602,6 +615,13 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { } } + // 2. max_connections_to_accept_per_socket_event + if cfg.MaxConnectionsToAcceptPerSocketEvent != nil { + for _, listener := range listeners { + listener.MaxConnectionsToAcceptPerSocketEvent = wrapperspb.UInt32(*cfg.MaxConnectionsToAcceptPerSocketEvent) + } + } + c.Update(listeners) } @@ -615,6 +635,10 @@ func httpGlobalExternalAuthConfig(config *GlobalExternalAuthConfig) *envoy_filte Name: dag.ExtensionClusterName(config.ExtensionServiceConfig.ExtensionService), SNI: config.ExtensionServiceConfig.SNI, }, + ServiceAPIType: config.ServiceAPIType, + HTTPAllowedAuthorizationHeaders: config.HTTPAllowedAuthorizationHeaders, + HTTPAllowedUpstreamHeaders: config.HTTPAllowedUpstreamHeaders, + HTTPPathPrefix: config.HTTPPathPrefix, AuthorizationFailOpen: config.FailOpen, AuthorizationResponseTimeout: config.ExtensionServiceConfig.Timeout, AuthorizationServerWithRequestBody: config.WithRequestBody, diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go index 04931c8d349..e38e5d87812 100644 --- a/pkg/config/parameters.go +++ b/pkg/config/parameters.go @@ -528,6 +528,11 @@ type ListenerParameters struct { // // +optional MaxConnectionsPerListener *uint32 `yaml:"max-connections-per-listener,omitempty"` + + // MaxConnectionsToAcceptPerSocketEvent defines the maximum number of connections + // Envoy will accept from the kernel per socket event. + // See: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto + MaxConnectionsToAcceptPerSocketEvent *uint32 `yaml:"max-connections-to-accept-per-socket-event,omitempty"` } func (p *ListenerParameters) Validate() error { @@ -559,6 +564,10 @@ func (p *ListenerParameters) Validate() error { return fmt.Errorf("invalid max connections per listener value %q set on listener, minimum value is 1", *p.MaxConnectionsPerListener) } + if p.MaxConnectionsToAcceptPerSocketEvent != nil && *p.MaxConnectionsToAcceptPerSocketEvent == 0 { + return fmt.Errorf("max-connections-to-accept-per-socket-event must be greater than 0") + } + return p.SocketOptions.Validate() } @@ -761,11 +770,21 @@ type CustomTag struct { RequestHeaderName string `yaml:"requestHeaderName,omitempty"` } -// GlobalExternalAuthorizationConfig defines properties of global external authorization. +// GlobalExternalAuthorization defines properties of global external authorization. type GlobalExternalAuthorization struct { // ExtensionService identifies the extension service defining the RLS, // formatted as /. ExtensionService string `yaml:"extensionService,omitempty"` + // ServiceAPIType defines the external authorization service API type. + // It indicates the protocol implemented by the external server, specifying whether it's a raw HTTP authorization server + // or a gRPC authorization server. + // + // +optional + ServiceAPIType contour_v1.AuthorizationServiceAPIType `json:"serviceAPIType,omitempty"` + // HttpAuthorizationServerSettings defines configurations for interacting with an external HTTP authorization server. + // + // +optional + HTTPServerSettings *contour_v1.HTTPAuthorizationServerSettings `json:"httpSettings,omitempty"` // AuthPolicy sets a default authorization policy for client requests. // This policy will be used unless overridden by individual routes. // diff --git a/site/content/docs/main/config/api-reference.html b/site/content/docs/main/config/api-reference.html index ad1062f70d4..068350fb46c 100644 --- a/site/content/docs/main/config/api-reference.html +++ b/site/content/docs/main/config/api-reference.html @@ -161,6 +161,22 @@

HTTPProxy is given precedence over this field.

+ + +httpVersions +
+ + +[]HTTPVersion + + + + +

HTTPVersions specify the http versions to offer for this HTTPProxy. +If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. +It is ignored when TCPProxy is set.

+ + @@ -361,6 +377,38 @@

AuthorizationServer +serviceAPIType +
+ + +AuthorizationServiceAPIType + + + + +(Optional) +

ServiceAPIType defines the external authorization service API type. +It indicates the protocol implemented by the external server, specifying whether it’s a raw HTTP authorization server +or a gRPC authorization server.

+ + + + +httpSettings +
+ + +HTTPAuthorizationServerSettings + + + + +(Optional) +

HTTPServerSettings defines configurations for interacting with an external HTTP authorization server.

+ + + + authPolicy
@@ -482,6 +530,28 @@

AuthorizationSer +

AuthorizationServiceAPIType +(string alias)

+

+(Appears on: +AuthorizationServer) +

+

+

AuthorizationServiceAPIType is an alias to enforce validation

+

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

"grpc"

"http"

CORSHeaderValue (string alias)

@@ -1281,6 +1351,159 @@

GlobalRateLimitPolicy +

HTTPAuthorizationServerAllowedHeaders +

+

+(Appears on: +HTTPAuthorizationServerSettings) +

+

+

HTTPAuthorizationServerAllowedHeaders specifies how to conditionally match against allowed headers +in the context of HTTP authorization. It includes options such as Exact, Prefix, Suffix, +Contains, and IgnoreCase to customize header matching criteria. However, regex support +is intentionally excluded to simplify the user experience and prevent potential issues. +One of Prefix, Exact, Suffix or Contains must be provided.

+

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

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

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

Prefix defines a prefix match for the header name.

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

Suffix defines a suffix match for a header name.

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

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

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

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

+
+

HTTPAuthorizationServerSettings +

+

+(Appears on: +AuthorizationServer) +

+

+

HTTPAuthorizationServerSettings defines configurations for interacting with an external HTTP authorization server.

+

+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+pathPrefix +
+ +string + +
+(Optional) +

PathPrefix Sets a prefix to the value of authorization request header Path.

+
+allowedAuthorizationHeaders +
+ + +[]HTTPAuthorizationServerAllowedHeaders + + +
+(Optional) +

AllowedAuthorizationHeaders specifies client request headers that will be sent to the authorization server. +Note that in addition to the user’s supplied matchers, Host, Method, Path, Content-Length, and Authorization are additionally included in the list.

+
+allowedUpstreamHeaders +
+ + +[]HTTPAuthorizationServerAllowedHeaders + + +
+(Optional) +

AllowedUpstreamHeaders specifies authorization response headers that will be added to the original client request. +Note that coexistent headers will be overridden.

+

HTTPDirectResponsePolicy

@@ -1616,6 +1839,22 @@

HTTPProxySpec is given precedence over this field.

+ + +httpVersions +
+ + +[]HTTPVersion + + + + +

HTTPVersions specify the http versions to offer for this HTTPProxy. +If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. +It is ignored when TCPProxy is set.

+ +

HTTPProxyStatus @@ -1850,6 +2089,15 @@

HTTPStatusRange +

HTTPVersion +(string alias)

+

+(Appears on: +HTTPProxySpec) +

+

+

HTTPVersion is an alias to enforce validation

+

HeaderHashOptions

@@ -5178,7 +5426,7 @@

ContourConfiguration -

Tracing defines properties for exporting trace data to OpenTelemetry.

+

Tracing defines properties for exporting trace data to the OpenTelemetry.

@@ -5438,7 +5686,7 @@

ExtensionService

Services specifies the set of Kubernetes Service resources that -receive GRPC extension API requests. +receive 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. @@ -5472,7 +5720,7 @@

ExtensionService (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.

+Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations.

@@ -5487,9 +5735,9 @@

ExtensionService (Optional) -

The policy for load balancing GRPC service requests. Note that the +

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

+here for GRPC service requests.

@@ -6071,7 +6319,7 @@

ContourConfiguratio -

Tracing defines properties for exporting trace data to OpenTelemetry.

+

Tracing defines properties for exporting trace data to the OpenTelemetry.

@@ -6810,6 +7058,19 @@

EnvoyConfig

Network holds various configurable Envoy network values.

+ + +enableStatPrefix +
+ +bool + + + +(Optional) +

Set StatPrefix on envoy routes

+ +

EnvoyListener @@ -7084,6 +7345,20 @@

EnvoyListenerConfig per listener. The default value when this is not set is unlimited.

+ + +maxConnectionsToAcceptPerSocketEvent +
+ +uint32 + + + +(Optional) +

MaxConnectionsToAcceptPerSocketEvent defines the maximum number of +connections Envoy will accept per socket event.

+ +

EnvoyLogging @@ -7545,7 +7820,7 @@

ExtensionServiceSpec

Services specifies the set of Kubernetes Service resources that -receive GRPC extension API requests. +receive 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. @@ -7579,7 +7854,7 @@

ExtensionServiceSpec (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.

+Values may be h2, h2c or http/1.1. If omitted, protocol-selection falls back on Service annotations.

@@ -7594,9 +7869,9 @@

ExtensionServiceSpec (Optional) -

The policy for load balancing GRPC service requests. Note that the +

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

+here for GRPC service requests.