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 HTTPProxy
is given precedence over this field.
httpVersions
+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.
+serviceAPIType
+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
+HTTPServerSettings defines configurations for interacting with an external HTTP authorization server.
+authPolicy
string alias)+(Appears on: +AuthorizationServer) +
++
AuthorizationServiceAPIType is an alias to enforce validation
+ +| Value | +Description | +
|---|---|
"grpc" |
++ |
"http" |
++ |
string alias)@@ -1281,6 +1351,159 @@
+(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.
+ +| Field | +Description | +
|---|---|
+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. + |
+
+(Appears on: +AuthorizationServer) +
++
HTTPAuthorizationServerSettings defines configurations for interacting with an external HTTP authorization server.
+ +| Field | +Description | +
|---|---|
+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. + |
+
@@ -1616,6 +1839,22 @@
httpVersions
+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.
+string alias)+(Appears on: +HTTPProxySpec) +
++
HTTPVersion is an alias to enforce validation
+@@ -5178,7 +5426,7 @@
Tracing defines properties for exporting trace data to OpenTelemetry.
+Tracing defines properties for exporting trace data to the OpenTelemetry.
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 @@
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.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.
Tracing defines properties for exporting trace data to OpenTelemetry.
+Tracing defines properties for exporting trace data to the OpenTelemetry.
Network holds various configurable Envoy network values.
enableStatPrefix
+Set StatPrefix on envoy routes
+maxConnectionsToAcceptPerSocketEvent
+MaxConnectionsToAcceptPerSocketEvent defines the maximum number of +connections Envoy will accept per socket event.
+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 @@
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.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.