diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index c61b03d74fd..a03fe40a02a 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -20,7 +20,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps # Generate the install manifests first so it can checked # for errors while running `make -k lint` @@ -31,21 +31,21 @@ jobs: gen-check: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - run: make -k gen-check license-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - run: make -k licensecheck coverage-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps # test @@ -63,14 +63,14 @@ jobs: runs-on: ubuntu-latest needs: [lint, gen-check, license-check, coverage-test] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - name: Build EG Multiarch Binaries run: make build-multiarch PLATFORMS="linux_amd64 linux_arm64" - name: Upload EG Binaries - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: envoy-gateway path: bin/ @@ -82,11 +82,11 @@ jobs: matrix: version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - name: Download EG Binaries - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: envoy-gateway path: bin/ @@ -110,11 +110,11 @@ jobs: matrix: version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - name: Download EG Binaries - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: envoy-gateway path: bin/ @@ -135,11 +135,11 @@ jobs: runs-on: ubuntu-latest needs: [conformance-test, e2e-test] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - name: Download EG Binaries - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: envoy-gateway path: bin/ @@ -174,4 +174,4 @@ jobs: - name: Build and Push EG Latest Helm Chart if: github.event_name == 'push' && github.ref == 'refs/heads/main' # use `0.0.0` as the default latest version. - run: OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=v0.0.0-latest TAG=latest make helm-package helm-push + run: IMAGE_PULL_POLICY=Always OCI_REGISTRY=oci://docker.io/envoyproxy CHART_VERSION=v0.0.0-latest TAG=latest make helm-package helm-push diff --git a/.github/workflows/cherrypick.yaml b/.github/workflows/cherrypick.yaml index cbceef0cb9e..bda95da1b33 100644 --- a/.github/workflows/cherrypick.yaml +++ b/.github/workflows/cherrypick.yaml @@ -6,17 +6,19 @@ on: types: ["closed"] permissions: - pull-requests: write - contents: write + contents: read jobs: cherry_pick_release_v1_0: + permissions: + pull-requests: write + contents: write runs-on: ubuntu-22.04 name: Cherry pick into release-v1.0 if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v1.0') && github.event.pull_request.merged == true }} steps: - name: Checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 - name: Cherry pick into release/v1.0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ee983e5c1e4..bc69c913007 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,18 +32,18 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - name: Initialize CodeQL - uses: github/codeql-action/init@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 + uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 + uses: github/codeql-action/autobuild@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 + uses: github/codeql-action/analyze@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index a31eb04cd9c..28ec10e0b6b 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Check out code - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ github.event.pull_request.head.sha }} @@ -48,7 +48,7 @@ jobs: contents: write steps: - name: Git checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: submodules: true ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/experimental_conformance.yaml b/.github/workflows/experimental_conformance.yaml index 87dd94ae081..c7f00139f2c 100644 --- a/.github/workflows/experimental_conformance.yaml +++ b/.github/workflows/experimental_conformance.yaml @@ -20,7 +20,7 @@ jobs: matrix: version: [ v1.26.14, v1.27.11, v1.28.7, v1.29.2 ] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps # gateway api experimental conformance @@ -32,7 +32,7 @@ jobs: run: make experimental-conformance - name: Upload Conformance Report - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: conformance-report-k8s-${{ matrix.version }} path: ./test/conformance/conformance-report-k8s-${{ matrix.version }}.yaml diff --git a/.github/workflows/latest_release.yaml b/.github/workflows/latest_release.yaml index 55a14ebb106..de577267da3 100644 --- a/.github/workflows/latest_release.yaml +++ b/.github/workflows/latest_release.yaml @@ -22,7 +22,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - name: Generate Release Manifests diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml new file mode 100644 index 00000000000..035c12c0cda --- /dev/null +++ b/.github/workflows/osv-scanner.yml @@ -0,0 +1,33 @@ +name: OSV-Scanner + +on: + pull_request: + branches: + - "main" + merge_group: + branches: + - "main" + push: + branches: + - "main" + schedule: + - cron: '44 15 * * 5' + +permissions: + contents: read + +jobs: + scan-scheduled: + if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }} + uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@1f1242919d8a60496dd1874b24b62b2370ed4c78" # v1.7.1 + permissions: + contents: read + # Require writing security events to upload SARIF file to security tab + security-events: write + scan-pr: + if: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }} + uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@1f1242919d8a60496dd1874b24b62b2370ed4c78" # v1.7.1 + permissions: + contents: read + # Require writing security events to upload SARIF file to security tab + security-events: write diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 75d3111c32a..a104b0f1daf 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -15,7 +15,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Extract Release Tag and Commit SHA id: vars diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 55c8db20a7a..77c1a3dcb03 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -21,7 +21,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false @@ -33,13 +33,13 @@ jobs: publish_results: true - name: "Upload artifact" - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: SARIF file path: results.sarif retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: results.sarif diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 00000000000..87a7483f6d5 --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,31 @@ +name: Trivy + +on: + push: + branches: + - "main" + schedule: + - cron: '55 17 * * 5' + +permissions: + contents: read + +jobs: + image-scan: + permissions: + contents: read # for actions/checkout to fetch code + name: Image Scan + runs-on: ubuntu-22.04 + steps: + - name: Checkout code + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - name: Build an image from Dockerfile + run: | + IMAGE=envoy-proxy/gateway-dev TAG=${{ github.sha }} make image + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@d710430a6722f083d3b36b8339ff66b32f22ee55 # v0.19.0 + with: + image-ref: envoy-proxy/gateway-dev:${{ github.sha }} + exit-code: '1' diff --git a/README.md b/README.md index babe462ad38..25fa9af8d94 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/envoyproxy/gateway/badge)](https://securityscorecards.dev/viewer/?uri=github.com/envoyproxy/gateway) [![Build and Test](https://github.com/envoyproxy/gateway/actions/workflows/build_and_test.yaml/badge.svg)](https://github.com/envoyproxy/gateway/actions/workflows/build_and_test.yaml) [![codecov](https://codecov.io/gh/envoyproxy/gateway/branch/main/graph/badge.svg)](https://codecov.io/gh/envoyproxy/gateway) +[![CodeQL](https://github.com/envoyproxy/gateway/actions/workflows/codeql.yml/badge.svg)](https://github.com/envoyproxy/gateway/actions/workflows/codeql.yml) +[![OSV-Scanner](https://github.com/envoyproxy/gateway/actions/workflows/osv-scanner.yml/badge.svg)](https://github.com/envoyproxy/gateway/actions/workflows/osv-scanner.yml) +[![Trivy](https://github.com/envoyproxy/gateway/actions/workflows/trivy.yml/badge.svg)](https://github.com/envoyproxy/gateway/actions/workflows/trivy.yml) Envoy Gateway is an open source project for managing Envoy Proxy as a standalone or Kubernetes-based application gateway. @@ -12,8 +15,8 @@ Kubernetes-based application gateway. * [Blog][blog] introducing Envoy Gateway. * [Goals](GOALS.md) -* [Quickstart](https://gateway.envoyproxy.io/latest/user/quickstart/) to use Envoy Gateway in a few simple steps. -* [Roadmap](https://gateway.envoyproxy.io/latest/contributions/roadmap/) +* [Quickstart](https://gateway.envoyproxy.io/latest/tasks/quickstart/) to use Envoy Gateway in a few simple steps. +* [Roadmap](https://gateway.envoyproxy.io/contributions/roadmap/) ## Contact @@ -22,9 +25,9 @@ Kubernetes-based application gateway. ## Contributing -* [Code of conduct](https://gateway.envoyproxy.io/latest/contributions/code_of_conduct/) -* [Contributing guide](https://gateway.envoyproxy.io/latest/contributions/contributing/) -* [Developer guide](https://gateway.envoyproxy.io/latest/contributions/develop/) +* [Code of conduct](/CODE_OF_CONDUCT) +* [Contributing guide](https://gateway.envoyproxy.io/contributions/contributing/) +* [Developer guide](https://gateway.envoyproxy.io/contributions/develop/) ## Community Meeting diff --git a/api/v1alpha1/accesslogging_types.go b/api/v1alpha1/accesslogging_types.go index 48694edb2a7..e1311566eeb 100644 --- a/api/v1alpha1/accesslogging_types.go +++ b/api/v1alpha1/accesslogging_types.go @@ -5,8 +5,6 @@ package v1alpha1 -import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - type ProxyAccessLog struct { // Disable disables access logging for managed proxies if set to true. Disable bool `json:"disable,omitempty"` @@ -62,6 +60,10 @@ type ProxyAccessLogFormat struct { type ProxyAccessLogSinkType string const ( + // ProxyAccessLogSinkTypeALS defines the gRPC Access Log Service (ALS) sink. + // The service must implement the Envoy gRPC Access Log Service streaming API: + // https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto + ProxyAccessLogSinkTypeALS ProxyAccessLogSinkType = "ALS" // ProxyAccessLogSinkTypeFile defines the file accesslog sink. ProxyAccessLogSinkTypeFile ProxyAccessLogSinkType = "File" // ProxyAccessLogSinkTypeOpenTelemetry defines the OpenTelemetry accesslog sink. @@ -73,13 +75,17 @@ const ( // ProxyAccessLogSink defines the sink of accesslog. // +union // +// +kubebuilder:validation:XValidation:rule="self.type == 'ALS' ? has(self.als) : !has(self.als)",message="If AccessLogSink type is ALS, als field needs to be set." // +kubebuilder:validation:XValidation:rule="self.type == 'File' ? has(self.file) : !has(self.file)",message="If AccessLogSink type is File, file field needs to be set." // +kubebuilder:validation:XValidation:rule="self.type == 'OpenTelemetry' ? has(self.openTelemetry) : !has(self.openTelemetry)",message="If AccessLogSink type is OpenTelemetry, openTelemetry field needs to be set." type ProxyAccessLogSink struct { // Type defines the type of accesslog sink. - // +kubebuilder:validation:Enum=File;OpenTelemetry + // +kubebuilder:validation:Enum=ALS;File;OpenTelemetry // +unionDiscriminator Type ProxyAccessLogSinkType `json:"type,omitempty"` + // ALS defines the gRPC Access Log Service (ALS) sink. + // +optional + ALS *ALSEnvoyProxyAccessLog `json:"als,omitempty"` // File defines the file accesslog sink. // +optional File *FileEnvoyProxyAccessLog `json:"file,omitempty"` @@ -88,6 +94,59 @@ type ProxyAccessLogSink struct { OpenTelemetry *OpenTelemetryEnvoyProxyAccessLog `json:"openTelemetry,omitempty"` } +type ALSEnvoyProxyAccessLogType string + +const ( + // ALSEnvoyProxyAccessLogTypeHTTP defines the HTTP access log type and will populate StreamAccessLogsMessage.http_logs. + ALSEnvoyProxyAccessLogTypeHTTP ALSEnvoyProxyAccessLogType = "HTTP" + // ALSEnvoyProxyAccessLogTypeTCP defines the TCP access log type and will populate StreamAccessLogsMessage.tcp_logs. + ALSEnvoyProxyAccessLogTypeTCP ALSEnvoyProxyAccessLogType = "TCP" +) + +// ALSEnvoyProxyAccessLog defines the gRPC Access Log Service (ALS) sink. +// The service must implement the Envoy gRPC Access Log Service streaming API: +// https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto +// Access log format information is passed in the form of gRPC metadata when the +// stream is established. Specifically, the following metadata is passed: +// +// - `x-accesslog-text` - The access log format string when a Text format is used. +// - `x-accesslog-attr` - JSON encoded key/value pairs when a JSON format is used. +// +// +kubebuilder:validation:XValidation:rule="self.type == 'HTTP' || !has(self.http)",message="The http field may only be set when type is HTTP." +type ALSEnvoyProxyAccessLog struct { + // BackendRefs references a Kubernetes object that represents the gRPC service to which + // the access logs will be sent. Currently only Service is supported. + // + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="self.all(f, f.kind == 'Service')" + BackendRefs []BackendRef `json:"backendRefs"` + // LogName defines the friendly name of the access log to be returned in + // StreamAccessLogsMessage.Identifier. This allows the access log server + // to differentiate between different access logs coming from the same Envoy. + // +optional + // +kubebuilder:validation:MinLength=1 + LogName *string `json:"logName,omitempty"` + // Type defines the type of accesslog. Supported types are "HTTP" and "TCP". + // +kubebuilder:validation:Enum=HTTP;TCP + Type ALSEnvoyProxyAccessLogType `json:"type"` + // HTTP defines additional configuration specific to HTTP access logs. + // +optional + HTTP *ALSEnvoyProxyHTTPAccessLogConfig `json:"http,omitempty"` +} + +type ALSEnvoyProxyHTTPAccessLogConfig struct { + // RequestHeaders defines request headers to include in log entries sent to the access log service. + // +optional + RequestHeaders []string `json:"requestHeaders,omitempty"` + // ResponseHeaders defines response headers to include in log entries sent to the access log service. + // +optional + ResponseHeaders []string `json:"responseHeaders,omitempty"` + // ResponseTrailers defines response trailers to include in log entries sent to the access log service. + // +optional + ResponseTrailers []string `json:"responseTrailers,omitempty"` +} + type FileEnvoyProxyAccessLog struct { // Path defines the file path used to expose envoy access log(e.g. /dev/stdout). // +kubebuilder:validation:MinLength=1 @@ -96,11 +155,13 @@ type FileEnvoyProxyAccessLog struct { // OpenTelemetryEnvoyProxyAccessLog defines the OpenTelemetry access log sink. // -// +kubebuilder:validation:XValidation:message="BackendRef only support Service Kind.",rule="!has(self.backendRef) || !has(self.backendRef.kind) || self.backendRef.kind == 'Service'" +// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" type OpenTelemetryEnvoyProxyAccessLog struct { // Host define the extension service hostname. // Deprecated: Use BackendRef instead. - Host string `json:"host"` + // + // +optional + Host *string `json:"host,omitempty"` // Port defines the port the extension service is exposed on. // Deprecated: Use BackendRef instead. // @@ -108,12 +169,14 @@ type OpenTelemetryEnvoyProxyAccessLog struct { // +kubebuilder:validation:Minimum=0 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRef references a Kubernetes object that represents the + // BackendRefs references a Kubernetes object that represents the // backend server to which the accesslog will be sent. // Only service Kind is supported for now. // // +optional - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"` + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" + BackendRefs []BackendRef `json:"backendRefs,omitempty"` // Resources is a set of labels that describe the source of a log entry, including envoy node info. // It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). // +optional diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index b47deebc02c..4689fdfeea9 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -18,9 +18,8 @@ const ( // +kubebuilder:object:root=true // +kubebuilder:resource:categories=envoy-gateway,shortName=btp // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Accepted")].reason` // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` -// + // BackendTrafficPolicy allows the user to configure the behavior of the connection // between the Envoy Proxy listener and the backend service. type BackendTrafficPolicy struct { @@ -34,7 +33,7 @@ type BackendTrafficPolicy struct { Status gwapiv1a2.PolicyStatus `json:"status,omitempty"` } -// spec defines the desired state of BackendTrafficPolicy. +// BackendTrafficPolicySpec defines the desired state of BackendTrafficPolicy. type BackendTrafficPolicySpec struct { // +kubebuilder:validation:XValidation:rule="self.group == 'gateway.networking.k8s.io'", message="this policy can only have a targetRef.group of gateway.networking.k8s.io" // +kubebuilder:validation:XValidation:rule="self.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute', 'UDPRoute', 'TCPRoute', 'TLSRoute']", message="this policy can only have a targetRef.kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute" @@ -87,6 +86,13 @@ type BackendTrafficPolicySpec struct { // +optional Retry *Retry `json:"retry,omitempty"` + // UseClientProtocol configures Envoy to prefer sending requests to backends using + // the same HTTP protocol that the incoming request used. Defaults to false, which means + // that Envoy will use the protocol indicated by the attached BackendRef. + // + // +optional + UseClientProtocol *bool `json:"useClientProtocol,omitempty"` + // Timeout settings for the backend connections. // // +optional @@ -95,10 +101,12 @@ type BackendTrafficPolicySpec struct { // The compression config for the http streams. // // +optional + // +notImplementedHide Compression []*Compression `json:"compression,omitempty"` } // +kubebuilder:object:root=true + // BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources. type BackendTrafficPolicyList struct { metav1.TypeMeta `json:",inline"` diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index 619bbeb50f3..8f85d0617c7 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -6,6 +6,7 @@ package v1alpha1 import ( + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) @@ -18,7 +19,6 @@ const ( // +kubebuilder:object:root=true // +kubebuilder:resource:categories=envoy-gateway,shortName=ctp // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Accepted")].reason` // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` // ClientTrafficPolicy allows the user to configure the behavior of the connection @@ -63,22 +63,14 @@ type ClientTrafficPolicySpec struct { // // +optional ClientIPDetection *ClientIPDetectionSettings `json:"clientIPDetection,omitempty"` - // HTTP3 provides HTTP/3 configuration on the listener. - // - // +optional - HTTP3 *HTTP3Settings `json:"http3,omitempty"` // TLS settings configure TLS termination settings with the downstream client. // // +optional - TLS *TLSSettings `json:"tls,omitempty"` + TLS *ClientTLSSettings `json:"tls,omitempty"` // Path enables managing how the incoming path set by clients can be normalized. // // +optional Path *PathSettings `json:"path,omitempty"` - // HTTP1 provides HTTP/1 configuration on the listener. - // - // +optional - HTTP1 *HTTP1Settings `json:"http1,omitempty"` // HeaderSettings provides configuration for header management. // // +optional @@ -91,9 +83,21 @@ type ClientTrafficPolicySpec struct { // // +optional Connection *Connection `json:"connection,omitempty"` + // HTTP1 provides HTTP/1 configuration on the listener. + // + // +optional + HTTP1 *HTTP1Settings `json:"http1,omitempty"` + // HTTP2 provides HTTP/2 configuration on the listener. + // + // +optional + HTTP2 *HTTP2Settings `json:"http2,omitempty"` + // HTTP3 provides HTTP/3 configuration on the listener. + // + // +optional + HTTP3 *HTTP3Settings `json:"http3,omitempty"` } -// HeaderSettings providess configuration options for headers on the listener. +// HeaderSettings provides configuration options for headers on the listener. type HeaderSettings struct { // EnableEnvoyHeaders configures Envoy Proxy to add the "X-Envoy-" headers to requests // and responses. @@ -151,7 +155,7 @@ type XForwardedForSettings struct { NumTrustedHops *uint32 `json:"numTrustedHops,omitempty"` } -// CustomHeader provides configuration for determining the client IP address for a request based on +// CustomHeaderExtensionSettings provides configuration for determining the client IP address for a request based on // a trusted custom HTTP header. This uses the the custom_header original IP detection extension. // Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto // for more details. @@ -172,8 +176,7 @@ type CustomHeaderExtensionSettings struct { } // HTTP3Settings provides HTTP/3 configuration on the listener. -type HTTP3Settings struct { -} +type HTTP3Settings struct{} // HTTP1Settings provides HTTP/1 configuration on the listener. type HTTP1Settings struct { @@ -200,6 +203,30 @@ type HTTP10Settings struct { UseDefaultHost *bool `json:"useDefaultHost,omitempty"` } +// HTTP2Settings provides HTTP/2 configuration on the listener. +type HTTP2Settings struct { + // InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + // If not set, the default value is 64 KiB(64*1024). + // + // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +optional + InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"` + + // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + // If not set, the default value is 1 MiB. + // + // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +optional + InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"` + + // MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + // If not set, the default value is 100. + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=2147483647 + // +optional + MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty"` +} + const ( // PolicyConditionOverridden indicates whether the policy has // completely attached to all the sections within the target or not. diff --git a/api/v1alpha1/compression_types.go b/api/v1alpha1/compression_types.go index 37c0ec8587b..73cb0109ae5 100644 --- a/api/v1alpha1/compression_types.go +++ b/api/v1alpha1/compression_types.go @@ -13,8 +13,7 @@ type CompressorType string // GzipCompressor defines the config for the Gzip compressor. // The default values can be found here: // https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/compression/gzip/compressor/v3/gzip.proto#extension-envoy-compression-gzip-compressor -type GzipCompressor struct { -} +type GzipCompressor struct{} // Compression defines the config of enabling compression. // This can help reduce the bandwidth at the expense of higher CPU. diff --git a/api/v1alpha1/envoyextensionypolicy_types.go b/api/v1alpha1/envoyextensionypolicy_types.go index f4bb6aa9d56..76e863ce00d 100644 --- a/api/v1alpha1/envoyextensionypolicy_types.go +++ b/api/v1alpha1/envoyextensionypolicy_types.go @@ -18,7 +18,6 @@ const ( // +kubebuilder:object:root=true // +kubebuilder:resource:shortName=eep // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Accepted")].reason` // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` // EnvoyExtensionPolicy allows the user to configure various envoy extensibility options for the Gateway. @@ -39,22 +38,23 @@ type EnvoyExtensionPolicySpec struct { // +kubebuilder:validation:XValidation:rule="self.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute', 'UDPRoute', 'TCPRoute', 'TLSRoute']", message="this policy can only have a targetRef.kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute" // +kubebuilder:validation:XValidation:rule="!has(self.sectionName)",message="this policy does not yet support the sectionName field" // - // TargetRef is the name of the Gateway resource this policy + // TargetRef is the name of the resource this policy // is being attached to. // This Policy and the TargetRef MUST be in the same namespace - // for this Policy to have effect and be applied to the Gateway. - // TargetRef + // for this Policy to have effect and be applied to the Gateway or xRoute. TargetRef gwapiv1a2.PolicyTargetReferenceWithSectionName `json:"targetRef"` - // WASM is a list of Wasm extensions to be loaded by the Gateway. + // Wasm is a list of Wasm extensions to be loaded by the Gateway. // Order matters, as the extensions will be loaded in the order they are // defined in this list. // // +optional - WASM []Wasm `json:"wasm,omitempty"` + Wasm []Wasm `json:"wasm,omitempty"` // ExtProc is an ordered list of external processing filters // that should added to the envoy filter chain + // + // +optional ExtProc []ExtProc `json:"extProc,omitempty"` } diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go index 47b9861e170..3ae313dc409 100644 --- a/api/v1alpha1/envoygateway_types.go +++ b/api/v1alpha1/envoygateway_types.go @@ -354,6 +354,9 @@ type RateLimit struct { type RateLimitTelemetry struct { // Metrics defines metrics configuration for RateLimit. Metrics *RateLimitMetrics `json:"metrics,omitempty"` + + // Tracing defines traces configuration for RateLimit. + Tracing *RateLimitTracing `json:"tracing,omitempty"` } type RateLimitMetrics struct { @@ -366,6 +369,34 @@ type RateLimitMetricsPrometheusProvider struct { Disable bool `json:"disable,omitempty"` } +type RateLimitTracing struct { + // SamplingRate controls the rate at which traffic will be + // selected for tracing if no prior sampling decision has been made. + // Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. + // +optional + SamplingRate *uint32 `json:"samplingRate,omitempty"` + + // Provider defines the rateLimit tracing provider. + // Only OpenTelemetry is supported currently. + Provider *RateLimitTracingProvider `json:"provider,omitempty"` +} + +type RateLimitTracingProviderType string + +const ( + RateLimitTracingProviderTypeOpenTelemetry TracingProviderType = "OpenTelemetry" +) + +// RateLimitTracingProvider defines the tracing provider configuration of RateLimit +type RateLimitTracingProvider struct { + // Type defines the tracing provider type. + // Since to RateLimit Exporter currently using OpenTelemetry, only OpenTelemetry is supported + Type *RateLimitTracingProviderType `json:"type,omitempty"` + + // URL is the endpoint of the trace collector that supports the OTLP protocol + URL string `json:"url"` +} + // RateLimitDatabaseBackend defines the configuration associated with // the database backend used by the rate limit service. // +union @@ -475,7 +506,6 @@ type ExtensionTLS struct { // EnvoyGatewayAdmin defines the Envoy Gateway Admin configuration. type EnvoyGatewayAdmin struct { - // Address defines the address of Envoy Gateway Admin Server. // // +optional diff --git a/api/v1alpha1/envoyproxy_helpers.go b/api/v1alpha1/envoyproxy_helpers.go index c3461127153..2bcc086cbba 100644 --- a/api/v1alpha1/envoyproxy_helpers.go +++ b/api/v1alpha1/envoyproxy_helpers.go @@ -70,11 +70,20 @@ func (r *EnvoyProxyProvider) GetEnvoyProxyKubeProvider() *EnvoyProxyKubernetesPr return r.Kubernetes } - if r.Kubernetes.EnvoyDeployment == nil { + // if EnvoyDeployment and EnvoyDaemonSet are both nil, use EnvoyDeployment + if r.Kubernetes.EnvoyDeployment == nil && r.Kubernetes.EnvoyDaemonSet == nil { r.Kubernetes.EnvoyDeployment = DefaultKubernetesDeployment(DefaultEnvoyProxyImage) } - r.Kubernetes.EnvoyDeployment.defaultKubernetesDeploymentSpec(DefaultEnvoyProxyImage) + // if use EnvoyDeployment, set default values + if r.Kubernetes.EnvoyDeployment != nil { + r.Kubernetes.EnvoyDeployment.defaultKubernetesDeploymentSpec(DefaultEnvoyProxyImage) + } + + // if use EnvoyDaemonSet, set default values + if r.Kubernetes.EnvoyDaemonSet != nil { + r.Kubernetes.EnvoyDaemonSet.defaultKubernetesDaemonSetSpec(DefaultEnvoyProxyImage) + } if r.Kubernetes.EnvoyService == nil { r.Kubernetes.EnvoyService = DefaultKubernetesService() diff --git a/api/v1alpha1/envoyproxy_metric_types.go b/api/v1alpha1/envoyproxy_metric_types.go index 4c45df39e36..52b17cf627b 100644 --- a/api/v1alpha1/envoyproxy_metric_types.go +++ b/api/v1alpha1/envoyproxy_metric_types.go @@ -5,8 +5,6 @@ package v1alpha1 -import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - type MetricSinkType string const ( @@ -29,6 +27,10 @@ type ProxyMetrics struct { // EnableVirtualHostStats enables envoy stat metrics for virtual hosts. EnableVirtualHostStats bool `json:"enableVirtualHostStats,omitempty"` + + // EnablePerEndpointStats enables per endpoint envoy stats metrics. + // Please use with caution. + EnablePerEndpointStats bool `json:"enablePerEndpointStats,omitempty"` } // ProxyMetricSink defines the sink of metrics. @@ -51,11 +53,13 @@ type ProxyMetricSink struct { // ProxyOpenTelemetrySink defines the configuration for OpenTelemetry sink. // -// +kubebuilder:validation:XValidation:message="BackendRef only support Service Kind.",rule="!has(self.backendRef) || !has(self.backendRef.kind) || self.backendRef.kind == 'Service'" +// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" type ProxyOpenTelemetrySink struct { // Host define the service hostname. // Deprecated: Use BackendRef instead. - Host string `json:"host"` + // + // +optional + Host *string `json:"host,omitempty"` // Port defines the port the service is exposed on. // Deprecated: Use BackendRef instead. // @@ -64,12 +68,14 @@ type ProxyOpenTelemetrySink struct { // +kubebuilder:validation:Maximum=65535 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRef references a Kubernetes object that represents the + // BackendRefs references a Kubernetes object that represents the // backend server to which the metric will be sent. // Only service Kind is supported for now. // // +optional - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"` + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" + BackendRefs []BackendRef `json:"backendRefs,omitempty"` // TODO: add support for customizing OpenTelemetry sink in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto#envoy-v3-api-msg-extensions-stat-sinks-open-telemetry-v3-sinkconfig } @@ -77,4 +83,7 @@ type ProxyOpenTelemetrySink struct { type ProxyPrometheusProvider struct { // Disable the Prometheus endpoint. Disable bool `json:"disable,omitempty"` + // Configure the compression on Prometheus endpoint. Compression is useful in situations when bandwidth is scarce and large payloads can be effectively compressed at the expense of higher CPU load. + // +optional + Compression *Compression `json:"compression,omitempty"` } diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go index a8bb1505717..bcec1ff5837 100644 --- a/api/v1alpha1/envoyproxy_types.go +++ b/api/v1alpha1/envoyproxy_types.go @@ -7,6 +7,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) const ( @@ -86,8 +87,106 @@ type EnvoyProxySpec struct { // // +optional Shutdown *ShutdownConfig `json:"shutdown,omitempty"` + + // FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. + // If unspecified, the default filter order is applied. + // Default filter order is: + // + // - envoy.filters.http.fault + // + // - envoy.filters.http.cors + // + // - envoy.filters.http.ext_authz + // + // - envoy.filters.http.basic_authn + // + // - envoy.filters.http.oauth2 + // + // - envoy.filters.http.jwt_authn + // + // - envoy.filters.http.ext_proc + // + // - envoy.filters.http.wasm + // + // - envoy.filters.http.local_ratelimit + // + // - envoy.filters.http.ratelimit + // + // - envoy.filters.http.router + // + // +optional + // +notImplementedHide + FilterOrder []FilterPosition `json:"filterOrder,omitempty"` + // BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends. + // These settings are applied on backends for which TLS policies are specified. + // +optional + BackendTLS *BackendTLSConfig `json:"backendTLS,omitempty"` +} + +// BackendTLSConfig describes the BackendTLS configuration for Envoy Proxy. +type BackendTLSConfig struct { + // ClientCertificateRef defines the reference to a Kubernetes Secret that contains + // the client certificate and private key for Envoy to use when connecting to + // backend services and external services, such as ExtAuth, ALS, OpenTelemetry, etc. + // +optional + ClientCertificateRef *gwapiv1.SecretObjectReference `json:"clientCertificateRef,omitempty"` + TLSSettings `json:",inline"` +} + +// FilterPosition defines the position of an Envoy HTTP filter in the filter chain. +// +kubebuilder:validation:XValidation:rule="(has(self.before) || has(self.after))",message="one of before or after must be specified" +// +kubebuilder:validation:XValidation:rule="(has(self.before) && !has(self.after)) || (!has(self.before) && has(self.after))",message="only one of before or after can be specified" +type FilterPosition struct { + // Name of the filter. + Name EnvoyFilter `json:"filter"` + + // Before defines the filter that should come before the filter. + // Only one of Before or After must be set. + Before *EnvoyFilter `json:"before,omitempty"` + + // After defines the filter that should come after the filter. + // Only one of Before or After must be set. + After *EnvoyFilter `json:"after,omitempty"` } +// EnvoyFilter defines the type of Envoy HTTP filter. +// +kubebuilder:validation:Enum=envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_authn;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.fault;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.wasm;envoy.filters.http.ext_proc +type EnvoyFilter string + +const ( + // EnvoyFilterFault defines the Envoy HTTP fault filter. + EnvoyFilterFault EnvoyFilter = "envoy.filters.http.fault" + // EnvoyFilterCORS defines the Envoy HTTP CORS filter. + EnvoyFilterCORS EnvoyFilter = "envoy.filters.http.cors" + + // EnvoyFilterExtAuthz defines the Envoy HTTP external authorization filter. + EnvoyFilterExtAuthz EnvoyFilter = "envoy.filters.http.ext_authz" + + // EnvoyFilterBasicAuthn defines the Envoy HTTP basic authentication filter. + EnvoyFilterBasicAuthn EnvoyFilter = "envoy.filters.http.basic_authn" + + // EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter. + EnvoyFilterOAuth2 EnvoyFilter = "envoy.filters.http.oauth2" + + // EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter. + EnvoyFilterJWTAuthn EnvoyFilter = "envoy.filters.http.jwt_authn" + + // EnvoyFilterExtProc defines the Envoy HTTP external process filter. + EnvoyFilterExtProc EnvoyFilter = "envoy.filters.http.ext_proc" + + // EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter. + EnvoyFilterWasm EnvoyFilter = "envoy.filters.http.wasm" + + // EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter. + EnvoyFilterLocalRateLimit EnvoyFilter = "envoy.filters.http.local_ratelimit" + + // EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter. + EnvoyFilterRateLimit EnvoyFilter = "envoy.filters.http.ratelimit" + + // EnvoyFilterRouter defines the Envoy HTTP router filter. + EnvoyFilterRouter EnvoyFilter = "envoy.filters.http.router" +) + type ProxyTelemetry struct { // AccessLogs defines accesslog parameters for managed proxies. // If unspecified, will send default format to stdout. @@ -134,6 +233,9 @@ type ShutdownConfig struct { MinDrainDuration *metav1.Duration `json:"minDrainDuration,omitempty"` } +// +kubebuilder:validation:XValidation:rule="((has(self.envoyDeployment) && !has(self.envoyDaemonSet)) || (!has(self.envoyDeployment) && has(self.envoyDaemonSet))) || (!has(self.envoyDeployment) && !has(self.envoyDaemonSet))",message="only one of envoyDeployment or envoyDaemonSet can be specified" +// +kubebuilder:validation:XValidation:rule="((has(self.envoyHpa) && !has(self.envoyDaemonSet)) || (!has(self.envoyHpa) && has(self.envoyDaemonSet))) || (!has(self.envoyHpa) && !has(self.envoyDaemonSet))",message="cannot use envoyHpa if envoyDaemonSet is used" +// // EnvoyProxyKubernetesProvider defines configuration for the Kubernetes resource // provider. type EnvoyProxyKubernetesProvider struct { @@ -144,6 +246,12 @@ type EnvoyProxyKubernetesProvider struct { // +optional EnvoyDeployment *KubernetesDeploymentSpec `json:"envoyDeployment,omitempty"` + // EnvoyDaemonSet defines the desired state of the Envoy daemonset resource. + // Disabled by default, a deployment resource is used instead to provision the Envoy Proxy fleet + // + // +optional + EnvoyDaemonSet *KubernetesDaemonSetSpec `json:"envoyDaemonSet,omitempty"` + // EnvoyService defines the desired state of the Envoy service resource. // If unspecified, default settings for the managed Envoy service resource // are applied. diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go index c94682198b4..85f250c6314 100644 --- a/api/v1alpha1/ext_proc_types.go +++ b/api/v1alpha1/ext_proc_types.go @@ -9,21 +9,68 @@ import ( gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) -// +kubebuilder:validation:XValidation:rule="has(self.backendRef) ? (!has(self.backendRef.group) || self.backendRef.group == \"\") : true", message="group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported" -// +kubebuilder:validation:XValidation:rule="has(self.backendRef) ? (!has(self.backendRef.kind) || self.backendRef.kind == 'Service') : true", message="kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported" -// +// +kubebuilder:validation:Enum=Streamed;Buffered;BufferedPartial +type ExtProcBodyProcessingMode string + +const ( + // StreamedExtProcBodyProcessingMode will stream the body to the server in pieces as they arrive at the proxy. + StreamedExtProcBodyProcessingMode ExtProcBodyProcessingMode = "Streamed" + // BufferedExtProcBodyProcessingMode will buffer the message body in memory and send the entire body at once. If the body exceeds the configured buffer limit, then the downstream system will receive an error. + BufferedExtProcBodyProcessingMode ExtProcBodyProcessingMode = "Buffered" + // BufferedPartialExtBodyHeaderProcessingMode will buffer the message body in memory and send the entire body in one chunk. If the body exceeds the configured buffer limit, then the body contents up to the buffer limit will be sent. + BufferedPartialExtBodyHeaderProcessingMode ExtProcBodyProcessingMode = "BufferedPartial" +) + +// ProcessingModeOptions defines if headers or body should be processed by the external service +type ProcessingModeOptions struct { + // Defines body processing mode + // + // +optional + Body *ExtProcBodyProcessingMode `json:"body,omitempty"` +} + +// ExtProcProcessingMode defines if and how headers and bodies are sent to the service. +// https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto#envoy-v3-api-msg-extensions-filters-http-ext-proc-v3-processingmode +type ExtProcProcessingMode struct { + // Defines processing mode for requests. If present, request headers are sent. Request body is processed according + // to the specified mode. + // + // +optional + Request *ProcessingModeOptions `json:"request,omitempty"` + + // Defines processing mode for responses. If present, response headers are sent. Response body is processed according + // to the specified mode. + // + // +optional + Response *ProcessingModeOptions `json:"response,omitempty"` +} + // ExtProc defines the configuration for External Processing filter. type ExtProc struct { - // Service defines the configuration of the external processing service - BackendRef ExtProcBackendRef `json:"backendRef"` -} + // BackendRefs defines the configuration of the external processing service + // + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="self.all(f, f.kind == 'Service')" + // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')" + BackendRefs []BackendRef `json:"backendRefs"` + + // MessageTimeout is the timeout for a response to be returned from the external processor + // Default: 200ms + // + // +optional + MessageTimeout *gwapiv1.Duration `json:"messageTimeout,omitempty"` + + // FailOpen defines if requests or responses that cannot be processed due to connectivity to the + // external processor are terminated or passed-through. + // Default: false + // + // +optional + FailOpen *bool `json:"failOpen,omitempty"` -// ExtProcService defines the gRPC External Processing service using the envoy grpc client -// The processing request and response messages are defined in -// https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ext_proc/v3/external_processor.proto -type ExtProcBackendRef struct { - // BackendObjectReference references a Kubernetes object that represents the - // backend server to which the processing requests will be sent. - // Only service Kind is supported for now. - gwapiv1.BackendObjectReference `json:",inline"` + // ProcessingMode defines how request and response body is processed + // Default: header and body are not sent to the external processor + // + // +optional + ProcessingMode *ExtProcProcessingMode `json:"processingMode,omitempty"` } diff --git a/api/v1alpha1/fault_injection.go b/api/v1alpha1/fault_injection.go index d27a5c5ee12..a8b7e1f5412 100644 --- a/api/v1alpha1/fault_injection.go +++ b/api/v1alpha1/fault_injection.go @@ -13,7 +13,6 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // // +kubebuilder:validation:XValidation:rule=" has(self.delay) || has(self.abort) ",message="Delay and abort faults are set at least one." type FaultInjection struct { - // If specified, a delay will be injected into the request. // // +optional diff --git a/api/v1alpha1/healthcheck_types.go b/api/v1alpha1/healthcheck_types.go index 61172273e3d..cea83d2f5a1 100644 --- a/api/v1alpha1/healthcheck_types.go +++ b/api/v1alpha1/healthcheck_types.go @@ -22,7 +22,6 @@ type HealthCheck struct { // PassiveHealthCheck defines the configuration for passive health checks in the context of Envoy's Outlier Detection, // see https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/outlier type PassiveHealthCheck struct { - // SplitExternalLocalOriginErrors enables splitting of errors between external and local origin. // // +kubebuilder:default=false diff --git a/api/v1alpha1/jwt_types.go b/api/v1alpha1/jwt_types.go index 4948669a292..4bc8a994f5d 100644 --- a/api/v1alpha1/jwt_types.go +++ b/api/v1alpha1/jwt_types.go @@ -7,6 +7,9 @@ package v1alpha1 // JWT defines the configuration for JSON Web Token (JWT) authentication. type JWT struct { + // Optional determines whether a missing JWT is acceptable, defaulting to false if not specified. + // Note: Even if optional is set to true, JWT authentication will still fail if an invalid JWT is presented. + Optional *bool `json:"optional,omitempty"` // Providers defines the JSON Web Token (JWT) authentication provider type. // When multiple JWT providers are specified, the JWT is considered valid if @@ -87,7 +90,6 @@ type RemoteJWKS struct { // ClaimToHeader defines a configuration to convert JWT claims into HTTP headers type ClaimToHeader struct { - // Header defines the name of the HTTP request header that the JWT Claim will be saved into. Header string `json:"header"` diff --git a/api/v1alpha1/kubernetes_helpers.go b/api/v1alpha1/kubernetes_helpers.go index 957fabe72b0..f22f51822f4 100644 --- a/api/v1alpha1/kubernetes_helpers.go +++ b/api/v1alpha1/kubernetes_helpers.go @@ -24,6 +24,13 @@ func DefaultKubernetesDeploymentStrategy() *appv1.DeploymentStrategy { } } +// DefaultKubernetesDaemonSetStrategy returns the default daemonset strategy settings. +func DefaultKubernetesDaemonSetStrategy() *appv1.DaemonSetUpdateStrategy { + return &appv1.DaemonSetUpdateStrategy{ + Type: appv1.RollingUpdateDaemonSetStrategyType, + } +} + // DefaultKubernetesContainerImage returns the default envoyproxy image. func DefaultKubernetesContainerImage(image string) *string { return ptr.To(image) @@ -38,6 +45,15 @@ func DefaultKubernetesDeployment(image string) *KubernetesDeploymentSpec { } } +// DefaultKubernetesDaemonSet returns a new DefaultKubernetesDaemonSet with default settings. +func DefaultKubernetesDaemonSet(image string) *KubernetesDaemonSetSpec { + return &KubernetesDaemonSetSpec{ + Strategy: DefaultKubernetesDaemonSetStrategy(), + Pod: DefaultKubernetesPod(), + Container: DefaultKubernetesContainer(image), + } +} + // DefaultKubernetesPod returns a new KubernetesPodSpec with default settings. func DefaultKubernetesPod() *KubernetesPodSpec { return &KubernetesPodSpec{} @@ -110,6 +126,29 @@ func (deployment *KubernetesDeploymentSpec) defaultKubernetesDeploymentSpec(imag } } +// defaultKubernetesDaemonSetSpec fill a default KubernetesDaemonSetSpec if unspecified. +func (daemonset *KubernetesDaemonSetSpec) defaultKubernetesDaemonSetSpec(image string) { + if daemonset.Strategy == nil { + daemonset.Strategy = DefaultKubernetesDaemonSetStrategy() + } + + if daemonset.Pod == nil { + daemonset.Pod = DefaultKubernetesPod() + } + + if daemonset.Container == nil { + daemonset.Container = DefaultKubernetesContainer(image) + } + + if daemonset.Container.Resources == nil { + daemonset.Container.Resources = DefaultResourceRequirements() + } + + if daemonset.Container.Image == nil { + daemonset.Container.Image = DefaultKubernetesContainerImage(image) + } +} + // setDefault fill a default HorizontalPodAutoscalerSpec if unspecified func (hpa *KubernetesHorizontalPodAutoscalerSpec) setDefault() { if len(hpa.Metrics) == 0 { @@ -153,6 +192,42 @@ func (deployment *KubernetesDeploymentSpec) ApplyMergePatch(old *appv1.Deploymen return &patchedDeployment, nil } +// ApplyMergePatch applies a merge patch to a daemonset based on the merge type +func (daemonset *KubernetesDaemonSetSpec) ApplyMergePatch(old *appv1.DaemonSet) (*appv1.DaemonSet, error) { + if daemonset.Patch == nil { + return old, nil + } + + var patchedJSON []byte + var err error + + // Serialize the current daemonset to JSON + originalJSON, err := json.Marshal(old) + if err != nil { + return nil, fmt.Errorf("error marshaling original daemonset: %w", err) + } + + switch { + case daemonset.Patch.Type == nil || *daemonset.Patch.Type == StrategicMerge: + patchedJSON, err = strategicpatch.StrategicMergePatch(originalJSON, daemonset.Patch.Value.Raw, appv1.DaemonSet{}) + case *daemonset.Patch.Type == JSONMerge: + patchedJSON, err = jsonpatch.MergePatch(originalJSON, daemonset.Patch.Value.Raw) + default: + return nil, fmt.Errorf("unsupported merge type: %s", *daemonset.Patch.Type) + } + if err != nil { + return nil, fmt.Errorf("error applying merge patch: %w", err) + } + + // Deserialize the patched JSON into a new daemonset object + var patchedDaemonSet appv1.DaemonSet + if err := json.Unmarshal(patchedJSON, &patchedDaemonSet); err != nil { + return nil, fmt.Errorf("error unmarshaling patched daemonset: %w", err) + } + + return &patchedDaemonSet, nil +} + // ApplyMergePatch applies a merge patch to a service based on the merge type func (service *KubernetesServiceSpec) ApplyMergePatch(old *corev1.Service) (*corev1.Service, error) { if service.Patch == nil { diff --git a/api/v1alpha1/ratelimit_types.go b/api/v1alpha1/ratelimit_types.go index bd547b935d2..9228e7d4b87 100644 --- a/api/v1alpha1/ratelimit_types.go +++ b/api/v1alpha1/ratelimit_types.go @@ -114,6 +114,7 @@ type RateLimitSelectCondition struct { SourceCIDR *SourceMatch `json:"sourceCIDR,omitempty"` } +// +kubebuilder:validation:Enum=Exact;Distinct type SourceMatchType string const ( diff --git a/api/v1alpha1/securitypolicy_types.go b/api/v1alpha1/securitypolicy_types.go index bad947059bd..85c0b21892d 100644 --- a/api/v1alpha1/securitypolicy_types.go +++ b/api/v1alpha1/securitypolicy_types.go @@ -18,7 +18,6 @@ const ( // +kubebuilder:object:root=true // +kubebuilder:resource:categories=envoy-gateway,shortName=sp // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Accepted")].reason` // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` // SecurityPolicy allows the user to configure various security settings for a @@ -72,17 +71,6 @@ type SecurityPolicySpec struct { ExtAuth *ExtAuth `json:"extAuth,omitempty"` } -// SecurityPolicyStatus defines the state of SecurityPolicy -type SecurityPolicyStatus struct { - // Conditions describe the current conditions of the SecurityPolicy. - // - // +optional - // +listType=map - // +listMapKey=type - // +kubebuilder:validation:MaxItems=8 - Conditions []metav1.Condition `json:"conditions,omitempty"` -} - //+kubebuilder:object:root=true // SecurityPolicyList contains a list of SecurityPolicy resources. diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index a634995e1b5..e07c8ec158e 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -10,6 +10,7 @@ import ( autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) const ( @@ -92,6 +93,28 @@ type KubernetesDeploymentSpec struct { // TODO: Expose config as use cases are better understood, e.g. labels. } +// KubernetesDaemonsetSpec defines the desired state of the Kubernetes daemonset resource. +type KubernetesDaemonSetSpec struct { + // Patch defines how to perform the patch operation to daemonset + // + // +optional + Patch *KubernetesPatchSpec `json:"patch,omitempty"` + + // The daemonset strategy to use to replace existing pods with new ones. + // +optional + Strategy *appv1.DaemonSetUpdateStrategy `json:"strategy,omitempty"` + + // Pod defines the desired specification of pod. + // + // +optional + Pod *KubernetesPodSpec `json:"pod,omitempty"` + + // Container defines the desired specification of main container. + // + // +optional + Container *KubernetesContainerSpec `json:"container,omitempty"` +} + // KubernetesPodSpec defines the desired state of the Kubernetes pod resource. type KubernetesPodSpec struct { // Annotations are the annotations that should be appended to the pods. @@ -219,6 +242,7 @@ const ( // KubernetesServiceSpec defines the desired state of the Kubernetes service resource. // +kubebuilder:validation:XValidation:message="allocateLoadBalancerNodePorts can only be set for LoadBalancer type",rule="!has(self.allocateLoadBalancerNodePorts) || self.type == 'LoadBalancer'" +// +kubebuilder:validation:XValidation:message="loadBalancerSourceRanges can only be set for LoadBalancer type",rule="!has(self.loadBalancerSourceRanges) || self.type == 'LoadBalancer'" // +kubebuilder:validation:XValidation:message="loadBalancerIP can only be set for LoadBalancer type",rule="!has(self.loadBalancerIP) || self.type == 'LoadBalancer'" type KubernetesServiceSpec struct { // Annotations that should be appended to the service. @@ -249,6 +273,14 @@ type KubernetesServiceSpec struct { // +optional AllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty"` + // LoadBalancerSourceRanges defines a list of allowed IP addresses which will be configured as + // firewall rules on the platform providers load balancer. This is not guaranteed to be working as + // it happens outside of kubernetes and has to be supported and handled by the platform provider. + // This field may only be set for services with type LoadBalancer and will be cleared if the type + // is changed to any other type. + // +optional + LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty"` + // LoadBalancerIP defines the IP Address of the underlying load balancer service. This field // may be ignored if the load balancer provider does not support this feature. // This field has been deprecated in Kubernetes, but it is still used for setting the IP Address in some cloud @@ -407,3 +439,10 @@ type KubernetesPatchSpec struct { // Object contains the raw configuration for merged object Value apiextensionsv1.JSON `json:"value"` } + +// BackendRef defines how an ObjectReference that is specific to BackendRef. +type BackendRef struct { + // BackendObjectReference references a Kubernetes object that represents the backend. + // Only service Kind is supported for now. + gwapiv1.BackendObjectReference `json:",inline"` +} diff --git a/api/v1alpha1/tls_types.go b/api/v1alpha1/tls_types.go index 18729f0a68a..38c52761125 100644 --- a/api/v1alpha1/tls_types.go +++ b/api/v1alpha1/tls_types.go @@ -9,10 +9,17 @@ import ( gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) +type ClientTLSSettings struct { + // ClientValidation specifies the configuration to validate the client + // initiating the TLS connection to the Gateway listener. + // +optional + ClientValidation *ClientValidationContext `json:"clientValidation,omitempty"` + TLSSettings `json:",inline"` +} + // +kubebuilder:validation:XValidation:rule="has(self.minVersion) && self.minVersion == '1.3' ? !has(self.ciphers) : true", message="setting ciphers has no effect if the minimum possible TLS version is 1.3" // +kubebuilder:validation:XValidation:rule="has(self.minVersion) && has(self.maxVersion) ? {\"Auto\":0,\"1.0\":1,\"1.1\":2,\"1.2\":3,\"1.3\":4}[self.minVersion] <= {\"1.0\":1,\"1.1\":2,\"1.2\":3,\"1.3\":4,\"Auto\":5}[self.maxVersion] : !has(self.minVersion) && has(self.maxVersion) ? 3 <= {\"1.0\":1,\"1.1\":2,\"1.2\":3,\"1.3\":4,\"Auto\":5}[self.maxVersion] : true", message="minVersion must be smaller or equal to maxVersion" type TLSSettings struct { - // Min specifies the minimal TLS protocol version to allow. // The default is TLS 1.2 if this is not specified. // @@ -66,11 +73,6 @@ type TLSSettings struct { // // +optional ALPNProtocols []ALPNProtocol `json:"alpnProtocols,omitempty"` - - // ClientValidation specifies the configuration to validate the client - // initiating the TLS connection to the Gateway listener. - // +optional - ClientValidation *ClientValidationContext `json:"clientValidation,omitempty"` } // ALPNProtocol specifies the protocol to be negotiated using ALPN @@ -110,6 +112,11 @@ const ( // to the Gateway. // By default, no client specific configuration is validated. type ClientValidationContext struct { + // Optional set to true accepts connections even when a client doesn't present a certificate. + // Defaults to false, which rejects connections without a valid client certificate. + // +optional + Optional bool `json:"optional,omitempty"` + // CACertificateRefs contains one or more references to // Kubernetes objects that contain TLS certificates of // the Certificate Authorities that can be used diff --git a/api/v1alpha1/tracing_types.go b/api/v1alpha1/tracing_types.go index 7c86ba7c846..d3a18673f60 100644 --- a/api/v1alpha1/tracing_types.go +++ b/api/v1alpha1/tracing_types.go @@ -5,8 +5,6 @@ package v1alpha1 -import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" - type ProxyTracing struct { // SamplingRate controls the rate at which traffic will be // selected for tracing if no prior sampling decision has been made. @@ -32,7 +30,7 @@ const ( // TracingProvider defines the tracing provider configuration. // -// +kubebuilder:validation:XValidation:message="BackendRef only support Service Kind.",rule="!has(self.backendRef) || !has(self.backendRef.kind) || self.backendRef.kind == 'Service'" +// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" type TracingProvider struct { // Type defines the tracing provider type. // EG currently only supports OpenTelemetry. @@ -41,7 +39,9 @@ type TracingProvider struct { Type TracingProviderType `json:"type"` // Host define the provider service hostname. // Deprecated: Use BackendRef instead. - Host string `json:"host"` + // + // +optional + Host *string `json:"host,omitempty"` // Port defines the port the provider service is exposed on. // Deprecated: Use BackendRef instead. // @@ -49,12 +49,14 @@ type TracingProvider struct { // +kubebuilder:validation:Minimum=0 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRef references a Kubernetes object that represents the + // BackendRefs references a Kubernetes object that represents the // backend server to which the accesslog will be sent. // Only service Kind is supported for now. // // +optional - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef"` + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" + BackendRefs []BackendRef `json:"backendRefs,omitempty"` } type CustomTagType string diff --git a/api/v1alpha1/validation/envoygateway_validate_test.go b/api/v1alpha1/validation/envoygateway_validate_test.go index 6978a52e35f..aa76a90ec7b 100644 --- a/api/v1alpha1/validation/envoygateway_validate_test.go +++ b/api/v1alpha1/validation/envoygateway_validate_test.go @@ -660,7 +660,8 @@ func TestEnvoyGatewayProvider(t *testing.T) { Replicas: nil, Pod: nil, Container: nil, - }} + }, + } assert.Nil(t, envoyGatewayProvider.Kubernetes.RateLimitDeployment.Replicas) assert.Nil(t, envoyGatewayProvider.Kubernetes.RateLimitDeployment.Pod) assert.Nil(t, envoyGatewayProvider.Kubernetes.RateLimitDeployment.Container) @@ -674,7 +675,8 @@ func TestEnvoyGatewayProvider(t *testing.T) { SecurityContext: nil, Image: nil, }, - }} + }, + } assert.Nil(t, envoyGatewayProvider.Kubernetes.RateLimitDeployment.Container.Resources) envoyGatewayProvider.GetEnvoyGatewayKubeProvider() diff --git a/api/v1alpha1/validation/envoyproxy_validate.go b/api/v1alpha1/validation/envoyproxy_validate.go index bb880891e2c..0e4f7e22221 100644 --- a/api/v1alpha1/validation/envoyproxy_validate.go +++ b/api/v1alpha1/validation/envoyproxy_validate.go @@ -8,6 +8,7 @@ package validation import ( "errors" "fmt" + "net" "net/netip" bootstrapv3 "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3" @@ -109,12 +110,22 @@ func validateService(spec *egv1a1.EnvoyProxySpec) []error { errs = append(errs, fmt.Errorf("unsupported envoy service type %v", serviceType)) } } - if serviceType, serviceAllocateLoadBalancerNodePorts := - spec.Provider.Kubernetes.EnvoyService.Type, spec.Provider.Kubernetes.EnvoyService.AllocateLoadBalancerNodePorts; serviceType != nil && serviceAllocateLoadBalancerNodePorts != nil { + if serviceType, serviceAllocateLoadBalancerNodePorts := spec.Provider.Kubernetes.EnvoyService.Type, spec.Provider.Kubernetes.EnvoyService.AllocateLoadBalancerNodePorts; serviceType != nil && serviceAllocateLoadBalancerNodePorts != nil { if *serviceType != egv1a1.ServiceTypeLoadBalancer { errs = append(errs, fmt.Errorf("allocateLoadBalancerNodePorts can only be set for %v type", egv1a1.ServiceTypeLoadBalancer)) } } + if serviceType, serviceLoadBalancerSourceRanges := spec.Provider.Kubernetes.EnvoyService.Type, spec.Provider.Kubernetes.EnvoyService.LoadBalancerSourceRanges; serviceType != nil && serviceLoadBalancerSourceRanges != nil { + if *serviceType != egv1a1.ServiceTypeLoadBalancer { + errs = append(errs, fmt.Errorf("loadBalancerSourceRanges can only be set for %v type", egv1a1.ServiceTypeLoadBalancer)) + } + + for _, serviceLoadBalancerSourceRange := range serviceLoadBalancerSourceRanges { + if ip, _, err := net.ParseCIDR(serviceLoadBalancerSourceRange); err != nil || ip.To4() == nil { + errs = append(errs, fmt.Errorf("loadBalancerSourceRange:%s is an invalid IPv4 subnet", serviceLoadBalancerSourceRange)) + } + } + } if serviceType, serviceLoadBalancerIP := spec.Provider.Kubernetes.EnvoyService.Type, spec.Provider.Kubernetes.EnvoyService.LoadBalancerIP; serviceType != nil && serviceLoadBalancerIP != nil { if *serviceType != egv1a1.ServiceTypeLoadBalancer { errs = append(errs, fmt.Errorf("loadBalancerIP can only be set for %v type", egv1a1.ServiceTypeLoadBalancer)) diff --git a/api/v1alpha1/validation/envoyproxy_validate_test.go b/api/v1alpha1/validation/envoyproxy_validate_test.go index 93381bd527a..6619888bdc8 100644 --- a/api/v1alpha1/validation/envoyproxy_validate_test.go +++ b/api/v1alpha1/validation/envoyproxy_validate_test.go @@ -213,6 +213,49 @@ func TestValidateEnvoyProxy(t *testing.T) { }, expected: false, }, + + { + name: "envoy service type 'LoadBalancer' with loadBalancerSourceRanges", + proxy: &egv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "test", + }, + Spec: egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyService: &egv1a1.KubernetesServiceSpec{ + Type: egv1a1.GetKubernetesServiceType(egv1a1.ServiceTypeLoadBalancer), + LoadBalancerSourceRanges: []string{"1.1.1.1/32"}, + }, + }, + }, + }, + }, + expected: true, + }, + { + name: "non envoy service type 'LoadBalancer' with loadBalancerSourceRanges", + proxy: &egv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "test", + }, + Spec: egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyService: &egv1a1.KubernetesServiceSpec{ + Type: egv1a1.GetKubernetesServiceType(egv1a1.ServiceTypeClusterIP), + LoadBalancerSourceRanges: []string{"1.1.1.1/32"}, + }, + }, + }, + }, + }, + expected: false, + }, { name: "envoy service type 'LoadBalancer' with valid loadBalancerIP", proxy: &egv1a1.EnvoyProxy{ @@ -404,7 +447,8 @@ func TestValidateEnvoyProxy(t *testing.T) { }, }, expected: false, - }, { + }, + { name: "should invalid when metrics type is OpenTelemetry, but `OpenTelemetry` field being empty", proxy: &egv1a1.EnvoyProxy{ ObjectMeta: metav1.ObjectMeta{ @@ -424,7 +468,8 @@ func TestValidateEnvoyProxy(t *testing.T) { }, }, expected: false, - }, { + }, + { name: "should valid when metrics type is OpenTelemetry and `OpenTelemetry` field being not empty", proxy: &egv1a1.EnvoyProxy{ ObjectMeta: metav1.ObjectMeta{ @@ -438,7 +483,7 @@ func TestValidateEnvoyProxy(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - Host: "0.0.0.0", + Host: ptr.To("0.0.0.0"), Port: 3217, }, }, @@ -448,7 +493,8 @@ func TestValidateEnvoyProxy(t *testing.T) { }, }, expected: true, - }, { + }, + { name: "should be invalid when service patch type is empty", proxy: &egv1a1.EnvoyProxy{ ObjectMeta: metav1.ObjectMeta{ @@ -471,7 +517,8 @@ func TestValidateEnvoyProxy(t *testing.T) { }, }, expected: true, - }, { + }, + { name: "should be invalid when deployment patch type is empty", proxy: &egv1a1.EnvoyProxy{ ObjectMeta: metav1.ObjectMeta{ @@ -494,7 +541,8 @@ func TestValidateEnvoyProxy(t *testing.T) { }, }, expected: true, - }, { + }, + { name: "should invalid when patch object is empty", proxy: &egv1a1.EnvoyProxy{ ObjectMeta: metav1.ObjectMeta{ @@ -515,7 +563,8 @@ func TestValidateEnvoyProxy(t *testing.T) { }, }, expected: false, - }, { + }, + { name: "should valid when patch type and object are both not empty", proxy: &egv1a1.EnvoyProxy{ ObjectMeta: metav1.ObjectMeta{ @@ -539,7 +588,8 @@ func TestValidateEnvoyProxy(t *testing.T) { }, }, expected: true, - }, { + }, + { name: "should valid when patch type is empty and object is not empty", proxy: &egv1a1.EnvoyProxy{ ObjectMeta: metav1.ObjectMeta{ diff --git a/api/v1alpha1/wasm_types.go b/api/v1alpha1/wasm_types.go index f918f92c9e0..425c8e45892 100644 --- a/api/v1alpha1/wasm_types.go +++ b/api/v1alpha1/wasm_types.go @@ -31,14 +31,16 @@ type Wasm struct { // RootID is a unique ID for a set of extensions in a VM which will share a // RootContext and Contexts if applicable (e.g., an Wasm HttpFilter and an Wasm AccessLog). // If left blank, all extensions with a blank root_id with the same vm_id will share Context(s). - // RootID *string `json:"rootID,omitempty"` + // RootID must match the root_id parameter used to register the Context in the Wasm code. + RootID *string `json:"rootID,omitempty"` // Code is the wasm code for the extension. Code WasmCodeSource `json:"code"` // Config is the configuration for the Wasm extension. // This configuration will be passed as a JSON string to the Wasm extension. - Config *apiextensionsv1.JSON `json:"config"` + // +optional + Config *apiextensionsv1.JSON `json:"config,omitempty"` // FailOpen is a switch used to control the behavior when a fatal error occurs // during the initialization or the execution of the Wasm extension. @@ -61,7 +63,7 @@ type WasmCodeSource struct { // Type is the type of the source of the wasm code. // Valid WasmCodeSourceType values are "HTTP" or "Image". // - // +kubebuilder:validation:Enum=HTTP;Image + // +kubebuilder:validation:Enum=HTTP;Image;ConfigMap // +unionDiscriminator Type WasmCodeSourceType `json:"type"` @@ -78,12 +80,13 @@ type WasmCodeSource struct { Image *ImageWasmCodeSource `json:"image,omitempty"` // SHA256 checksum that will be used to verify the wasm code. - // +optional - // SHA256 *string `json:"sha256,omitempty"` + // + // kubebuilder:validation:Pattern=`^[a-f0-9]{64}$` + SHA256 string `json:"sha256"` } // WasmCodeSourceType specifies the types of sources for the wasm code. -// +kubebuilder:validation:Enum=Global;Local +// +kubebuilder:validation:Enum=HTTP;Image type WasmCodeSourceType string const ( diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index e82cda7787f..c3d53f443ba 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -19,6 +19,68 @@ import ( "sigs.k8s.io/gateway-api/apis/v1" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ALSEnvoyProxyAccessLog) DeepCopyInto(out *ALSEnvoyProxyAccessLog) { + *out = *in + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LogName != nil { + in, out := &in.LogName, &out.LogName + *out = new(string) + **out = **in + } + if in.HTTP != nil { + in, out := &in.HTTP, &out.HTTP + *out = new(ALSEnvoyProxyHTTPAccessLogConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ALSEnvoyProxyAccessLog. +func (in *ALSEnvoyProxyAccessLog) DeepCopy() *ALSEnvoyProxyAccessLog { + if in == nil { + return nil + } + out := new(ALSEnvoyProxyAccessLog) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ALSEnvoyProxyHTTPAccessLogConfig) DeepCopyInto(out *ALSEnvoyProxyHTTPAccessLogConfig) { + *out = *in + if in.RequestHeaders != nil { + in, out := &in.RequestHeaders, &out.RequestHeaders + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ResponseHeaders != nil { + in, out := &in.ResponseHeaders, &out.ResponseHeaders + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ResponseTrailers != nil { + in, out := &in.ResponseTrailers, &out.ResponseTrailers + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ALSEnvoyProxyHTTPAccessLogConfig. +func (in *ALSEnvoyProxyHTTPAccessLogConfig) DeepCopy() *ALSEnvoyProxyHTTPAccessLogConfig { + if in == nil { + return nil + } + out := new(ALSEnvoyProxyHTTPAccessLogConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ActiveHealthCheck) DeepCopyInto(out *ActiveHealthCheck) { *out = *in @@ -114,6 +176,43 @@ func (in *BackOffPolicy) DeepCopy() *BackOffPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackendRef) DeepCopyInto(out *BackendRef) { + *out = *in + in.BackendObjectReference.DeepCopyInto(&out.BackendObjectReference) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendRef. +func (in *BackendRef) DeepCopy() *BackendRef { + if in == nil { + return nil + } + out := new(BackendRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackendTLSConfig) DeepCopyInto(out *BackendTLSConfig) { + *out = *in + if in.ClientCertificateRef != nil { + in, out := &in.ClientCertificateRef, &out.ClientCertificateRef + *out = new(v1.SecretObjectReference) + (*in).DeepCopyInto(*out) + } + in.TLSSettings.DeepCopyInto(&out.TLSSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTLSConfig. +func (in *BackendTLSConfig) DeepCopy() *BackendTLSConfig { + if in == nil { + return nil + } + out := new(BackendTLSConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BackendTrafficPolicy) DeepCopyInto(out *BackendTrafficPolicy) { *out = *in @@ -217,6 +316,11 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) *out = new(Retry) (*in).DeepCopyInto(*out) } + if in.UseClientProtocol != nil { + in, out := &in.UseClientProtocol, &out.UseClientProtocol + *out = new(bool) + **out = **in + } if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout *out = new(Timeout) @@ -386,6 +490,27 @@ func (in *ClientIPDetectionSettings) DeepCopy() *ClientIPDetectionSettings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientTLSSettings) DeepCopyInto(out *ClientTLSSettings) { + *out = *in + if in.ClientValidation != nil { + in, out := &in.ClientValidation, &out.ClientValidation + *out = new(ClientValidationContext) + (*in).DeepCopyInto(*out) + } + in.TLSSettings.DeepCopyInto(&out.TLSSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientTLSSettings. +func (in *ClientTLSSettings) DeepCopy() *ClientTLSSettings { + if in == nil { + return nil + } + out := new(ClientTLSSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClientTimeout) DeepCopyInto(out *ClientTimeout) { *out = *in @@ -484,14 +609,9 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) { *out = new(ClientIPDetectionSettings) (*in).DeepCopyInto(*out) } - if in.HTTP3 != nil { - in, out := &in.HTTP3, &out.HTTP3 - *out = new(HTTP3Settings) - **out = **in - } if in.TLS != nil { in, out := &in.TLS, &out.TLS - *out = new(TLSSettings) + *out = new(ClientTLSSettings) (*in).DeepCopyInto(*out) } if in.Path != nil { @@ -499,11 +619,6 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) { *out = new(PathSettings) (*in).DeepCopyInto(*out) } - if in.HTTP1 != nil { - in, out := &in.HTTP1, &out.HTTP1 - *out = new(HTTP1Settings) - (*in).DeepCopyInto(*out) - } if in.Headers != nil { in, out := &in.Headers, &out.Headers *out = new(HeaderSettings) @@ -519,6 +634,21 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) { *out = new(Connection) (*in).DeepCopyInto(*out) } + if in.HTTP1 != nil { + in, out := &in.HTTP1, &out.HTTP1 + *out = new(HTTP1Settings) + (*in).DeepCopyInto(*out) + } + if in.HTTP2 != nil { + in, out := &in.HTTP2, &out.HTTP2 + *out = new(HTTP2Settings) + (*in).DeepCopyInto(*out) + } + if in.HTTP3 != nil { + in, out := &in.HTTP3, &out.HTTP3 + *out = new(HTTP3Settings) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientTrafficPolicySpec. @@ -766,8 +896,8 @@ func (in *EnvoyExtensionPolicyList) DeepCopyObject() runtime.Object { func (in *EnvoyExtensionPolicySpec) DeepCopyInto(out *EnvoyExtensionPolicySpec) { *out = *in in.TargetRef.DeepCopyInto(&out.TargetRef) - if in.WASM != nil { - in, out := &in.WASM, &out.WASM + if in.Wasm != nil { + in, out := &in.Wasm, &out.Wasm *out = make([]Wasm, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) @@ -1316,6 +1446,11 @@ func (in *EnvoyProxyKubernetesProvider) DeepCopyInto(out *EnvoyProxyKubernetesPr *out = new(KubernetesDeploymentSpec) (*in).DeepCopyInto(*out) } + if in.EnvoyDaemonSet != nil { + in, out := &in.EnvoyDaemonSet, &out.EnvoyDaemonSet + *out = new(KubernetesDaemonSetSpec) + (*in).DeepCopyInto(*out) + } if in.EnvoyService != nil { in, out := &in.EnvoyService, &out.EnvoyService *out = new(KubernetesServiceSpec) @@ -1429,6 +1564,18 @@ func (in *EnvoyProxySpec) DeepCopyInto(out *EnvoyProxySpec) { *out = new(ShutdownConfig) (*in).DeepCopyInto(*out) } + if in.FilterOrder != nil { + in, out := &in.FilterOrder, &out.FilterOrder + *out = make([]FilterPosition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.BackendTLS != nil { + in, out := &in.BackendTLS, &out.BackendTLS + *out = new(BackendTLSConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyProxySpec. @@ -1494,7 +1641,28 @@ func (in *ExtAuth) DeepCopy() *ExtAuth { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtProc) DeepCopyInto(out *ExtProc) { *out = *in - in.BackendRef.DeepCopyInto(&out.BackendRef) + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MessageTimeout != nil { + in, out := &in.MessageTimeout, &out.MessageTimeout + *out = new(v1.Duration) + **out = **in + } + if in.FailOpen != nil { + in, out := &in.FailOpen, &out.FailOpen + *out = new(bool) + **out = **in + } + if in.ProcessingMode != nil { + in, out := &in.ProcessingMode, &out.ProcessingMode + *out = new(ExtProcProcessingMode) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProc. @@ -1508,17 +1676,26 @@ func (in *ExtProc) DeepCopy() *ExtProc { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExtProcBackendRef) DeepCopyInto(out *ExtProcBackendRef) { +func (in *ExtProcProcessingMode) DeepCopyInto(out *ExtProcProcessingMode) { *out = *in - in.BackendObjectReference.DeepCopyInto(&out.BackendObjectReference) + if in.Request != nil { + in, out := &in.Request, &out.Request + *out = new(ProcessingModeOptions) + (*in).DeepCopyInto(*out) + } + if in.Response != nil { + in, out := &in.Response, &out.Response + *out = new(ProcessingModeOptions) + (*in).DeepCopyInto(*out) + } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProcBackendRef. -func (in *ExtProcBackendRef) DeepCopy() *ExtProcBackendRef { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProcProcessingMode. +func (in *ExtProcProcessingMode) DeepCopy() *ExtProcProcessingMode { if in == nil { return nil } - out := new(ExtProcBackendRef) + out := new(ExtProcProcessingMode) in.DeepCopyInto(out) return out } @@ -1719,6 +1896,31 @@ func (in *FileEnvoyProxyAccessLog) DeepCopy() *FileEnvoyProxyAccessLog { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilterPosition) DeepCopyInto(out *FilterPosition) { + *out = *in + if in.Before != nil { + in, out := &in.Before, &out.Before + *out = new(EnvoyFilter) + **out = **in + } + if in.After != nil { + in, out := &in.After, &out.After + *out = new(EnvoyFilter) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilterPosition. +func (in *FilterPosition) DeepCopy() *FilterPosition { + if in == nil { + return nil + } + out := new(FilterPosition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GRPCExtAuthService) DeepCopyInto(out *GRPCExtAuthService) { *out = *in @@ -1852,6 +2054,36 @@ func (in *HTTP1Settings) DeepCopy() *HTTP1Settings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { + *out = *in + if in.InitialStreamWindowSize != nil { + in, out := &in.InitialStreamWindowSize, &out.InitialStreamWindowSize + x := (*in).DeepCopy() + *out = &x + } + if in.InitialConnectionWindowSize != nil { + in, out := &in.InitialConnectionWindowSize, &out.InitialConnectionWindowSize + x := (*in).DeepCopy() + *out = &x + } + if in.MaxConcurrentStreams != nil { + in, out := &in.MaxConcurrentStreams, &out.MaxConcurrentStreams + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. +func (in *HTTP2Settings) DeepCopy() *HTTP2Settings { + if in == nil { + return nil + } + out := new(HTTP2Settings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTP3Settings) DeepCopyInto(out *HTTP3Settings) { *out = *in @@ -2107,6 +2339,11 @@ func (in *JSONPatchOperation) DeepCopy() *JSONPatchOperation { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JWT) DeepCopyInto(out *JWT) { *out = *in + if in.Optional != nil { + in, out := &in.Optional, &out.Optional + *out = new(bool) + **out = **in + } if in.Providers != nil { in, out := &in.Providers, &out.Providers *out = make([]JWTProvider, len(*in)) @@ -2258,6 +2495,41 @@ func (in *KubernetesContainerSpec) DeepCopy() *KubernetesContainerSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubernetesDaemonSetSpec) DeepCopyInto(out *KubernetesDaemonSetSpec) { + *out = *in + if in.Patch != nil { + in, out := &in.Patch, &out.Patch + *out = new(KubernetesPatchSpec) + (*in).DeepCopyInto(*out) + } + if in.Strategy != nil { + in, out := &in.Strategy, &out.Strategy + *out = new(appsv1.DaemonSetUpdateStrategy) + (*in).DeepCopyInto(*out) + } + if in.Pod != nil { + in, out := &in.Pod, &out.Pod + *out = new(KubernetesPodSpec) + (*in).DeepCopyInto(*out) + } + if in.Container != nil { + in, out := &in.Container, &out.Container + *out = new(KubernetesContainerSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesDaemonSetSpec. +func (in *KubernetesDaemonSetSpec) DeepCopy() *KubernetesDaemonSetSpec { + if in == nil { + return nil + } + out := new(KubernetesDaemonSetSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KubernetesDeployMode) DeepCopyInto(out *KubernetesDeployMode) { *out = *in @@ -2475,6 +2747,11 @@ func (in *KubernetesServiceSpec) DeepCopyInto(out *KubernetesServiceSpec) { *out = new(bool) **out = **in } + if in.LoadBalancerSourceRanges != nil { + in, out := &in.LoadBalancerSourceRanges, &out.LoadBalancerSourceRanges + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.LoadBalancerIP != nil { in, out := &in.LoadBalancerIP, &out.LoadBalancerIP *out = new(string) @@ -2689,10 +2966,17 @@ func (in *OIDCProvider) DeepCopy() *OIDCProvider { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenTelemetryEnvoyProxyAccessLog) DeepCopyInto(out *OpenTelemetryEnvoyProxyAccessLog) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(v1.BackendObjectReference) - (*in).DeepCopyInto(*out) + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(string) + **out = **in + } + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.Resources != nil { in, out := &in.Resources, &out.Resources @@ -2813,6 +3097,26 @@ func (in *PerRetryPolicy) DeepCopy() *PerRetryPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProcessingModeOptions) DeepCopyInto(out *ProcessingModeOptions) { + *out = *in + if in.Body != nil { + in, out := &in.Body, &out.Body + *out = new(ExtProcBodyProcessingMode) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProcessingModeOptions. +func (in *ProcessingModeOptions) DeepCopy() *ProcessingModeOptions { + if in == nil { + return nil + } + out := new(ProcessingModeOptions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProxyAccessLog) DeepCopyInto(out *ProxyAccessLog) { *out = *in @@ -2888,6 +3192,11 @@ func (in *ProxyAccessLogSetting) DeepCopy() *ProxyAccessLogSetting { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProxyAccessLogSink) DeepCopyInto(out *ProxyAccessLogSink) { *out = *in + if in.ALS != nil { + in, out := &in.ALS, &out.ALS + *out = new(ALSEnvoyProxyAccessLog) + (*in).DeepCopyInto(*out) + } if in.File != nil { in, out := &in.File, &out.File *out = new(FileEnvoyProxyAccessLog) @@ -2978,7 +3287,7 @@ func (in *ProxyMetrics) DeepCopyInto(out *ProxyMetrics) { if in.Prometheus != nil { in, out := &in.Prometheus, &out.Prometheus *out = new(ProxyPrometheusProvider) - **out = **in + (*in).DeepCopyInto(*out) } if in.Sinks != nil { in, out := &in.Sinks, &out.Sinks @@ -3009,10 +3318,17 @@ func (in *ProxyMetrics) DeepCopy() *ProxyMetrics { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProxyOpenTelemetrySink) DeepCopyInto(out *ProxyOpenTelemetrySink) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(v1.BackendObjectReference) - (*in).DeepCopyInto(*out) + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(string) + **out = **in + } + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } @@ -3029,6 +3345,11 @@ func (in *ProxyOpenTelemetrySink) DeepCopy() *ProxyOpenTelemetrySink { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProxyPrometheusProvider) DeepCopyInto(out *ProxyPrometheusProvider) { *out = *in + if in.Compression != nil { + in, out := &in.Compression, &out.Compression + *out = new(Compression) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyPrometheusProvider. @@ -3298,6 +3619,11 @@ func (in *RateLimitTelemetry) DeepCopyInto(out *RateLimitTelemetry) { *out = new(RateLimitMetrics) (*in).DeepCopyInto(*out) } + if in.Tracing != nil { + in, out := &in.Tracing, &out.Tracing + *out = new(RateLimitTracing) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitTelemetry. @@ -3310,6 +3636,51 @@ func (in *RateLimitTelemetry) DeepCopy() *RateLimitTelemetry { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitTracing) DeepCopyInto(out *RateLimitTracing) { + *out = *in + if in.SamplingRate != nil { + in, out := &in.SamplingRate, &out.SamplingRate + *out = new(uint32) + **out = **in + } + if in.Provider != nil { + in, out := &in.Provider, &out.Provider + *out = new(RateLimitTracingProvider) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitTracing. +func (in *RateLimitTracing) DeepCopy() *RateLimitTracing { + if in == nil { + return nil + } + out := new(RateLimitTracing) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitTracingProvider) DeepCopyInto(out *RateLimitTracingProvider) { + *out = *in + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(RateLimitTracingProviderType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitTracingProvider. +func (in *RateLimitTracingProvider) DeepCopy() *RateLimitTracingProvider { + if in == nil { + return nil + } + out := new(RateLimitTracingProvider) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RateLimitValue) DeepCopyInto(out *RateLimitValue) { *out = *in @@ -3535,28 +3906,6 @@ func (in *SecurityPolicySpec) DeepCopy() *SecurityPolicySpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecurityPolicyStatus) DeepCopyInto(out *SecurityPolicyStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityPolicyStatus. -func (in *SecurityPolicyStatus) DeepCopy() *SecurityPolicyStatus { - if in == nil { - return nil - } - out := new(SecurityPolicyStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ShutdownConfig) DeepCopyInto(out *ShutdownConfig) { *out = *in @@ -3750,11 +4099,6 @@ func (in *TLSSettings) DeepCopyInto(out *TLSSettings) { *out = make([]ALPNProtocol, len(*in)) copy(*out, *in) } - if in.ClientValidation != nil { - in, out := &in.ClientValidation, &out.ClientValidation - *out = new(ClientValidationContext) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSSettings. @@ -3795,10 +4139,17 @@ func (in *Timeout) DeepCopy() *Timeout { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TracingProvider) DeepCopyInto(out *TracingProvider) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(v1.BackendObjectReference) - (*in).DeepCopyInto(*out) + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(string) + **out = **in + } + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } @@ -3815,6 +4166,11 @@ func (in *TracingProvider) DeepCopy() *TracingProvider { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Wasm) DeepCopyInto(out *Wasm) { *out = *in + if in.RootID != nil { + in, out := &in.RootID, &out.RootID + *out = new(string) + **out = **in + } in.Code.DeepCopyInto(&out.Code) if in.Config != nil { in, out := &in.Config, &out.Config diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 4211ecafc03..94433f5715c 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: backendtrafficpolicies.gateway.envoyproxy.io spec: group: gateway.envoyproxy.io @@ -19,9 +19,6 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .status.conditions[?(@.type=="Accepted")].reason - name: Status - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -574,6 +571,9 @@ spec: properties: type: default: Exact + enum: + - Exact + - Distinct type: string value: description: |- @@ -704,6 +704,9 @@ spec: properties: type: default: Exact + enum: + - Exact + - Distinct type: string value: description: |- @@ -961,6 +964,12 @@ spec: type: string type: object type: object + useClientProtocol: + description: |- + UseClientProtocol configures Envoy to prefer sending requests to backends using + the same HTTP protocol that the incoming request used. Defaults to false, which means + that Envoy will use the protocol indicated by the attached BackendRef. + type: boolean required: - targetRef type: object diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index 1bcbce9a1d0..e82d67b932d 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: clienttrafficpolicies.gateway.envoyproxy.io spec: group: gateway.envoyproxy.io @@ -19,9 +19,6 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .status.conditions[?(@.type=="Accepted")].reason - name: Status - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -186,6 +183,44 @@ spec: By default, Envoy will lowercase all the headers. type: boolean type: object + http2: + description: HTTP2 provides HTTP/2 configuration on the listener. + properties: + initialConnectionWindowSize: + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + x-kubernetes-validations: + - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" + rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") + : type(self) == int' + initialStreamWindowSize: + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + x-kubernetes-validations: + - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" + rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") + : type(self) == int' + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + type: object http3: description: HTTP3 provides HTTP/3 configuration on the listener. type: object @@ -438,6 +473,11 @@ spec: type: object maxItems: 8 type: array + optional: + description: |- + Optional set to true accepts connections even when a client doesn't present a certificate. + Defaults to false, which rejects connections without a valid client certificate. + type: boolean type: object ecdhCurves: description: |- diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index 1207b989e8f..f8c0135411b 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: envoyextensionpolicies.gateway.envoyproxy.io spec: group: gateway.envoyproxy.io @@ -17,9 +17,6 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .status.conditions[?(@.type=="Accepted")].reason - name: Status - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -57,104 +54,148 @@ spec: description: ExtProc defines the configuration for External Processing filter. properties: - backendRef: - description: Service defines the configuration of the external + backendRefs: + description: BackendRefs defines the configuration of the external processing service - properties: - group: - default: "" - description: |- - Group is the group of the referent. For example, "gateway.networking.k8s.io". - When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: |- - Kind is the Kubernetes resource kind of the referent. For example - "Service". + items: + description: BackendRef defines how an ObjectReference that + is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". - Defaults to "Service" when not specified. + Defaults to "Service" when not specified. - ExternalName services can refer to CNAME DNS records that may live - outside of the cluster and as such are difficult to reason about in - terms of conformance. They also may not be safe to forward to (see - CVE-2021-25740 for more information). Implementations SHOULD NOT - support ExternalName Services. + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. - Support: Core (Services with a type other than ExternalName) + Support: Core (Services with a type other than ExternalName) - Support: Implementation-specific (Services with type ExternalName) - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace is the namespace of the backend. When unspecified, the local - namespace is inferred. + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. - Note that when a namespace different than the local namespace is specified, - a ReferenceGrant object is required in the referent namespace to allow that - namespace's owner to accept the reference. See the ReferenceGrant - documentation for details. + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. - Support: Core - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + maxItems: 1 + minItems: 1 + type: array + x-kubernetes-validations: + - message: BackendRefs only supports Service kind. + rule: self.all(f, f.kind == 'Service') + - message: BackendRefs only supports Core group. + rule: self.all(f, f.group == '') + failOpen: + description: |- + FailOpen defines if requests or responses that cannot be processed due to connectivity to the + external processor are terminated or passed-through. + Default: false + type: boolean + messageTimeout: + description: |- + MessageTimeout is the timeout for a response to be returned from the external processor + Default: 200ms + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + processingMode: + description: |- + ProcessingMode defines how request and response body is processed + Default: header and body are not sent to the external processor + properties: + request: description: |- - Port specifies the destination port number to use for this resource. - Port is required when the referent is a Kubernetes Service. In this - case, the port number is the service port number, not the target port. - For other resources, destination port might be derived from the referent - resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name + Defines processing mode for requests. If present, request headers are sent. Request body is processed according + to the specified mode. + properties: + body: + description: Defines body processing mode + enum: + - Streamed + - Buffered + - BufferedPartial + type: string + type: object + response: + description: |- + Defines processing mode for responses. If present, response headers are sent. Response body is processed according + to the specified mode. + properties: + body: + description: Defines body processing mode + enum: + - Streamed + - Buffered + - BufferedPartial + type: string + type: object type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') - ? has(self.port) : true' required: - - backendRef + - backendRefs type: object - x-kubernetes-validations: - - message: group is invalid, only the core API group (specified - by omitting the group field or setting it to an empty string) - is supported - rule: 'has(self.backendRef) ? (!has(self.backendRef.group) || - self.backendRef.group == "") : true' - - message: kind is invalid, only Service (specified by omitting - the kind field or setting it to 'Service') is supported - rule: 'has(self.backendRef) ? (!has(self.backendRef.kind) || self.backendRef.kind - == ''Service'') : true' type: array targetRef: description: |- - TargetRef is the name of the Gateway resource this policy + TargetRef is the name of the resource this policy is being attached to. This Policy and the TargetRef MUST be in the same namespace - for this Policy to have effect and be applied to the Gateway. - TargetRef + for this Policy to have effect and be applied to the Gateway or xRoute. properties: group: description: Group is the group of the target resource. @@ -215,7 +256,7 @@ spec: rule: '!has(self.sectionName)' wasm: description: |- - WASM is a list of Wasm extensions to be loaded by the Gateway. + Wasm is a list of Wasm extensions to be loaded by the Gateway. Order matters, as the extensions will be loaded in the order they are defined in this list. items: @@ -301,19 +342,28 @@ spec: - pullSecret - url type: object + sha256: + description: |- + SHA256 checksum that will be used to verify the wasm code. + + + kubebuilder:validation:Pattern=`^[a-f0-9]{64}$` + type: string type: allOf: - enum: - - Global - - Local + - HTTP + - Image - enum: - HTTP - Image + - ConfigMap description: |- Type is the type of the source of the wasm code. Valid WasmCodeSourceType values are "HTTP" or "Image". type: string required: + - sha256 - type type: object config: @@ -337,9 +387,15 @@ spec: Wasm extension if multiple extensions are handled by the same vm_id and root_id. It's also used for logging/debugging. type: string + rootID: + description: |- + RootID is a unique ID for a set of extensions in a VM which will share a + RootContext and Contexts if applicable (e.g., an Wasm HttpFilter and an Wasm AccessLog). + If left blank, all extensions with a blank root_id with the same vm_id will share Context(s). + RootID must match the root_id parameter used to register the Context in the Wasm code. + type: string required: - code - - config - name type: object type: array diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml index 9e20ec9c57e..9bd88ed1bb3 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: envoypatchpolicies.gateway.envoyproxy.io spec: group: gateway.envoyproxy.io diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml index 4232d906453..79328d5b80d 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: envoyproxies.gateway.envoyproxy.io spec: group: gateway.envoyproxy.io @@ -43,6 +43,142 @@ spec: spec: description: EnvoyProxySpec defines the desired state of EnvoyProxy. properties: + backendTLS: + description: |- + BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends. + These settings are applied on backends for which TLS policies are specified. + properties: + alpnProtocols: + description: |- + ALPNProtocols supplies the list of ALPN protocols that should be + exposed by the listener. By default h2 and http/1.1 are enabled. + Supported values are: + - http/1.0 + - http/1.1 + - h2 + items: + description: ALPNProtocol specifies the protocol to be negotiated + using ALPN + enum: + - http/1.0 + - http/1.1 + - h2 + type: string + type: array + ciphers: + description: |- + Ciphers specifies the set of cipher suites supported when + negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3. + In non-FIPS Envoy Proxy builds the default cipher list is: + - [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305] + - [ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305] + - ECDHE-ECDSA-AES256-GCM-SHA384 + - ECDHE-RSA-AES256-GCM-SHA384 + In builds using BoringSSL FIPS the default cipher list is: + - ECDHE-ECDSA-AES128-GCM-SHA256 + - ECDHE-RSA-AES128-GCM-SHA256 + - ECDHE-ECDSA-AES256-GCM-SHA384 + - ECDHE-RSA-AES256-GCM-SHA384 + items: + type: string + type: array + clientCertificateRef: + description: |- + ClientCertificateRef defines the reference to a Kubernetes Secret that contains + the client certificate and private key for Envoy to use when connecting to + backend services and external services, such as ExtAuth, ALS, OpenTelemetry, etc. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Secret + description: Kind is kind of the referent. For example "Secret". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referenced object. When unspecified, the local + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + ecdhCurves: + description: |- + ECDHCurves specifies the set of supported ECDH curves. + In non-FIPS Envoy Proxy builds the default curves are: + - X25519 + - P-256 + In builds using BoringSSL FIPS the default curve is: + - P-256 + items: + type: string + type: array + maxVersion: + description: |- + Max specifies the maximal TLS protocol version to allow + The default is TLS 1.3 if this is not specified. + enum: + - Auto + - "1.0" + - "1.1" + - "1.2" + - "1.3" + type: string + minVersion: + description: |- + Min specifies the minimal TLS protocol version to allow. + The default is TLS 1.2 if this is not specified. + enum: + - Auto + - "1.0" + - "1.1" + - "1.2" + - "1.3" + type: string + signatureAlgorithms: + description: |- + SignatureAlgorithms specifies which signature algorithms the listener should + support. + items: + type: string + type: array + type: object + x-kubernetes-validations: + - message: setting ciphers has no effect if the minimum possible TLS + version is 1.3 + rule: 'has(self.minVersion) && self.minVersion == ''1.3'' ? !has(self.ciphers) + : true' + - message: minVersion must be smaller or equal to maxVersion + rule: 'has(self.minVersion) && has(self.maxVersion) ? {"Auto":0,"1.0":1,"1.1":2,"1.2":3,"1.3":4}[self.minVersion] + <= {"1.0":1,"1.1":2,"1.2":3,"1.3":4,"Auto":5}[self.maxVersion] + : !has(self.minVersion) && has(self.maxVersion) ? 3 <= {"1.0":1,"1.1":2,"1.2":3,"1.3":4,"Auto":5}[self.maxVersion] + : true' bootstrap: description: |- Bootstrap defines the Envoy Bootstrap as a YAML string. @@ -85,6 +221,104 @@ spec: items: type: string type: array + filterOrder: + description: |- + FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. + If unspecified, the default filter order is applied. + Default filter order is: + + + - envoy.filters.http.fault + + + - envoy.filters.http.cors + + + - envoy.filters.http.ext_authz + + + - envoy.filters.http.basic_authn + + + - envoy.filters.http.oauth2 + + + - envoy.filters.http.jwt_authn + + + - envoy.filters.http.ext_proc + + + - envoy.filters.http.wasm + + + - envoy.filters.http.local_ratelimit + + + - envoy.filters.http.ratelimit + + + - envoy.filters.http.router + items: + description: FilterPosition defines the position of an Envoy HTTP + filter in the filter chain. + properties: + after: + description: |- + After defines the filter that should come after the filter. + Only one of Before or After must be set. + enum: + - envoy.filters.http.cors + - envoy.filters.http.ext_authz + - envoy.filters.http.basic_authn + - envoy.filters.http.oauth2 + - envoy.filters.http.jwt_authn + - envoy.filters.http.fault + - envoy.filters.http.local_ratelimit + - envoy.filters.http.ratelimit + - envoy.filters.http.wasm + - envoy.filters.http.ext_proc + type: string + before: + description: |- + Before defines the filter that should come before the filter. + Only one of Before or After must be set. + enum: + - envoy.filters.http.cors + - envoy.filters.http.ext_authz + - envoy.filters.http.basic_authn + - envoy.filters.http.oauth2 + - envoy.filters.http.jwt_authn + - envoy.filters.http.fault + - envoy.filters.http.local_ratelimit + - envoy.filters.http.ratelimit + - envoy.filters.http.wasm + - envoy.filters.http.ext_proc + type: string + filter: + description: Name of the filter. + enum: + - envoy.filters.http.cors + - envoy.filters.http.ext_authz + - envoy.filters.http.basic_authn + - envoy.filters.http.oauth2 + - envoy.filters.http.jwt_authn + - envoy.filters.http.fault + - envoy.filters.http.local_ratelimit + - envoy.filters.http.ratelimit + - envoy.filters.http.wasm + - envoy.filters.http.ext_proc + type: string + required: + - filter + type: object + x-kubernetes-validations: + - message: one of before or after must be specified + rule: (has(self.before) || has(self.after)) + - message: only one of before or after can be specified + rule: (has(self.before) && !has(self.after)) || (!has(self.before) + && has(self.after)) + type: array logging: default: level: @@ -128,11 +362,10 @@ spec: e.g. Envoy proxy. If unspecified and type is "Kubernetes", default settings for managed Kubernetes resources are applied. properties: - envoyDeployment: + envoyDaemonSet: description: |- - EnvoyDeployment defines the desired state of the Envoy deployment resource. - If unspecified, default settings for the managed Envoy deployment resource - are applied. + EnvoyDaemonSet defines the desired state of the Envoy daemonset resource. + Disabled by default, a deployment resource is used instead to provision the Envoy Proxy fleet properties: container: description: Container defines the desired specification @@ -335,6 +568,3755 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + volumeMounts: + description: |- + VolumeMounts are volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + + If ReadOnly is false, this field has no meaning and must be unspecified. + + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + type: object + patch: + description: Patch defines how to perform the patch operation + to daemonset + properties: + type: + description: |- + Type is the type of merge operation to perform + + + By default, StrategicMerge is used as the patch type. + type: string + value: + description: Object contains the raw configuration + for merged object + x-kubernetes-preserve-unknown-fields: true + required: + - value + type: object + pod: + description: Pod defines the desired specification of + pod. + properties: + affinity: + description: If specified, the pod's scheduling constraints. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with + matching the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node + selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling + rules (e.g. co-locate this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + annotations: + additionalProperties: + type: string + description: |- + Annotations are the annotations that should be appended to the pods. + By default, no pod annotations are appended. + type: object + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets + in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + labels: + additionalProperties: + type: string + description: |- + Labels are the additional labels that should be tagged to the pods. + By default, no additional pod labels are tagged. + type: object + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter + to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies + how to spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + volumes: + description: |- + Volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in + a pod that may be accessed by any container in + the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data + Disk mount on the host and bind mount to the + pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the + data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data + disk in the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed + availability set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File + Service mount on the host and bind mount to + the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of + secret that contains Azure Storage Account + Name and Key + type: string + shareName: + description: shareName is the azure share + Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount + on the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as + the mounted root, rather than the full + Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap + that should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) + represents ephemeral storage that is handled + by certain external CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward + API about the pod that should populate this + volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward + API volume file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name, namespace and uid + are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label + query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume + backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine + and then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target + lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC + target worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this + field holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume + attached to a kubelet's host machine. This + depends on the Flocker control service being + running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of + the dataset. This is unique identifier + of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash + for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether + support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target + Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret + for iSCSI target and initiator authentication + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents + a PhotonController persistent disk attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies + Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies + a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one + resources secrets, configmaps, and downward + API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume + projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from + the volume root to write the + bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information + about the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key + to a path within a volume. + properties: + key: + description: key is the + key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: optional specify + whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information + about the downwardAPI data to project + properties: + items: + description: Items is a list of + DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile + represents information to + create the file containing + the pod field + properties: + fieldRef: + description: 'Required: + Selects a field of the + pod: only annotations, + labels, name, namespace + and uid are supported.' + properties: + apiVersion: + description: Version + of the schema the + FieldPath is written + in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of + the field to select + in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: + Path is the relative + path name of the file + to be created. Must not + be absolute or contain + the ''..'' path. Must + be utf-8 encoded. The + first item of the relative + path must not start with + ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container + name: required for + volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies + the output format + of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + description: secret information about + the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key + to a path within a volume. + properties: + key: + description: key is the + key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: optional field specify + whether the Secret or its key + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is + information about the serviceAccountToken + data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: quobyte represents a Quobyte mount + on the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address + of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name + of the ScaleIO Protection Domain for the + configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable + SSL communication with Gateway, default + false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO + Storage Pool associated with the protection + domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere + volume attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage + Policy Based Management (SPBM) profile + ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile + name. + type: string + volumePath: + description: volumePath is the path that + identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + strategy: + description: The daemonset strategy to use to replace + existing pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + type: object + envoyDeployment: + description: |- + EnvoyDeployment defines the desired state of the Envoy deployment resource. + If unspecified, default settings for the managed Envoy deployment resource + are applied. + properties: + container: + description: Container defines the desired specification + of main container. + properties: + env: + description: List of environment variables to set + in the container. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image specifies the EnvoyProxy container + image to be used, instead of the default image. + type: string + resources: + description: |- + Resources required by this container. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -348,6 +4330,7 @@ spec: capabilities type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -355,6 +4338,7 @@ spec: capabilities type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -508,6 +4492,8 @@ spec: to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). type: string name: description: This must match the Name of a Volume. @@ -517,6 +4503,29 @@ spec: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + + If ReadOnly is false, this field has no meaning and must be unspecified. + + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string subPath: description: |- Path within the volume from which the container's volume should be mounted. @@ -556,6 +4565,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic command: description: |- Entrypoint array. Not executed within a shell. @@ -569,6 +4579,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic env: description: |- List of environment variables to set in the container. @@ -689,6 +4700,9 @@ spec: - name type: object type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map envFrom: description: |- List of sources to populate environment variables in the container. @@ -738,6 +4752,7 @@ spec: x-kubernetes-map-type: atomic type: object type: array + x-kubernetes-list-type: atomic image: description: |- Container image name. @@ -779,6 +4794,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object httpGet: description: HTTPGet specifies the http @@ -812,6 +4828,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic path: description: Path to access on the HTTP server. @@ -895,6 +4912,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object httpGet: description: HTTPGet specifies the http @@ -928,6 +4946,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic path: description: Path to access on the HTTP server. @@ -1006,6 +5025,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object failureThreshold: description: |- @@ -1062,6 +5082,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic path: description: Path to access on the HTTP server. @@ -1220,6 +5241,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object failureThreshold: description: |- @@ -1276,6 +5298,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic path: description: Path to access on the HTTP server. @@ -1472,6 +5495,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -1485,6 +5532,7 @@ spec: capabilities type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -1492,6 +5540,7 @@ spec: capabilities type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -1649,6 +5698,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object failureThreshold: description: |- @@ -1705,6 +5755,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic path: description: Path to access on the HTTP server. @@ -1848,6 +5899,9 @@ spec: - name type: object type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map volumeMounts: description: |- Pod volumes to mount into the container's filesystem. @@ -1867,6 +5921,8 @@ spec: to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). type: string name: description: This must match the Name of a @@ -1877,6 +5933,29 @@ spec: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + + If ReadOnly is false, this field has no meaning and must be unspecified. + + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string subPath: description: |- Path within the volume from which the container's volume should be mounted. @@ -1894,6 +5973,9 @@ spec: - name type: object type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map workingDir: description: |- Container's working directory. @@ -1982,11 +6064,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -2015,11 +6099,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic weight: @@ -2033,6 +6119,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -2078,11 +6165,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchFields: description: A list of node selector requirements by node's fields. @@ -2111,14 +6200,17 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic type: object x-kubernetes-map-type: atomic type: array + x-kubernetes-list-type: atomic required: - nodeSelectorTerms type: object @@ -2184,11 +6276,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2203,12 +6297,12 @@ spec: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. - Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2218,12 +6312,12 @@ spec: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. - Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2266,11 +6360,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2290,6 +6386,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2312,6 +6409,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the affinity requirements specified by this field are not met at @@ -2363,11 +6461,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2382,12 +6482,12 @@ spec: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. - Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2397,12 +6497,12 @@ spec: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. - Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2444,11 +6544,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2468,6 +6570,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2480,6 +6583,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object podAntiAffinity: description: Describes pod anti-affinity scheduling @@ -2541,11 +6645,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2560,12 +6666,12 @@ spec: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. - Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2575,12 +6681,12 @@ spec: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. - Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2623,11 +6729,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2647,6 +6755,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2669,6 +6778,7 @@ spec: - weight type: object type: array + x-kubernetes-list-type: atomic requiredDuringSchedulingIgnoredDuringExecution: description: |- If the anti-affinity requirements specified by this field are not met at @@ -2720,11 +6830,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2739,12 +6851,12 @@ spec: description: |- MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. - Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2754,12 +6866,12 @@ spec: description: |- MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the - incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. - The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. - Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. items: type: string @@ -2801,11 +6913,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2825,6 +6939,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic topologyKey: description: |- This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching @@ -2837,6 +6952,7 @@ spec: - topologyKey type: object type: array + x-kubernetes-list-type: atomic type: object type: object annotations: @@ -2886,6 +7002,29 @@ spec: SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- A special supplemental group that applies to all containers in a pod. @@ -3005,6 +7144,7 @@ spec: format: int64 type: integer type: array + x-kubernetes-list-type: atomic sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -3025,6 +7165,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -3139,11 +7280,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3214,9 +7357,6 @@ spec: In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. - - - This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). format: int32 type: integer nodeAffinityPolicy: @@ -3399,6 +7539,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic path: description: 'path is Optional: Used as the mounted root, rather than the full @@ -3528,6 +7669,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: description: |- Name of the referent. @@ -3615,7 +7757,8 @@ spec: fieldRef: description: 'Required: Selects a field of the pod: only annotations, - labels, name and namespace are supported.' + labels, name, namespace and uid + are supported.' properties: apiVersion: description: Version of the schema @@ -3681,6 +7824,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object emptyDir: description: |- @@ -3786,6 +7930,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic dataSource: description: |- dataSource field can be used to specify either: @@ -3933,11 +8078,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3965,7 +8112,7 @@ spec: If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource exists. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. type: string volumeMode: @@ -4011,6 +8158,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic wwids: description: |- wwids Optional: FC volume world wide identifiers (wwids) @@ -4018,6 +8166,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic type: object flexVolume: description: |- @@ -4242,6 +8391,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic readOnly: description: |- readOnly here will force the ReadOnly setting in VolumeMounts. @@ -4438,11 +8588,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -4523,6 +8675,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: description: |- Name of the referent. @@ -4553,8 +8706,8 @@ spec: description: 'Required: Selects a field of the pod: only annotations, - labels, name and namespace - are supported.' + labels, name, namespace + and uid are supported.' properties: apiVersion: description: Version @@ -4628,6 +8781,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic type: object secret: description: secret information about @@ -4672,6 +8826,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic name: description: |- Name of the referent. @@ -4717,6 +8872,7 @@ spec: type: object type: object type: array + x-kubernetes-list-type: atomic type: object quobyte: description: quobyte represents a Quobyte mount @@ -4787,6 +8943,7 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic pool: description: |- pool is the rados pool name. @@ -4946,6 +9103,7 @@ spec: - path type: object type: array + x-kubernetes-list-type: atomic optional: description: optional field specify whether the Secret or its keys must be defined @@ -5343,11 +9501,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5469,11 +9629,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5577,11 +9739,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5761,6 +9925,16 @@ spec: x-kubernetes-validations: - message: loadBalancerIP must be a valid IPv4 address rule: self.matches(r"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$") + loadBalancerSourceRanges: + description: |- + LoadBalancerSourceRanges defines a list of allowed IP addresses which will be configured as + firewall rules on the platform providers load balancer. This is not guaranteed to be working as + it happens outside of kubernetes and has to be supported and handled by the platform provider. + This field may only be set for services with type LoadBalancer and will be cleared if the type + is changed to any other type. + items: + type: string + type: array patch: description: Patch defines how to perform the patch operation to the service @@ -5798,10 +9972,24 @@ spec: LoadBalancer type rule: '!has(self.allocateLoadBalancerNodePorts) || self.type == ''LoadBalancer''' + - message: loadBalancerSourceRanges can only be set for LoadBalancer + type + rule: '!has(self.loadBalancerSourceRanges) || self.type + == ''LoadBalancer''' - message: loadBalancerIP can only be set for LoadBalancer type rule: '!has(self.loadBalancerIP) || self.type == ''LoadBalancer''' type: object + x-kubernetes-validations: + - message: only one of envoyDeployment or envoyDaemonSet can be + specified + rule: ((has(self.envoyDeployment) && !has(self.envoyDaemonSet)) + || (!has(self.envoyDeployment) && has(self.envoyDaemonSet))) + || (!has(self.envoyDeployment) && !has(self.envoyDaemonSet)) + - message: cannot use envoyHpa if envoyDaemonSet is used + rule: ((has(self.envoyHpa) && !has(self.envoyDaemonSet)) || + (!has(self.envoyHpa) && has(self.envoyDaemonSet))) || (!has(self.envoyHpa) + && !has(self.envoyDaemonSet)) type: description: |- Type is the type of resource provider to use. A resource provider provides @@ -5886,6 +10074,147 @@ spec: description: ProxyAccessLogSink defines the sink of accesslog. properties: + als: + description: ALS defines the gRPC Access Log Service + (ALS) sink. + properties: + backendRefs: + description: |- + BackendRefs references a Kubernetes object that represents the gRPC service to which + the access logs will be sent. Currently only Service is supported. + items: + description: BackendRef defines how an ObjectReference + that is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the + referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + maxItems: 1 + minItems: 1 + type: array + x-kubernetes-validations: + - message: BackendRefs only supports Service + kind. + rule: self.all(f, f.kind == 'Service') + http: + description: HTTP defines additional configuration + specific to HTTP access logs. + properties: + requestHeaders: + description: RequestHeaders defines request + headers to include in log entries sent + to the access log service. + items: + type: string + type: array + responseHeaders: + description: ResponseHeaders defines response + headers to include in log entries sent + to the access log service. + items: + type: string + type: array + responseTrailers: + description: ResponseTrailers defines + response trailers to include in log + entries sent to the access log service. + items: + type: string + type: array + type: object + logName: + description: |- + LogName defines the friendly name of the access log to be returned in + StreamAccessLogsMessage.Identifier. This allows the access log server + to differentiate between different access logs coming from the same Envoy. + minLength: 1 + type: string + type: + description: Type defines the type of accesslog. + Supported types are "HTTP" and "TCP". + enum: + - HTTP + - TCP + type: string + required: + - backendRefs + - type + type: object + x-kubernetes-validations: + - message: The http field may only be set when + type is HTTP. + rule: self.type == 'HTTP' || !has(self.http) file: description: File defines the file accesslog sink. properties: @@ -5899,85 +10228,94 @@ spec: description: OpenTelemetry defines the OpenTelemetry accesslog sink. properties: - backendRef: + backendRefs: description: |- - BackendRef references a Kubernetes object that represents the + BackendRefs references a Kubernetes object that represents the backend server to which the accesslog will be sent. Only service Kind is supported for now. - properties: - group: - default: "" - description: |- - Group is the group of the referent. For example, "gateway.networking.k8s.io". - When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: |- - Kind is the Kubernetes resource kind of the referent. For example - "Service". + items: + description: BackendRef defines how an ObjectReference + that is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". - Defaults to "Service" when not specified. + Defaults to "Service" when not specified. - ExternalName services can refer to CNAME DNS records that may live - outside of the cluster and as such are difficult to reason about in - terms of conformance. They also may not be safe to forward to (see - CVE-2021-25740 for more information). Implementations SHOULD NOT - support ExternalName Services. + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. - Support: Core (Services with a type other than ExternalName) + Support: Core (Services with a type other than ExternalName) - Support: Implementation-specific (Services with type ExternalName) - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace is the namespace of the backend. When unspecified, the local - namespace is inferred. + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the + referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. - Note that when a namespace different than the local namespace is specified, - a ReferenceGrant object is required in the referent namespace to allow that - namespace's owner to accept the reference. See the ReferenceGrant - documentation for details. + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. - Support: Core - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: |- - Port specifies the destination port number to use for this resource. - Port is required when the referent is a Kubernetes Service. In this - case, the port number is the service port number, not the target port. - For other resources, destination port might be derived from the referent - resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + maxItems: 1 + type: array x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind - == ''Service'') ? has(self.port) : true' + - message: only support Service kind. + rule: self.all(f, f.kind == 'Service') host: description: |- Host define the extension service hostname. @@ -5998,22 +10336,24 @@ spec: Resources is a set of labels that describe the source of a log entry, including envoy node info. It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). type: object - required: - - host type: object x-kubernetes-validations: - - message: BackendRef only support Service Kind. - rule: '!has(self.backendRef) || !has(self.backendRef.kind) - || self.backendRef.kind == ''Service''' + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() + > 0 type: description: Type defines the type of accesslog sink. enum: + - ALS - File - OpenTelemetry type: string type: object x-kubernetes-validations: + - message: If AccessLogSink type is ALS, als field + needs to be set. + rule: 'self.type == ''ALS'' ? has(self.als) : !has(self.als)' - message: If AccessLogSink type is File, file field needs to be set. rule: 'self.type == ''File'' ? has(self.file) : @@ -6034,6 +10374,11 @@ spec: description: Metrics defines metrics configuration for managed proxies. properties: + enablePerEndpointStats: + description: |- + EnablePerEndpointStats enables per endpoint envoy stats metrics. + Please use with caution. + type: boolean enableVirtualHostStats: description: EnableVirtualHostStats enables envoy stat metrics for virtual hosts. @@ -6075,6 +10420,24 @@ spec: description: Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. properties: + compression: + description: Configure the compression on Prometheus endpoint. + Compression is useful in situations when bandwidth is + scarce and large payloads can be effectively compressed + at the expense of higher CPU load. + properties: + gzip: + description: The configuration for GZIP compressor. + type: object + type: + description: CompressorType defines the compressor + type to use for compression. + enum: + - Gzip + type: string + required: + - type + type: object disable: description: Disable the Prometheus endpoint. type: boolean @@ -6092,85 +10455,93 @@ spec: OpenTelemetry defines the configuration for OpenTelemetry sink. It's required if the sink type is OpenTelemetry. properties: - backendRef: + backendRefs: description: |- - BackendRef references a Kubernetes object that represents the + BackendRefs references a Kubernetes object that represents the backend server to which the metric will be sent. Only service Kind is supported for now. - properties: - group: - default: "" - description: |- - Group is the group of the referent. For example, "gateway.networking.k8s.io". - When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: |- - Kind is the Kubernetes resource kind of the referent. For example - "Service". + items: + description: BackendRef defines how an ObjectReference + that is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". - Defaults to "Service" when not specified. + Defaults to "Service" when not specified. - ExternalName services can refer to CNAME DNS records that may live - outside of the cluster and as such are difficult to reason about in - terms of conformance. They also may not be safe to forward to (see - CVE-2021-25740 for more information). Implementations SHOULD NOT - support ExternalName Services. + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. - Support: Core (Services with a type other than ExternalName) + Support: Core (Services with a type other than ExternalName) - Support: Implementation-specific (Services with type ExternalName) - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace is the namespace of the backend. When unspecified, the local - namespace is inferred. + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. - Note that when a namespace different than the local namespace is specified, - a ReferenceGrant object is required in the referent namespace to allow that - namespace's owner to accept the reference. See the ReferenceGrant - documentation for details. + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. - Support: Core - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: |- - Port specifies the destination port number to use for this resource. - Port is required when the referent is a Kubernetes Service. In this - case, the port number is the service port number, not the target port. - For other resources, destination port might be derived from the referent - resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == + ''Service'') ? has(self.port) : true' + maxItems: 1 + type: array x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == - ''Service'') ? has(self.port) : true' + - message: only support Service kind. + rule: self.all(f, f.kind == 'Service') host: description: |- Host define the service hostname. @@ -6185,13 +10556,11 @@ spec: maximum: 65535 minimum: 0 type: integer - required: - - host type: object x-kubernetes-validations: - - message: BackendRef only support Service Kind. - rule: '!has(self.backendRef) || !has(self.backendRef.kind) - || self.backendRef.kind == ''Service''' + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() > + 0 type: default: OpenTelemetry description: |- @@ -6282,85 +10651,93 @@ spec: Provider defines the tracing provider. Only OpenTelemetry is supported currently. properties: - backendRef: + backendRefs: description: |- - BackendRef references a Kubernetes object that represents the + BackendRefs references a Kubernetes object that represents the backend server to which the accesslog will be sent. Only service Kind is supported for now. - properties: - group: - default: "" - description: |- - Group is the group of the referent. For example, "gateway.networking.k8s.io". - When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: |- - Kind is the Kubernetes resource kind of the referent. For example - "Service". + items: + description: BackendRef defines how an ObjectReference + that is specific to BackendRef. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". - Defaults to "Service" when not specified. + Defaults to "Service" when not specified. - ExternalName services can refer to CNAME DNS records that may live - outside of the cluster and as such are difficult to reason about in - terms of conformance. They also may not be safe to forward to (see - CVE-2021-25740 for more information). Implementations SHOULD NOT - support ExternalName Services. + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. - Support: Core (Services with a type other than ExternalName) + Support: Core (Services with a type other than ExternalName) - Support: Implementation-specific (Services with type ExternalName) - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace is the namespace of the backend. When unspecified, the local - namespace is inferred. + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. - Note that when a namespace different than the local namespace is specified, - a ReferenceGrant object is required in the referent namespace to allow that - namespace's owner to accept the reference. See the ReferenceGrant - documentation for details. + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. - Support: Core - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: |- - Port specifies the destination port number to use for this resource. - Port is required when the referent is a Kubernetes Service. In this - case, the port number is the service port number, not the target port. - For other resources, destination port might be derived from the referent - resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + maxItems: 1 + type: array x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') - ? has(self.port) : true' + - message: only support Service kind. + rule: self.all(f, f.kind == 'Service') host: description: |- Host define the provider service hostname. @@ -6383,13 +10760,11 @@ spec: - OpenTelemetry type: string required: - - host - type type: object x-kubernetes-validations: - - message: BackendRef only support Service Kind. - rule: '!has(self.backendRef) || !has(self.backendRef.kind) - || self.backendRef.kind == ''Service''' + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() > 0 samplingRate: default: 100 description: |- diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index bad8a8f3533..2758a9c2524 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: securitypolicies.gateway.envoyproxy.io spec: group: gateway.envoyproxy.io @@ -19,9 +19,6 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .status.conditions[?(@.type=="Accepted")].reason - name: Status - type: string - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -422,6 +419,11 @@ spec: description: JWT defines the configuration for JSON Web Token (JWT) authentication. properties: + optional: + description: |- + Optional determines whether a missing JWT is acceptable, defaulting to false if not specified. + Note: Even if optional is set to true, JWT authentication will still fail if an invalid JWT is presented. + type: boolean providers: description: |- Providers defines the JSON Web Token (JWT) authentication provider type. diff --git a/charts/gateway-helm/templates/envoy-gateway-service.yaml b/charts/gateway-helm/templates/envoy-gateway-service.yaml index b9dd4cd5f22..099129477f7 100644 --- a/charts/gateway-helm/templates/envoy-gateway-service.yaml +++ b/charts/gateway-helm/templates/envoy-gateway-service.yaml @@ -11,4 +11,4 @@ spec: control-plane: envoy-gateway {{- include "eg.selectorLabels" . | nindent 4 }} ports: - {{- .Values.deployment.ports | toYaml | nindent 2 -}} + {{- .Values.deployment.ports | toYaml | nindent 2 -}} diff --git a/charts/gateway-helm/templates/infra-manager-rbac.yaml b/charts/gateway-helm/templates/infra-manager-rbac.yaml index ad8aa5e5b0b..e8639e978ae 100644 --- a/charts/gateway-helm/templates/infra-manager-rbac.yaml +++ b/charts/gateway-helm/templates/infra-manager-rbac.yaml @@ -20,6 +20,7 @@ rules: - apps resources: - deployments + - daemonsets verbs: - create - get diff --git a/charts/gateway-helm/values.tmpl.yaml b/charts/gateway-helm/values.tmpl.yaml index ce6359dabc6..5ebcd1f3438 100644 --- a/charts/gateway-helm/values.tmpl.yaml +++ b/charts/gateway-helm/values.tmpl.yaml @@ -3,7 +3,7 @@ deployment: image: repository: ${ImageRepository} tag: '${ImageTag}' - imagePullPolicy: Always + imagePullPolicy: IfNotPresent imagePullSecrets: [] resources: limits: @@ -48,7 +48,7 @@ certgen: job: annotations: {} resources: {} - ttlSecondsAfterFinished: 0 + ttlSecondsAfterFinished: 30 rbac: annotations: {} labels: {} diff --git a/go.mod b/go.mod index 17638e32adb..ba3e100d73a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/envoyproxy/gateway -go 1.22 +go 1.22.2 require ( fortio.org/fortio v1.63.7 @@ -8,7 +8,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa github.com/davecgh/go-spew v1.1.1 - github.com/envoyproxy/go-control-plane v0.12.1-0.20240322155512-db0b36a50fa8 + github.com/envoyproxy/go-control-plane v0.12.1-0.20240410145647-bdba4bba15fc github.com/envoyproxy/ratelimit v1.4.1-0.20230427142404-e2a87f41d3a7 github.com/evanphx/json-patch/v5 v5.9.0 github.com/fatih/color v1.16.0 @@ -19,21 +19,21 @@ require ( github.com/golang/protobuf v1.5.4 github.com/google/go-cmp v0.6.0 github.com/grafana/tempo v1.5.0 - github.com/miekg/dns v1.1.58 + github.com/miekg/dns v1.1.59 github.com/prometheus/client_golang v1.19.0 - github.com/prometheus/common v0.52.2 + github.com/prometheus/common v0.53.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7 github.com/tsaarni/certyaml v0.9.3 - go.opentelemetry.io/otel v1.25.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.25.0 - go.opentelemetry.io/otel/exporters/prometheus v0.47.0 - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.25.0 - go.opentelemetry.io/otel/metric v1.25.0 - go.opentelemetry.io/otel/sdk/metric v1.25.0 + go.opentelemetry.io/otel v1.26.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0 + go.opentelemetry.io/otel/exporters/prometheus v0.48.0 + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.26.0 + go.opentelemetry.io/otel/metric v1.26.0 + go.opentelemetry.io/otel/sdk/metric v1.26.0 go.opentelemetry.io/proto/otlp v1.2.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 @@ -41,15 +41,15 @@ require ( google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v3 v3.0.1 - helm.sh/helm/v3 v3.14.3 - k8s.io/api v0.29.3 - k8s.io/apiextensions-apiserver v0.29.3 - k8s.io/apimachinery v0.29.3 - k8s.io/cli-runtime v0.29.3 - k8s.io/client-go v0.29.3 - k8s.io/kubectl v0.29.3 + helm.sh/helm/v3 v3.14.4 + k8s.io/api v0.30.0 + k8s.io/apiextensions-apiserver v0.30.0 + k8s.io/apimachinery v0.30.0 + k8s.io/cli-runtime v0.30.0 + k8s.io/client-go v0.30.0 + k8s.io/kubectl v0.30.0 k8s.io/utils v0.0.0-20230726121419-3b25d923346b - sigs.k8s.io/controller-runtime v0.17.2 + sigs.k8s.io/controller-runtime v0.18.0 sigs.k8s.io/gateway-api v1.0.0 sigs.k8s.io/mcs-api v0.1.0 sigs.k8s.io/yaml v1.4.0 @@ -72,7 +72,7 @@ require ( github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/docker/cli v24.0.6+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect @@ -99,7 +99,7 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect - github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rubenv/sql-migrate v1.5.2 // indirect github.com/shopspring/decimal v1.3.1 // indirect @@ -108,8 +108,8 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - k8s.io/apiserver v0.29.3 // indirect + golang.org/x/crypto v0.22.0 // indirect + k8s.io/apiserver v0.30.0 // indirect oras.land/oras-go v1.2.4 // indirect ) @@ -166,15 +166,15 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/tsaarni/x500dn v1.0.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.opentelemetry.io/otel/sdk v1.25.0 - go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/otel/sdk v1.26.0 + go.opentelemetry.io/otel/trace v1.26.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/mod v0.16.0 // indirect - golang.org/x/net v0.23.0 + golang.org/x/net v0.24.0 golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.19.0 // indirect @@ -185,9 +185,9 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/component-base v0.29.3 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/component-base v0.30.0 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect diff --git a/go.sum b/go.sum index f7a81a16dff..0d42859e767 100644 --- a/go.sum +++ b/go.sum @@ -141,8 +141,8 @@ github.com/docker/cli v24.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvM github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= +github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -167,8 +167,8 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.12.1-0.20240322155512-db0b36a50fa8 h1:Zghtu+wdlGvrmutCyhU9Ew5ozU18PVpxP+zGSgyUpFs= -github.com/envoyproxy/go-control-plane v0.12.1-0.20240322155512-db0b36a50fa8/go.mod h1:YtsM9q/kVkKyvmemY+BF/ZK7I93OWsx4uk4Do2Mr/OA= +github.com/envoyproxy/go-control-plane v0.12.1-0.20240410145647-bdba4bba15fc h1:FJoupBhZkbUXmzGxgAic3rEHeZf8jgvREB7uMfBI23w= +github.com/envoyproxy/go-control-plane v0.12.1-0.20240410145647-bdba4bba15fc/go.mod h1:Dj0RQ153G7gNYzcQCihXUreYTQbuJNuL7IT7v9+jTr4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= @@ -213,7 +213,6 @@ github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -474,8 +473,8 @@ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -522,15 +521,15 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= -github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= @@ -546,8 +545,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795 h1:pH+U6pJP0BhxqQ4njBUjOg0++WMMvv3eByWzB+oATBY= -github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= @@ -569,8 +568,8 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck= -github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -685,24 +684,24 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= -go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= -go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0 h1:hDKnobznDpcdTlNzO0S/owRB8tyVr1OoeZZhDoqY+Cs= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.25.0/go.mod h1:kUDQaUs1h8iTIHbQTk+iJRiUvSfJYMMKTtMCaiVu7B0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.25.0 h1:Wc4hZuYXhVqq+TfRXLXlmNIL/awOanGx8ssq3ciDQxc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.25.0/go.mod h1:BydOvapRqVEc0DVz27qWBX2jq45Ca5TI9mhZBDIdweY= -go.opentelemetry.io/otel/exporters/prometheus v0.47.0 h1:OL6yk1Z/pEGdDnrBbxSsH+t4FY1zXfBRGd7bjwhlMLU= -go.opentelemetry.io/otel/exporters/prometheus v0.47.0/go.mod h1:xF3N4OSICZDVbbYZydz9MHFro1RjmkPUKEvar2utG+Q= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.25.0 h1:d7nHbdzU84STOiszaOxQ3kw5IwkSmHsU5Muol5/vL4I= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.25.0/go.mod h1:yiPA1iZbb/EHYnODXOxvtKuB0I2hV8ehfLTEWpl7BJU= -go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= -go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= -go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= -go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= -go.opentelemetry.io/otel/sdk/metric v1.25.0 h1:7CiHOy08LbrxMAp4vWpbiPcklunUshVpAvGBrdDRlGw= -go.opentelemetry.io/otel/sdk/metric v1.25.0/go.mod h1:LzwoKptdbBBdYfvtGCzGwk6GWMA3aUzBOwtQpR6Nz7o= -go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= -go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0 h1:+hm+I+KigBy3M24/h1p/NHkUx/evbLH0PNcjpMyCHc4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0/go.mod h1:NjC8142mLvvNT6biDpaMjyz78kyEHIwAJlSX0N9P5KI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0 h1:HGZWGmCVRCVyAs2GQaiHQPbDHo+ObFWeUEOd+zDnp64= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0/go.mod h1:SaH+v38LSCHddyk7RGlU9uZyQoRrKao6IBnJw6Kbn+c= +go.opentelemetry.io/otel/exporters/prometheus v0.48.0 h1:sBQe3VNGUjY9IKWQC6z2lNqa5iGbDSxhs60ABwK4y0s= +go.opentelemetry.io/otel/exporters/prometheus v0.48.0/go.mod h1:DtrbMzoZWwQHyrQmCfLam5DZbnmorsGbOtTbYHycU5o= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.26.0 h1:5fnmgteaar1VcAA69huatudPduNFz7guRtCmfZCooZI= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.26.0/go.mod h1:lsPccfZiz1cb1AhBPmicWM2E4F1VynFXEvD8SEBS4TM= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= +go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/sdk/metric v1.26.0 h1:cWSks5tfriHPdWFnl+qpX3P681aAYqlZHcAyHw5aU9Y= +go.opentelemetry.io/otel/sdk/metric v1.26.0/go.mod h1:ClMFFknnThJCksebJwz7KIyEDHO+nTB6gK8obLy8RyE= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= @@ -729,8 +728,8 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= @@ -767,8 +766,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -824,8 +823,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -936,53 +935,53 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= -helm.sh/helm/v3 v3.14.3 h1:HmvRJlwyyt9HjgmAuxHbHv3PhMz9ir/XNWHyXfmnOP4= -helm.sh/helm/v3 v3.14.3/go.mod h1:v6myVbyseSBJTzhmeE39UcPLNv6cQK6qss3dvgAySaE= +helm.sh/helm/v3 v3.14.4 h1:6FSpEfqyDalHq3kUr4gOMThhgY55kXUEjdQoyODYnrM= +helm.sh/helm/v3 v3.14.4/go.mod h1:Tje7LL4gprZpuBNTbG34d1Xn5NmRT3OWfBRwpOSer9I= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4= -k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= -k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= +k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= +k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= -k8s.io/apiextensions-apiserver v0.29.3 h1:9HF+EtZaVpFjStakF4yVufnXGPRppWFEQ87qnO91YeI= -k8s.io/apiextensions-apiserver v0.29.3/go.mod h1:po0XiY5scnpJfFizNGo6puNU6Fq6D70UJY2Cb2KwAVc= +k8s.io/apiextensions-apiserver v0.30.0 h1:jcZFKMqnICJfRxTgnC4E+Hpcq8UEhT8B2lhBcQ+6uAs= +k8s.io/apiextensions-apiserver v0.30.0/go.mod h1:N9ogQFGcrbWqAY9p2mUAL5mGxsLqwgtUce127VtRX5Y= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= -k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= -k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= +k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= +k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8= -k8s.io/apiserver v0.29.3 h1:xR7ELlJ/BZSr2n4CnD3lfA4gzFivh0wwfNfz9L0WZcE= -k8s.io/apiserver v0.29.3/go.mod h1:hrvXlwfRulbMbBgmWRQlFru2b/JySDpmzvQwwk4GUOs= -k8s.io/cli-runtime v0.29.3 h1:r68rephmmytoywkw2MyJ+CxjpasJDQY7AGc3XY2iv1k= -k8s.io/cli-runtime v0.29.3/go.mod h1:aqVUsk86/RhaGJwDhHXH0jcdqBrgdF3bZWk4Z9D4mkM= +k8s.io/apiserver v0.30.0 h1:QCec+U72tMQ+9tR6A0sMBB5Vh6ImCEkoKkTDRABWq6M= +k8s.io/apiserver v0.30.0/go.mod h1:smOIBq8t0MbKZi7O7SyIpjPsiKJ8qa+llcFCluKyqiY= +k8s.io/cli-runtime v0.30.0 h1:0vn6/XhOvn1RJ2KJOC6IRR2CGqrpT6QQF4+8pYpWQ48= +k8s.io/cli-runtime v0.30.0/go.mod h1:vATpDMATVTMA79sZ0YUCzlMelf6rUjoBzlp+RnoM+cg= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g= -k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= -k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= +k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= +k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk= -k8s.io/component-base v0.29.3 h1:Oq9/nddUxlnrCuuR2K/jp6aflVvc0uDvxMzAWxnGzAo= -k8s.io/component-base v0.29.3/go.mod h1:Yuj33XXjuOk2BAaHsIGHhCKZQAgYKhqIxIjIr2UXYio= +k8s.io/component-base v0.30.0 h1:cj6bp38g0ainlfYtaOQuRELh5KSYjhKxM+io7AUIk4o= +k8s.io/component-base v0.30.0/go.mod h1:V9x/0ePFNaKeKYA3bOvIbrNoluTSG+fSJKjLdjOoeXQ= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/kubectl v0.29.3 h1:RuwyyIU42MAISRIePaa8Q7A3U74Q9P4MoJbDFz9o3us= -k8s.io/kubectl v0.29.3/go.mod h1:yCxfY1dbwgVdEt2zkJ6d5NNLOhhWgTyrqACIoFhpdd4= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kubectl v0.30.0 h1:xbPvzagbJ6RNYVMVuiHArC1grrV5vSmmIcSZuCdzRyk= +k8s.io/kubectl v0.30.0/go.mod h1:zgolRw2MQXLPwmic2l/+iHs239L49fhSeICuMhQQXTI= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= @@ -991,8 +990,8 @@ oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY= oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A= -sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= -sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= +sigs.k8s.io/controller-runtime v0.18.0 h1:Z7jKuX784TQSUL1TIyeuF7j8KXZ4RtSX0YgtjKcSTME= +sigs.k8s.io/controller-runtime v0.18.0/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs= sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c= diff --git a/internal/admin/server.go b/internal/admin/server.go index 9c035b43816..29901814381 100644 --- a/internal/admin/server.go +++ b/internal/admin/server.go @@ -17,9 +17,7 @@ import ( "github.com/envoyproxy/gateway/internal/logging" ) -var ( - adminLogger = logging.DefaultLogger(v1alpha1.LogLevelInfo).WithName("admin") -) +var adminLogger = logging.DefaultLogger(v1alpha1.LogLevelInfo).WithName("admin") func Init(cfg *config.Server) error { if cfg.EnvoyGateway.GetEnvoyGatewayAdmin().EnableDumpConfig { diff --git a/internal/cmd/egctl/config_ratelimit.go b/internal/cmd/egctl/config_ratelimit.go index 376ff65cd06..089a52f1f69 100644 --- a/internal/cmd/egctl/config_ratelimit.go +++ b/internal/cmd/egctl/config_ratelimit.go @@ -32,10 +32,7 @@ var ( ) func ratelimitConfigCommand() *cobra.Command { - - var ( - namespace string - ) + var namespace string rlConfigCmd := &cobra.Command{ Use: "envoy-ratelimit", @@ -57,7 +54,6 @@ func ratelimitConfigCommand() *cobra.Command { } func runRateLimitConfig(c *cobra.Command, ns string) error { - cli, err := getCLIClient() if err != nil { return err @@ -73,7 +69,6 @@ func runRateLimitConfig(c *cobra.Command, ns string) error { } func retrieveRateLimitConfig(cli kubernetes.CLIClient, ns string) ([]byte, error) { - // Before retrieving the rate limit configuration // we make sure that the global rate limit feature is enabled if enable, err := checkEnableGlobalRateLimit(cli); !enable { @@ -103,7 +98,6 @@ func retrieveRateLimitConfig(cli kubernetes.CLIClient, ns string) ([]byte, error // fetchRunningRateLimitPods gets the rate limit Pods, based on the labelSelectors. // It further filters out only those rate limit Pods that are in "Running" state. func fetchRunningRateLimitPods(cli kubernetes.CLIClient, namespace string, labelSelector []string) ([]types.NamespacedName, error) { - // Since multiple replicas of the rate limit are configured to be equal, // we do not need to use the pod name to obtain the specified pod. rlPods, err := cli.PodsForSelector(namespace, labelSelector...) @@ -134,7 +128,6 @@ func fetchRunningRateLimitPods(cli kubernetes.CLIClient, namespace string, label // checkRateLimitPodStatusReady Check that the rate limit pod is ready func checkRateLimitPodStatusReady(status corev1.PodStatus) bool { - if status.Phase != corev1.PodRunning { return false } @@ -152,7 +145,6 @@ func checkRateLimitPodStatusReady(status corev1.PodStatus) bool { // extractRateLimitConfig After turning on port forwarding through PortForwarder, // construct a request and send it to the rate limit Pod to obtain relevant configuration information. func extractRateLimitConfig(fw kubernetes.PortForwarder, rlPod types.NamespacedName) ([]byte, error) { - if err := fw.Start(); err != nil { return nil, fmt.Errorf("failed to start port forwarding for pod %s/%s: %w", rlPod.Namespace, rlPod.Name, err) } @@ -168,7 +160,6 @@ func extractRateLimitConfig(fw kubernetes.PortForwarder, rlPod types.NamespacedN // checkEnableGlobalRateLimit Check whether the Global Rate Limit function is enabled func checkEnableGlobalRateLimit(cli kubernetes.CLIClient) (bool, error) { - kubeCli := cli.Kube() cm, err := kubeCli.CoreV1(). ConfigMaps(defaultRateLimitNamespace). diff --git a/internal/cmd/egctl/config_test.go b/internal/cmd/egctl/config_test.go index ff1ad2f8ace..8d1eb45b934 100644 --- a/internal/cmd/egctl/config_test.go +++ b/internal/cmd/egctl/config_test.go @@ -156,7 +156,8 @@ func TestExtractSubResourcesConfigDump(t *testing.T) { output: "yaml", resourceType: BootstrapEnvoyConfigType, expected: "out.bootstrap.yaml", - }, { + }, + { output: "json", resourceType: ClusterEnvoyConfigType, expected: "out.cluster.json", @@ -165,7 +166,8 @@ func TestExtractSubResourcesConfigDump(t *testing.T) { output: "yaml", resourceType: ClusterEnvoyConfigType, expected: "out.cluster.yaml", - }, { + }, + { output: "json", resourceType: ListenerEnvoyConfigType, expected: "out.listener.json", @@ -174,7 +176,8 @@ func TestExtractSubResourcesConfigDump(t *testing.T) { output: "yaml", resourceType: ListenerEnvoyConfigType, expected: "out.listener.yaml", - }, { + }, + { output: "json", resourceType: RouteEnvoyConfigType, expected: "out.route.json", @@ -303,7 +306,6 @@ func (f *fakeCLIClient) Kube() kubernetes.Interface { } func TestFetchRunningRateLimitPods(t *testing.T) { - cases := []struct { caseName string rlPods []corev1.Pod @@ -363,23 +365,18 @@ func TestFetchRunningRateLimitPods(t *testing.T) { } for _, tc := range cases { - t.Run(tc.caseName, func(t *testing.T) { - fakeCli := &fakeCLIClient{ pods: tc.rlPods, } _, err := fetchRunningRateLimitPods(fakeCli, tc.namespace, tc.labelSelector) require.Equal(t, tc.expectErr, err) - }) - } } func TestCheckEnableGlobalRateLimit(t *testing.T) { - cases := []struct { caseName string egConfigMap *corev1.ConfigMap @@ -433,9 +430,7 @@ gateway: } for _, tc := range cases { - t.Run(tc.caseName, func(t *testing.T) { - fakeCli := &fakeCLIClient{ cm: tc.egConfigMap, } @@ -443,14 +438,11 @@ gateway: actual, err := checkEnableGlobalRateLimit(fakeCli) require.Equal(t, tc.expect, actual) require.NoError(t, err) - }) - } } func TestExtractRateLimitConfig(t *testing.T) { - cases := []struct { caseName string responseBody []byte @@ -467,23 +459,18 @@ func TestExtractRateLimitConfig(t *testing.T) { } for _, tc := range cases { - t.Run(tc.caseName, func(t *testing.T) { - fw, err := newFakePortForwarder(tc.responseBody) require.NoError(t, err) out, err := extractRateLimitConfig(fw, tc.rlPod) require.NoError(t, err) require.NotEmpty(t, out) - }) - } } func TestCheckRateLimitPodStatusReady(t *testing.T) { - cases := []struct { caseName string status corev1.PodStatus @@ -538,5 +525,4 @@ func TestCheckRateLimitPodStatusReady(t *testing.T) { require.Equal(t, tc.expect, actual) }) } - } diff --git a/internal/cmd/egctl/envoy_stats.go b/internal/cmd/egctl/envoy_stats.go index c7701da0bcd..c8b22c8d05d 100644 --- a/internal/cmd/egctl/envoy_stats.go +++ b/internal/cmd/egctl/envoy_stats.go @@ -24,9 +24,7 @@ const ( prometheusOutput = "prom" ) -var ( - statsType, outputFormat string -) +var statsType, outputFormat string func newEnvoyStatsCmd() *cobra.Command { var podName, podNamespace string diff --git a/internal/cmd/egctl/install.go b/internal/cmd/egctl/install.go index 640dfca0bd0..076ecb8d2f2 100644 --- a/internal/cmd/egctl/install.go +++ b/internal/cmd/egctl/install.go @@ -13,7 +13,6 @@ import ( ) func newInstallCommand() *cobra.Command { - packageFlags := &helm.PackageOptions{} pt := helm.NewPackageTool() diff --git a/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml b/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml index 3f2009bccf3..3ea1f3f2bc7 100644 --- a/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/quickstart.all.yaml @@ -80,7 +80,7 @@ infraIR: name: envoy-gateway-system/eg/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go index a441378f52a..9d21b20105e 100644 --- a/internal/cmd/egctl/translate.go +++ b/internal/cmd/egctl/translate.go @@ -161,12 +161,14 @@ func getValidOutputTypesStr() string { } func validResourceTypes() []envoyConfigType { - return []envoyConfigType{BootstrapEnvoyConfigType, + return []envoyConfigType{ + BootstrapEnvoyConfigType, EndpointEnvoyConfigType, ClusterEnvoyConfigType, ListenerEnvoyConfigType, RouteEnvoyConfigType, - AllEnvoyConfigType} + AllEnvoyConfigType, + } } func isValidResourceType(outType envoyConfigType) bool { diff --git a/internal/cmd/egctl/translate_test.go b/internal/cmd/egctl/translate_test.go index 6159b832b41..96707159a99 100644 --- a/internal/cmd/egctl/translate_test.go +++ b/internal/cmd/egctl/translate_test.go @@ -26,9 +26,7 @@ import ( "github.com/envoyproxy/gateway/internal/utils/file" ) -var ( - overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") -) +var overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") func TestTranslate(t *testing.T) { testCases := []struct { @@ -353,7 +351,6 @@ func TestTranslate(t *testing.T) { mustUnmarshal(t, requireTestDataOutFile(t, fn), want) opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime") require.Empty(t, cmp.Diff(want, got, opts)) - }) } } diff --git a/internal/cmd/egctl/uninstall.go b/internal/cmd/egctl/uninstall.go index 769222fe271..9241db83197 100644 --- a/internal/cmd/egctl/uninstall.go +++ b/internal/cmd/egctl/uninstall.go @@ -13,7 +13,6 @@ import ( ) func newUnInstallCommand() *cobra.Command { - packageFlags := &helm.PackageOptions{} pt := helm.NewPackageTool() diff --git a/internal/cmd/envoy/shutdown_manager.go b/internal/cmd/envoy/shutdown_manager.go index 5f517365c74..257a3d323bc 100644 --- a/internal/cmd/envoy/shutdown_manager.go +++ b/internal/cmd/envoy/shutdown_manager.go @@ -23,9 +23,7 @@ import ( "github.com/envoyproxy/gateway/internal/xds/bootstrap" ) -var ( - logger = logging.DefaultLogger(v1alpha1.LogLevelInfo).WithName("shutdown-manager") -) +var logger = logging.DefaultLogger(v1alpha1.LogLevelInfo).WithName("shutdown-manager") const ( // ShutdownManagerPort is the port Envoy shutdown manager will listen on. @@ -88,7 +86,7 @@ func ShutdownManager(readyTimeout time.Duration) error { // container to block until ready to terminate. After the graceful drain process // has completed a file will be written to indicate shutdown readiness. func shutdownReadyHandler(w http.ResponseWriter, readyTimeout time.Duration, readyFile string) { - var startTime = time.Now() + startTime := time.Now() logger.Info("received shutdown ready request") @@ -119,8 +117,8 @@ func shutdownReadyHandler(w http.ResponseWriter, readyTimeout time.Duration, rea // it will initiate a graceful drain sequence on the Envoy proxy and block until // connections are drained or a timeout is exceeded. func Shutdown(drainTimeout time.Duration, minDrainDuration time.Duration, exitAtConnections int) error { - var startTime = time.Now() - var allowedToExit = false + startTime := time.Now() + allowedToExit := false // Reconfigure logger to write to stdout of main process if running in Kubernetes if _, k8s := os.LookupEnv("KUBERNETES_SERVICE_HOST"); k8s && os.Getpid() != 1 { diff --git a/internal/cmd/server.go b/internal/cmd/server.go index 1d2741228fe..f2638145872 100644 --- a/internal/cmd/server.go +++ b/internal/cmd/server.go @@ -24,10 +24,8 @@ import ( xdstranslatorrunner "github.com/envoyproxy/gateway/internal/xds/translator/runner" ) -var ( - // cfgPath is the path to the EnvoyGateway configuration file. - cfgPath string -) +// cfgPath is the path to the EnvoyGateway configuration file. +var cfgPath string // getServerCommand returns the server cobra command to be executed. func getServerCommand() *cobra.Command { diff --git a/internal/cmd/server_test.go b/internal/cmd/server_test.go index b6608445e3d..dffe10670c9 100644 --- a/internal/cmd/server_test.go +++ b/internal/cmd/server_test.go @@ -71,5 +71,4 @@ func TestGetConfigValidate(t *testing.T) { } }) } - } diff --git a/internal/crypto/certgen.go b/internal/crypto/certgen.go index 6c6ef10ccbf..de5a6584843 100644 --- a/internal/crypto/certgen.go +++ b/internal/crypto/certgen.go @@ -225,7 +225,6 @@ func newCert(request *certificateRequest) ([]byte, []byte, error) { Bytes: newCert, }) return newCertPEM, newKeyPEM, nil - } // newCA generates a new CA, given the CA's CN and an expiry time. diff --git a/internal/crypto/certgen_test.go b/internal/crypto/certgen_test.go index eb09d6d2c34..429fea518e7 100644 --- a/internal/crypto/certgen_test.go +++ b/internal/crypto/certgen_test.go @@ -129,7 +129,6 @@ func TestGeneratedValidKubeCerts(t *testing.T) { require.NoErrorf(t, err, "Validating %s failed", tc.name) }) } - } func verifyCert(certPEM []byte, roots *x509.CertPool, dnsname string, currentTime time.Time) error { diff --git a/internal/envoygateway/config/decoder_test.go b/internal/envoygateway/config/decoder_test.go index d8c8e36a230..28ce394cb7c 100644 --- a/internal/envoygateway/config/decoder_test.go +++ b/internal/envoygateway/config/decoder_test.go @@ -18,9 +18,7 @@ import ( "github.com/envoyproxy/gateway/api/v1alpha1" ) -var ( - inPath = "./testdata/decoder/in/" -) +var inPath = "./testdata/decoder/in/" func TestDecode(t *testing.T) { testCases := []struct { diff --git a/internal/envoygateway/scheme.go b/internal/envoygateway/scheme.go index 911ae708351..78567e9208c 100644 --- a/internal/envoygateway/scheme.go +++ b/internal/envoygateway/scheme.go @@ -16,15 +16,13 @@ import ( egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" ) -var ( - // scheme contains all the API types necessary for the provider's dynamic - // clients to work. Any new non-core types must be added here. - // - // NOTE: The discovery mechanism used by the client doesn't automatically - // refresh, so only add types here that are guaranteed to exist before the - // provider starts. - scheme = runtime.NewScheme() -) +// scheme contains all the API types necessary for the provider's dynamic +// clients to work. Any new non-core types must be added here. +// +// NOTE: The discovery mechanism used by the client doesn't automatically +// refresh, so only add types here that are guaranteed to exist before the +// provider starts. +var scheme = runtime.NewScheme() func init() { if err := clientgoscheme.AddToScheme(scheme); err != nil { diff --git a/internal/extension/registry/xds_hook.go b/internal/extension/registry/xds_hook.go index a7962d62e7f..e53d90dcd5e 100644 --- a/internal/extension/registry/xds_hook.go +++ b/internal/extension/registry/xds_hook.go @@ -53,7 +53,6 @@ func (h *XDSHook) PostRouteModifyHook(route *route.Route, routeHostnames []strin ExtensionResources: extensionResourceBytes, }, }) - if err != nil { return nil, err } @@ -69,7 +68,6 @@ func (h *XDSHook) PostVirtualHostModifyHook(vh *route.VirtualHost) (*route.Virtu VirtualHost: vh, PostVirtualHostContext: &extension.PostVirtualHostExtensionContext{}, }) - if err != nil { return nil, err } @@ -85,7 +83,6 @@ func (h *XDSHook) PostHTTPListenerModifyHook(l *listener.Listener) (*listener.Li Listener: l, PostListenerContext: &extension.PostHTTPListenerExtensionContext{}, }) - if err != nil { return nil, err } @@ -102,7 +99,6 @@ func (h *XDSHook) PostTranslateModifyHook(clusters []*cluster.Cluster, secrets [ Clusters: clusters, Secrets: secrets, }) - if err != nil { return nil, nil, err } diff --git a/internal/extension/testutils/hooks.go b/internal/extension/testutils/hooks.go index f6b699b34b8..b7b38c1660f 100644 --- a/internal/extension/testutils/hooks.go +++ b/internal/extension/testutils/hooks.go @@ -103,7 +103,6 @@ func (c *XDSHookClient) PostVirtualHostModifyHook(vh *routeV3.VirtualHost) (*rou // A more useful use-case for an extension would be looping through the FilterChains to find the // HTTPConnectionManager(s) and inject a custom HTTPFilter, but that for testing purposes we don't need to make a complex change func (c *XDSHookClient) PostHTTPListenerModifyHook(l *listenerV3.Listener) (*listenerV3.Listener, error) { - // Only make the change when the listener's name matches the expected testdata // This prevents us from having to update every single testfile.out if l.Name == "extension-post-xdslistener-hook-error" { @@ -120,7 +119,6 @@ func (c *XDSHookClient) PostHTTPListenerModifyHook(l *listenerV3.Listener) (*lis // PostTranslateModifyHook inserts and overrides some clusters/secrets func (c *XDSHookClient) PostTranslateModifyHook(clusters []*clusterV3.Cluster, secrets []*tlsV3.Secret) ([]*clusterV3.Cluster, []*tlsV3.Secret, error) { - extensionSvcEndpoint := &endpointV3.LbEndpoint_Endpoint{ Endpoint: &endpointV3.Endpoint{ Address: &coreV3.Address{ diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go index 3a137030a1e..3dcfc9ad214 100644 --- a/internal/gatewayapi/backendtlspolicy.go +++ b/internal/gatewayapi/backendtlspolicy.go @@ -21,7 +21,8 @@ func (t *Translator) processBackendTLSPolicy( backendRef gwapiv1.BackendObjectReference, backendNamespace string, parent gwapiv1a2.ParentReference, - resources *Resources) *ir.TLSUpstreamConfig { + resources *Resources, +) *ir.TLSUpstreamConfig { tlsBundle, err := getBackendTLSBundle(resources.BackendTLSPolicies, resources.ConfigMaps, backendRef, backendNamespace) if err == nil && tlsBundle == nil { return nil @@ -78,12 +79,36 @@ func (t *Translator) processBackendTLSPolicy( } status.SetAcceptedForPolicyAncestors(&policy.Status, ancestorRefs, t.GatewayControllerName) - + // apply defaults as per envoyproxy + if resources.EnvoyProxy != nil { + if resources.EnvoyProxy.Spec.BackendTLS != nil { + if len(resources.EnvoyProxy.Spec.BackendTLS.Ciphers) > 0 { + tlsBundle.Ciphers = resources.EnvoyProxy.Spec.BackendTLS.Ciphers + } + if len(resources.EnvoyProxy.Spec.BackendTLS.ECDHCurves) > 0 { + tlsBundle.ECDHCurves = resources.EnvoyProxy.Spec.BackendTLS.ECDHCurves + } + if len(resources.EnvoyProxy.Spec.BackendTLS.SignatureAlgorithms) > 0 { + tlsBundle.SignatureAlgorithms = resources.EnvoyProxy.Spec.BackendTLS.SignatureAlgorithms + } + if resources.EnvoyProxy.Spec.BackendTLS.MinVersion != nil { + tlsBundle.MinVersion = ptr.To(ir.TLSVersion(*resources.EnvoyProxy.Spec.BackendTLS.MinVersion)) + } + if resources.EnvoyProxy.Spec.BackendTLS.MinVersion != nil { + tlsBundle.MaxVersion = ptr.To(ir.TLSVersion(*resources.EnvoyProxy.Spec.BackendTLS.MaxVersion)) + } + if len(resources.EnvoyProxy.Spec.BackendTLS.ALPNProtocols) > 0 { + tlsBundle.ALPNProtocols = make([]string, len(resources.EnvoyProxy.Spec.BackendTLS.ALPNProtocols)) + for i := range resources.EnvoyProxy.Spec.BackendTLS.ALPNProtocols { + tlsBundle.ALPNProtocols[i] = string(resources.EnvoyProxy.Spec.BackendTLS.ALPNProtocols[i]) + } + } + } + } return tlsBundle } func backendTLSTargetMatched(policy gwapiv1a2.BackendTLSPolicy, target gwapiv1a2.PolicyTargetReferenceWithSectionName) bool { - policyTarget := policy.Spec.TargetRef if target.Group == policyTarget.Group && @@ -109,7 +134,6 @@ func getBackendTLSPolicy(policies []*gwapiv1a2.BackendTLSPolicy, backendRef gwap } func getBackendTLSBundle(policies []*gwapiv1a2.BackendTLSPolicy, configmaps []*corev1.ConfigMap, backendRef gwapiv1a2.BackendObjectReference, backendNamespace string) (*ir.TLSUpstreamConfig, error) { - backendTLSPolicy := getBackendTLSPolicy(policies, backendRef, backendNamespace) if backendTLSPolicy == nil { diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 5748caee206..b77a551d439 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -31,7 +31,8 @@ import ( func (t *Translator) ProcessBackendTrafficPolicies(backendTrafficPolicies []*egv1a1.BackendTrafficPolicy, gateways []*GatewayContext, routes []RouteContext, - xdsIR XdsIRMap) []*egv1a1.BackendTrafficPolicy { + xdsIR XdsIRMap, +) []*egv1a1.BackendTrafficPolicy { var res []*egv1a1.BackendTrafficPolicy // Sort based on timestamp @@ -389,6 +390,10 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen } r.Timeout = to } + + if policy.Spec.UseClientProtocol != nil { + r.UseClientProtocol = policy.Spec.UseClientProtocol + } } } } @@ -560,6 +565,12 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back r.Timeout = ct } } + + if policy.Spec.UseClientProtocol != nil { + if r.UseClientProtocol == nil { + r.UseClientProtocol = policy.Spec.UseClientProtocol + } + } } } @@ -621,7 +632,7 @@ func (t *Translator) buildLocalRateLimit(policy *egv1a1.BackendTrafficPolicy) (* var err error var irRule *ir.RateLimitRule - var irRules = make([]*ir.RateLimitRule, 0) + irRules := make([]*ir.RateLimitRule, 0) for _, rule := range local.Rules { // We don't process the rule without clientSelectors here because it's // previously used as the default route-level limit. diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 8aa416270f3..d4d059dc462 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -28,7 +28,11 @@ import ( const ( // Use an invalid string to represent all sections (listeners) within a Gateway - AllSections = "/" + AllSections = "/" + MinHTTP2InitialStreamWindowSize = 65535 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size + MaxHTTP2InitialStreamWindowSize = 2147483647 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size + MinHTTP2InitialConnectionWindowSize = MinHTTP2InitialStreamWindowSize + MaxHTTP2InitialConnectionWindowSize = MaxHTTP2InitialStreamWindowSize ) func hasSectionName(policy *egv1a1.ClientTrafficPolicy) bool { @@ -37,7 +41,8 @@ func hasSectionName(policy *egv1a1.ClientTrafficPolicy) bool { func (t *Translator) ProcessClientTrafficPolicies(resources *Resources, gateways []*GatewayContext, - xdsIR XdsIRMap, infraIR InfraIRMap) []*egv1a1.ClientTrafficPolicy { + xdsIR XdsIRMap, infraIR InfraIRMap, +) []*egv1a1.ClientTrafficPolicy { var res []*egv1a1.ClientTrafficPolicy clientTrafficPolicies := resources.ClientTrafficPolicies @@ -358,7 +363,8 @@ func validatePortOverlapForClientTrafficPolicy(l *ListenerContext, xds *ir.Xds, } func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.ClientTrafficPolicy, l *ListenerContext, - xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources) error { + xdsIR XdsIRMap, infraIR InfraIRMap, resources *Resources, +) error { // Find IR irKey := t.getIRKey(l.gateway) // It must exist since we've already finished processing the gateways @@ -409,6 +415,11 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie return err } + // Translate HTTP2 Settings + if err := translateHTTP2Settings(policy.Spec.HTTP2, httpIR); err != nil { + return err + } + // enable http3 if set and TLS is enabled if httpIR.TLS != nil && policy.Spec.HTTP3 != nil { http3 := &ir.HTTP3Settings{ @@ -576,8 +587,55 @@ func translateHTTP1Settings(http1Settings *egv1a1.HTTP1Settings, httpIR *ir.HTTP return nil } +func translateHTTP2Settings(http2Settings *egv1a1.HTTP2Settings, httpIR *ir.HTTPListener) error { + if http2Settings == nil { + return nil + } + + var ( + http2 = &ir.HTTP2Settings{} + errs error + ) + + if http2Settings.InitialStreamWindowSize != nil { + initialStreamWindowSize, ok := http2Settings.InitialStreamWindowSize.AsInt64() + switch { + case !ok: + errs = errors.Join(errs, fmt.Errorf("invalid InitialStreamWindowSize value %s", http2Settings.InitialStreamWindowSize.String())) + case initialStreamWindowSize < MinHTTP2InitialStreamWindowSize || initialStreamWindowSize > MaxHTTP2InitialStreamWindowSize: + errs = errors.Join(errs, fmt.Errorf("InitialStreamWindowSize value %s is out of range, must be between %d and %d", + http2Settings.InitialStreamWindowSize.String(), + MinHTTP2InitialStreamWindowSize, + MaxHTTP2InitialStreamWindowSize)) + default: + http2.InitialStreamWindowSize = ptr.To(uint32(initialStreamWindowSize)) + } + } + + if http2Settings.InitialConnectionWindowSize != nil { + initialConnectionWindowSize, ok := http2Settings.InitialConnectionWindowSize.AsInt64() + switch { + case !ok: + errs = errors.Join(errs, fmt.Errorf("invalid InitialConnectionWindowSize value %s", http2Settings.InitialConnectionWindowSize.String())) + case initialConnectionWindowSize < MinHTTP2InitialConnectionWindowSize || initialConnectionWindowSize > MaxHTTP2InitialConnectionWindowSize: + errs = errors.Join(errs, fmt.Errorf("InitialConnectionWindowSize value %s is out of range, must be between %d and %d", + http2Settings.InitialConnectionWindowSize.String(), + MinHTTP2InitialConnectionWindowSize, + MaxHTTP2InitialConnectionWindowSize)) + default: + http2.InitialConnectionWindowSize = ptr.To(uint32(initialConnectionWindowSize)) + } + } + + http2.MaxConcurrentStreams = http2Settings.MaxConcurrentStreams + + httpIR.HTTP2 = http2 + return errs +} + func (t *Translator) translateListenerTLSParameters(policy *egv1a1.ClientTrafficPolicy, - httpIR *ir.HTTPListener, resources *Resources) error { + httpIR *ir.HTTPListener, resources *Resources, +) error { // Return if this listener isn't a TLS listener. There has to be // at least one certificate defined, which would cause httpIR to // have a TLS structure. @@ -674,6 +732,7 @@ func (t *Translator) translateListenerTLSParameters(policy *egv1a1.ClientTraffic if len(irCACert.Certificate) > 0 { httpIR.TLS.CACertificate = irCACert + httpIR.TLS.RequireClientCertificate = !tlsParams.ClientValidation.Optional } } @@ -710,7 +769,8 @@ func translateListenerConnection(connection *egv1a1.Connection, httpIR *ir.HTTPL return fmt.Errorf("invalid BufferLimit value %s", connection.BufferLimit.String()) } if bufferLimit < 0 || bufferLimit > math.MaxUint32 { - return fmt.Errorf("BufferLimit value %s is out of range", connection.BufferLimit.String()) + return fmt.Errorf("BufferLimit value %s is out of range, must be between 0 and %d", + connection.BufferLimit.String(), math.MaxUint32) } irConnection.BufferLimitBytes = ptr.To(uint32(bufferLimit)) } diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index ca843d4d7a9..2e1fe34ffde 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -6,16 +6,17 @@ package gatewayapi import ( + "errors" "fmt" "sort" "strings" + "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1" @@ -29,7 +30,8 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv gateways []*GatewayContext, routes []RouteContext, resources *Resources, - xdsIR XdsIRMap) []*egv1a1.EnvoyExtensionPolicy { + xdsIR XdsIRMap, +) []*egv1a1.EnvoyExtensionPolicy { var res []*egv1a1.EnvoyExtensionPolicy // Sort based on timestamp @@ -292,7 +294,21 @@ func resolveEEPolicyRouteTargetRef(policy *egv1a1.EnvoyExtensionPolicy, routes m } func (t *Translator) translateEnvoyExtensionPolicyForRoute(policy *egv1a1.EnvoyExtensionPolicy, route RouteContext, - xdsIR XdsIRMap, resources *Resources) error { + xdsIR XdsIRMap, resources *Resources, +) error { + var ( + extProcs []ir.ExtProc + wasms []ir.Wasm + err, errs error + ) + + if extProcs, err = t.buildExtProcs(policy, resources); err != nil { + errs = errors.Join(errs, err) + } + if wasms, err = t.buildWasms(policy); err != nil { + errs = errors.Join(errs, err) + } + // Apply IR to all relevant routes prefix := irRoutePrefix(route) for _, ir := range xdsIR { @@ -300,17 +316,14 @@ func (t *Translator) translateEnvoyExtensionPolicyForRoute(policy *egv1a1.EnvoyE for _, r := range http.Routes { // Apply if there is a match if strings.HasPrefix(r.Name, prefix) { - if extProcs, err := t.buildExtProcs(policy, resources); err == nil { - r.ExtProcs = extProcs - } else { - return err - } + r.ExtProcs = extProcs + r.Wasms = wasms } } } } - return nil + return errs } func (t *Translator) buildExtProcs(policy *egv1a1.EnvoyExtensionPolicy, resources *Resources) ([]ir.ExtProc, error) { @@ -320,21 +333,25 @@ func (t *Translator) buildExtProcs(policy *egv1a1.EnvoyExtensionPolicy, resource return nil, nil } - if len(policy.Spec.ExtProc) > 0 { - for idx, ep := range policy.Spec.ExtProc { - name := irConfigNameForEEP(policy, idx) - extProcIR, err := t.buildExtProc(name, utils.NamespacedName(policy), ep, idx, resources) - if err != nil { - return nil, err - } - extProcIRList = append(extProcIRList, *extProcIR) + for idx, ep := range policy.Spec.ExtProc { + name := irConfigNameForEEP(policy, idx) + extProcIR, err := t.buildExtProc(name, utils.NamespacedName(policy), ep, idx, resources) + if err != nil { + return nil, err } + extProcIRList = append(extProcIRList, *extProcIR) } return extProcIRList, nil } func (t *Translator) translateEnvoyExtensionPolicyForGateway(policy *egv1a1.EnvoyExtensionPolicy, - gateway *GatewayContext, xdsIR XdsIRMap, resources *Resources) error { + gateway *GatewayContext, xdsIR XdsIRMap, resources *Resources, +) error { + var ( + extProcs []ir.ExtProc + wasms []ir.Wasm + err, errs error + ) irKey := t.getIRKey(gateway.Gateway) // Should exist since we've validated this @@ -345,9 +362,11 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway(policy *egv1a1.Envo string(policy.Spec.TargetRef.Name), ) - extProcs, err := t.buildExtProcs(policy, resources) - if err != nil { - return err + if extProcs, err = t.buildExtProcs(policy, resources); err != nil { + errs = errors.Join(errs, err) + } + if wasms, err = t.buildWasms(policy); err != nil { + errs = errors.Join(errs, err) } for _, http := range ir.HTTP { @@ -360,13 +379,21 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway(policy *egv1a1.Envo // targeting a lesser specific scope(Gateway). for _, r := range http.Routes { // if already set - there's a route level policy, so skip + if r.ExtProcs != nil || + r.Wasms != nil { + continue + } + if r.ExtProcs == nil { r.ExtProcs = extProcs } + if r.Wasms == nil { + r.Wasms = wasms + } } } - return nil + return errs } func (t *Translator) buildExtProc( @@ -374,50 +401,81 @@ func (t *Translator) buildExtProc( policyNamespacedName types.NamespacedName, extProc egv1a1.ExtProc, extProcIdx int, - resources *Resources) (*ir.ExtProc, error) { + resources *Resources, +) (*ir.ExtProc, error) { var ( - backendRef *gwapiv1.BackendObjectReference - ds *ir.DestinationSetting - authority string - err error + ds *ir.DestinationSetting + authority string + err error ) - backendRef = &extProc.BackendRef.BackendObjectReference - - if err = t.validateExtServiceBackendReference( - backendRef, - policyNamespacedName.Namespace, - resources); err != nil { - return nil, err - } + var dsl []*ir.DestinationSetting + for i := range extProc.BackendRefs { + if err = t.validateExtServiceBackendReference( + &extProc.BackendRefs[i].BackendObjectReference, + policyNamespacedName.Namespace, + resources); err != nil { + return nil, err + } - authority = fmt.Sprintf( - "%s.%s:%d", - backendRef.Name, - NamespaceDerefOr(backendRef.Namespace, policyNamespacedName.Namespace), - *backendRef.Port) + ds, err = t.processExtServiceDestination( + &extProc.BackendRefs[i].BackendObjectReference, + policyNamespacedName, + egv1a1.KindEnvoyExtensionPolicy, + ir.GRPC, + resources) + if err != nil { + return nil, err + } - if ds, err = t.processExtServiceDestination( - backendRef, - policyNamespacedName, - egv1a1.KindEnvoyExtensionPolicy, - ir.GRPC, - resources); err != nil { - return nil, err + dsl = append(dsl, ds) } rd := ir.RouteDestination{ - Name: irIndexedExtServiceDestinationName(policyNamespacedName, egv1a1.KindEnvoyExtensionPolicy, - string(backendRef.Name), extProcIdx), - Settings: []*ir.DestinationSetting{ds}, + Name: irIndexedExtServiceDestinationName(policyNamespacedName, egv1a1.KindEnvoyExtensionPolicy, extProcIdx), + Settings: dsl, } + authority = fmt.Sprintf( + "%s.%s:%d", + extProc.BackendRefs[0].Name, + NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace), + *extProc.BackendRefs[0].Port) + extProcIR := &ir.ExtProc{ Name: name, Destination: rd, Authority: authority, } + if extProc.MessageTimeout != nil { + d, err := time.ParseDuration(string(*extProc.MessageTimeout)) + if err != nil { + return nil, fmt.Errorf("invalid ExtProc MessageTimeout value %v", extProc.MessageTimeout) + } + extProcIR.MessageTimeout = ptr.To(metav1.Duration{Duration: d}) + } + + if extProc.FailOpen != nil { + extProcIR.FailOpen = extProc.FailOpen + } + + if extProc.ProcessingMode != nil { + if extProc.ProcessingMode.Request != nil { + extProcIR.RequestHeaderProcessing = true + if extProc.ProcessingMode.Request.Body != nil { + extProcIR.RequestBodyProcessingMode = ptr.To(ir.ExtProcBodyProcessingMode(*extProc.ProcessingMode.Request.Body)) + } + } + + if extProc.ProcessingMode.Response != nil { + extProcIR.ResponseHeaderProcessing = true + if extProc.ProcessingMode.Response.Body != nil { + extProcIR.ResponseBodyProcessingMode = ptr.To(ir.ExtProcBodyProcessingMode(*extProc.ProcessingMode.Response.Body)) + } + } + } + return extProcIR, err } @@ -428,3 +486,56 @@ func irConfigNameForEEP(policy *egv1a1.EnvoyExtensionPolicy, idx int) string { utils.NamespacedName(policy).String(), idx) } + +func (t *Translator) buildWasms(policy *egv1a1.EnvoyExtensionPolicy) ([]ir.Wasm, error) { + var wasmIRList []ir.Wasm + + if policy == nil { + return nil, nil + } + + for idx, wasm := range policy.Spec.Wasm { + name := irConfigNameForEEP(policy, idx) + wasmIR, err := t.buildWasm(name, wasm) + if err != nil { + return nil, err + } + wasmIRList = append(wasmIRList, *wasmIR) + } + return wasmIRList, nil +} + +func (t *Translator) buildWasm(name string, wasm egv1a1.Wasm) (*ir.Wasm, error) { + var ( + failOpen = false + httpWasmCode *ir.HTTPWasmCode + ) + + if wasm.FailOpen != nil { + failOpen = *wasm.FailOpen + } + + switch wasm.Code.Type { + case egv1a1.HTTPWasmCodeSourceType: + httpWasmCode = &ir.HTTPWasmCode{ + URL: wasm.Code.HTTP.URL, + SHA256: wasm.Code.SHA256, + } + case egv1a1.ImageWasmCodeSourceType: + return nil, fmt.Errorf("OCI image Wasm code source is not supported yet") + default: + // should never happen because of kubebuilder validation, just a sanity check + return nil, fmt.Errorf("unsupported Wasm code source type %q", wasm.Code.Type) + } + + wasmIR := &ir.Wasm{ + Name: name, + RootID: wasm.RootID, + WasmName: wasm.Name, + Config: wasm.Config, + FailOpen: failOpen, + HTTPWasmCode: httpWasmCode, + } + + return wasmIR, nil +} diff --git a/internal/gatewayapi/ext_service.go b/internal/gatewayapi/ext_service.go index a14e2b1258e..ec1c77063a0 100644 --- a/internal/gatewayapi/ext_service.go +++ b/internal/gatewayapi/ext_service.go @@ -26,7 +26,8 @@ func (t *Translator) processExtServiceDestination( policyNamespacedName types.NamespacedName, policyKind string, protocol ir.AppProtocol, - resources *Resources) (*ir.DestinationSetting, error) { + resources *Resources, +) (*ir.DestinationSetting, error) { var ( endpoints []*ir.DestinationEndpoint addrType *ir.DestinationAddressType @@ -93,12 +94,11 @@ func (t *Translator) processExtServiceDestination( } // TODO: also refer to extension type, as WASM may also introduce destinations -func irIndexedExtServiceDestinationName(policyNamespacedName types.NamespacedName, policyKind, service string, idx int) string { +func irIndexedExtServiceDestinationName(policyNamespacedName types.NamespacedName, policyKind string, idx int) string { return strings.ToLower(fmt.Sprintf( - "%s/%s/%s/%d/%s", + "%s/%s/%s/%d", policyKind, policyNamespacedName.Namespace, policyNamespacedName.Name, - idx, - service)) + idx)) } diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go index c728e1e863b..1cde4541f48 100644 --- a/internal/gatewayapi/filters.go +++ b/internal/gatewayapi/filters.go @@ -64,7 +64,8 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext, route RouteContext, filters []gwapiv1.HTTPRouteFilter, ruleIdx int, - resources *Resources) *HTTPFiltersContext { + resources *Resources, +) *HTTPFiltersContext { httpFiltersContext := &HTTPFiltersContext{ ParentRef: parentRef, Route: route, @@ -107,7 +108,8 @@ func (t *Translator) ProcessHTTPFilters(parentRef *RouteParentContext, func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext, route RouteContext, filters []v1alpha2.GRPCRouteFilter, - resources *Resources) *HTTPFiltersContext { + resources *Resources, +) *HTTPFiltersContext { httpFiltersContext := &HTTPFiltersContext{ ParentRef: parentRef, Route: route, @@ -144,7 +146,8 @@ func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext, func (t *Translator) processURLRewriteFilter( rewrite *gwapiv1.HTTPURLRewriteFilter, - filterContext *HTTPFiltersContext) { + filterContext *HTTPFiltersContext, +) { if filterContext.URLRewrite != nil { filterContext.ParentRef.SetCondition(filterContext.Route, gwapiv1.RouteConditionAccepted, @@ -246,7 +249,8 @@ func (t *Translator) processURLRewriteFilter( func (t *Translator) processRedirectFilter( redirect *gwapiv1.HTTPRequestRedirectFilter, - filterContext *HTTPFiltersContext) { + filterContext *HTTPFiltersContext, +) { // Can't have two redirects for the same route if filterContext.RedirectResponse != nil { filterContext.ParentRef.SetCondition(filterContext.Route, @@ -347,7 +351,8 @@ func (t *Translator) processRedirectFilter( func (t *Translator) processRequestHeaderModifierFilter( headerModifier *gwapiv1.HTTPHeaderFilter, - filterContext *HTTPFiltersContext) { + filterContext *HTTPFiltersContext, +) { // Make sure the header modifier config actually exists if headerModifier == nil { return @@ -500,7 +505,8 @@ func (t *Translator) processRequestHeaderModifierFilter( func (t *Translator) processResponseHeaderModifierFilter( headerModifier *gwapiv1.HTTPHeaderFilter, - filterContext *HTTPFiltersContext) { + filterContext *HTTPFiltersContext, +) { // Make sure the header modifier config actually exists if headerModifier == nil { return @@ -693,8 +699,8 @@ func (t *Translator) processRequestMirrorFilter( filterIdx int, mirrorFilter *gwapiv1.HTTPRequestMirrorFilter, filterContext *HTTPFiltersContext, - resources *Resources) { - + resources *Resources, +) { // Make sure the config actually exists if mirrorFilter == nil { return diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 252056f2d7d..269ea9b4147 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -359,6 +359,10 @@ func irUDPListenerName(listener *ListenerContext, udpRoute *UDPRouteContext) str return fmt.Sprintf("%s/%s/%s/%s", listener.gateway.Namespace, listener.gateway.Name, listener.Name, udpRoute.Name) } +func irListenerPortName(proto ir.ProtocolType, port int32) string { + return strings.ToLower(fmt.Sprintf("%s-%d", proto, port)) +} + func irRoutePrefix(route RouteContext) string { // add a "/" at the end of the prefix to prevent mismatching routes with the // same prefix. For example, route prefix "/foo/" should not match a route "/foobar". diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index de94aaf27e9..bab7c4c17c2 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -15,6 +15,7 @@ import ( "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/utils" "github.com/envoyproxy/gateway/internal/utils/naming" + "github.com/envoyproxy/gateway/internal/utils/net" ) var _ ListenersTranslator = (*Translator)(nil) @@ -42,10 +43,7 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap if resources.EnvoyProxy != nil { infraIR[irKey].Proxy.Config = resources.EnvoyProxy } - - xdsIR[irKey].AccessLog = processAccessLog(infraIR[irKey].Proxy.Config) - xdsIR[irKey].Tracing = processTracing(gateway.Gateway, infraIR[irKey].Proxy.Config) - xdsIR[irKey].Metrics = processMetrics(infraIR[irKey].Proxy.Config) + t.processProxyObservability(gateway.Gateway, xdsIR[irKey], infraIR[irKey].Proxy.Config) for _, listener := range gateway.listeners { // Process protocol & supported kinds @@ -129,6 +127,12 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap } } +func (t *Translator) processProxyObservability(gw *gwapiv1.Gateway, xdsIR *ir.Xds, envoyProxy *egv1a1.EnvoyProxy) { + xdsIR.AccessLog = processAccessLog(envoyProxy) + xdsIR.Tracing = processTracing(gw, envoyProxy, t.MergeGateways) + xdsIR.Metrics = processMetrics(envoyProxy) +} + func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR InfraIRMap, irKey string, servicePort *protocolPort) { var proto ir.ProtocolType switch listener.Protocol { @@ -144,12 +148,8 @@ func (t *Translator) processInfraIRListener(listener *ListenerContext, infraIR I proto = ir.UDPProtocolType } - infraPortName := string(listener.Name) - if t.MergeGateways { - infraPortName = irHTTPListenerName(listener) - } infraPort := ir.ListenerPort{ - Name: infraPortName, + Name: irListenerPortName(proto, servicePort.port), Protocol: proto, ServicePort: servicePort.port, ContainerPort: servicePortToContainerPort(servicePort.port), @@ -216,12 +216,20 @@ func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog { continue } + // TODO: remove support for Host/Port in v1.2 al := &ir.OpenTelemetryAccessLog{ Port: uint32(sink.OpenTelemetry.Port), - Host: sink.OpenTelemetry.Host, Resources: sink.OpenTelemetry.Resources, } + if sink.OpenTelemetry.Host != nil { + al.Host = *sink.OpenTelemetry.Host + } + + if len(sink.OpenTelemetry.BackendRefs) > 0 { + al.Host, al.Port = net.BackendHostAndPort(sink.OpenTelemetry.BackendRefs[0].BackendObjectReference, envoyproxy.Namespace) + } + switch accessLog.Format.Type { case egv1a1.ProxyAccessLogFormatTypeJSON: al.Attributes = accessLog.Format.JSON @@ -237,16 +245,40 @@ func processAccessLog(envoyproxy *egv1a1.EnvoyProxy) *ir.AccessLog { return irAccessLog } -func processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy) *ir.Tracing { +func processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.EnvoyProxy, mergeGateways bool) *ir.Tracing { if envoyproxy == nil || envoyproxy.Spec.Telemetry == nil || envoyproxy.Spec.Telemetry.Tracing == nil { return nil } + tracing := envoyproxy.Spec.Telemetry.Tracing + + // TODO: remove support for Host/Port in v1.2 + var host string + var port uint32 + if tracing.Provider.Host != nil { + host, port = *tracing.Provider.Host, uint32(tracing.Provider.Port) + } + if len(tracing.Provider.BackendRefs) > 0 { + host, port = net.BackendHostAndPort(tracing.Provider.BackendRefs[0].BackendObjectReference, gw.Namespace) + } + + samplingRate := 100.0 + if tracing.SamplingRate != nil { + samplingRate = float64(*tracing.SamplingRate) + } + + serviceName := naming.ServiceName(utils.NamespacedName(gw)) + if mergeGateways { + serviceName = string(gw.Spec.GatewayClassName) + } return &ir.Tracing{ - ServiceName: naming.ServiceName(utils.NamespacedName(gw)), - ProxyTracing: *envoyproxy.Spec.Telemetry.Tracing, + ServiceName: serviceName, + Host: host, + Port: port, + SamplingRate: samplingRate, + CustomTags: tracing.CustomTags, } } @@ -258,5 +290,6 @@ func processMetrics(envoyproxy *egv1a1.EnvoyProxy) *ir.Metrics { } return &ir.Metrics{ EnableVirtualHostStats: envoyproxy.Spec.Telemetry.Metrics.EnableVirtualHostStats, + EnablePerEndpointStats: envoyproxy.Spec.Telemetry.Metrics.EnablePerEndpointStats, } } diff --git a/internal/gatewayapi/listener_test.go b/internal/gatewayapi/listener_test.go index ddecda17ada..1da6638f9a8 100644 --- a/internal/gatewayapi/listener_test.go +++ b/internal/gatewayapi/listener_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" egcfgv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" @@ -18,8 +19,9 @@ import ( func TestProcessTracing(t *testing.T) { cases := []struct { - gw gwapiv1.Gateway - proxy *egcfgv1a1.EnvoyProxy + gw gwapiv1.Gateway + proxy *egcfgv1a1.EnvoyProxy + mergedgw bool expected *ir.Tracing }{ @@ -40,7 +42,130 @@ func TestProcessTracing(t *testing.T) { }, expected: &ir.Tracing{ ServiceName: "fake-gw.fake-ns", - ProxyTracing: egcfgv1a1.ProxyTracing{}, + SamplingRate: 100.0, + }, + }, + { + gw: gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-gw", + Namespace: "fake-ns", + }, + Spec: gwapiv1.GatewaySpec{ + GatewayClassName: "fake-gateway-class", + }, + }, + proxy: &egcfgv1a1.EnvoyProxy{ + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Tracing: &egcfgv1a1.ProxyTracing{}, + }, + }, + }, + mergedgw: true, + expected: &ir.Tracing{ + ServiceName: "fake-gateway-class", + SamplingRate: 100.0, + }, + }, + { + gw: gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-gw", + Namespace: "fake-ns", + }, + }, + proxy: &egcfgv1a1.EnvoyProxy{ + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Tracing: &egcfgv1a1.ProxyTracing{ + Provider: egcfgv1a1.TracingProvider{ + Host: ptr.To("fake-host"), + Port: 4317, + }, + }, + }, + }, + }, + expected: &ir.Tracing{ + ServiceName: "fake-gw.fake-ns", + SamplingRate: 100.0, + Host: "fake-host", + Port: 4317, + }, + }, + { + gw: gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-gw", + Namespace: "fake-ns", + }, + }, + proxy: &egcfgv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-eproxy", + Namespace: "fake-ns", + }, + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Tracing: &egcfgv1a1.ProxyTracing{ + Provider: egcfgv1a1.TracingProvider{ + Host: ptr.To("fake-host"), + Port: 4317, + BackendRefs: []egcfgv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-name", + Port: PortNumPtr(4317), + }, + }, + }, + }, + }, + }, + }, + }, + expected: &ir.Tracing{ + ServiceName: "fake-gw.fake-ns", + SamplingRate: 100.0, + Host: "fake-name.fake-ns.svc", + Port: 4317, + }, + }, + { + gw: gwapiv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-gw", + Namespace: "fake-ns", + }, + }, + proxy: &egcfgv1a1.EnvoyProxy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fake-eproxy", + Namespace: "fake-ns", + }, + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Tracing: &egcfgv1a1.ProxyTracing{ + Provider: egcfgv1a1.TracingProvider{ + BackendRefs: []egcfgv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-name", + Port: PortNumPtr(4317), + }, + }, + }, + }, + }, + }, + }, + }, + expected: &ir.Tracing{ + ServiceName: "fake-gw.fake-ns", + SamplingRate: 100.0, + Host: "fake-name.fake-ns.svc", + Port: 4317, }, }, } @@ -48,7 +173,7 @@ func TestProcessTracing(t *testing.T) { for _, c := range cases { c := c t.Run("", func(t *testing.T) { - got := processTracing(&c.gw, c.proxy) + got := processTracing(&c.gw, c.proxy, c.mergedgw) assert.Equal(t, c.expected, got) }) } @@ -79,6 +204,21 @@ func TestProcessMetrics(t *testing.T) { EnableVirtualHostStats: true, }, }, + { + name: "peer endpoint stats enabled", + proxy: &egcfgv1a1.EnvoyProxy{ + Spec: egcfgv1a1.EnvoyProxySpec{ + Telemetry: &egcfgv1a1.ProxyTelemetry{ + Metrics: &egcfgv1a1.ProxyMetrics{ + EnablePerEndpointStats: true, + }, + }, + }, + }, + expected: &ir.Metrics{ + EnablePerEndpointStats: true, + }, + }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { diff --git a/internal/gatewayapi/resource.go b/internal/gatewayapi/resource.go index f930801c2bf..7ba85502b99 100644 --- a/internal/gatewayapi/resource.go +++ b/internal/gatewayapi/resource.go @@ -22,8 +22,10 @@ import ( "github.com/envoyproxy/gateway/internal/ir" ) -type XdsIRMap map[string]*ir.Xds -type InfraIRMap map[string]*ir.Infra +type ( + XdsIRMap map[string]*ir.Xds + InfraIRMap map[string]*ir.Infra +) // Resources holds the Gateway API and related // resources that the translators needs as inputs. diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index 1b0ac613bdd..ce2efc55be6 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -132,7 +132,7 @@ func (t *Translator) processHTTPRouteParentRefs(httpRoute *HTTPRouteContext, res continue } - var hasHostnameIntersection = t.processHTTPRouteParentRefListener(httpRoute, routeRoutes, parentRef, xdsIR) + hasHostnameIntersection := t.processHTTPRouteParentRefListener(httpRoute, routeRoutes, parentRef, xdsIR) if !hasHostnameIntersection { parentRef.SetCondition(httpRoute, gwapiv1.RouteConditionAccepted, @@ -391,7 +391,6 @@ func applyHTTPFiltersContextToIRRoute(httpFiltersContext *HTTPFiltersContext, ir if len(httpFiltersContext.ExtensionRefs) > 0 { irRoute.ExtensionRefs = httpFiltersContext.ExtensionRefs } - } func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, resources *Resources, xdsIR XdsIRMap) { @@ -424,7 +423,7 @@ func (t *Translator) processGRPCRouteParentRefs(grpcRoute *GRPCRouteContext, res if parentRef.HasCondition(grpcRoute, gwapiv1.RouteConditionAccepted, metav1.ConditionFalse) { continue } - var hasHostnameIntersection = t.processHTTPRouteParentRefListener(grpcRoute, routeRoutes, parentRef, xdsIR) + hasHostnameIntersection := t.processHTTPRouteParentRefListener(grpcRoute, routeRoutes, parentRef, xdsIR) if !hasHostnameIntersection { parentRef.SetCondition(grpcRoute, gwapiv1.RouteConditionAccepted, @@ -801,7 +800,8 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour } func (t *Translator) ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways []*GatewayContext, resources *Resources, - xdsIR XdsIRMap) []*UDPRouteContext { + xdsIR XdsIRMap, +) []*UDPRouteContext { var relevantUDPRoutes []*UDPRouteContext for _, u := range udpRoutes { @@ -932,7 +932,8 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour } func (t *Translator) ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways []*GatewayContext, resources *Resources, - xdsIR XdsIRMap) []*TCPRouteContext { + xdsIR XdsIRMap, +) []*TCPRouteContext { var relevantTCPRoutes []*TCPRouteContext for _, tcp := range tcpRoutes { @@ -1068,7 +1069,8 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour func (t *Translator) processDestination(backendRefContext BackendRefContext, parentRef *RouteParentContext, route RouteContext, - resources *Resources) (ds *ir.DestinationSetting, backendWeight uint32) { + resources *Resources, +) (ds *ir.DestinationSetting, backendWeight uint32) { routeType := GetRouteType(route) weight := uint32(1) backendRef := GetBackendRef(backendRefContext) diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go index 4ef2d3d2702..12ebe509a8b 100644 --- a/internal/gatewayapi/runner/runner.go +++ b/internal/gatewayapi/runner/runner.go @@ -123,37 +123,31 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { // Update Status for _, gateway := range result.Gateways { - gateway := gateway key := utils.NamespacedName(gateway) r.ProviderResources.GatewayStatuses.Store(key, &gateway.Status) delete(statusesToDelete.GatewayStatusKeys, key) } for _, httpRoute := range result.HTTPRoutes { - httpRoute := httpRoute key := utils.NamespacedName(httpRoute) r.ProviderResources.HTTPRouteStatuses.Store(key, &httpRoute.Status) delete(statusesToDelete.HTTPRouteStatusKeys, key) } for _, grpcRoute := range result.GRPCRoutes { - grpcRoute := grpcRoute key := utils.NamespacedName(grpcRoute) r.ProviderResources.GRPCRouteStatuses.Store(key, &grpcRoute.Status) delete(statusesToDelete.GRPCRouteStatusKeys, key) } for _, tlsRoute := range result.TLSRoutes { - tlsRoute := tlsRoute key := utils.NamespacedName(tlsRoute) r.ProviderResources.TLSRouteStatuses.Store(key, &tlsRoute.Status) delete(statusesToDelete.TLSRouteStatusKeys, key) } for _, tcpRoute := range result.TCPRoutes { - tcpRoute := tcpRoute key := utils.NamespacedName(tcpRoute) r.ProviderResources.TCPRouteStatuses.Store(key, &tcpRoute.Status) delete(statusesToDelete.TCPRouteStatusKeys, key) } for _, udpRoute := range result.UDPRoutes { - udpRoute := udpRoute key := utils.NamespacedName(udpRoute) r.ProviderResources.UDPRouteStatuses.Store(key, &udpRoute.Status) delete(statusesToDelete.UDPRouteStatusKeys, key) @@ -173,7 +167,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { } for _, clientTrafficPolicy := range result.ClientTrafficPolicies { - clientTrafficPolicy := clientTrafficPolicy key := utils.NamespacedName(clientTrafficPolicy) if !(reflect.ValueOf(clientTrafficPolicy.Status).IsZero()) { r.ProviderResources.ClientTrafficPolicyStatuses.Store(key, &clientTrafficPolicy.Status) @@ -181,7 +174,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { delete(statusesToDelete.ClientTrafficPolicyStatusKeys, key) } for _, backendTrafficPolicy := range result.BackendTrafficPolicies { - backendTrafficPolicy := backendTrafficPolicy key := utils.NamespacedName(backendTrafficPolicy) if !(reflect.ValueOf(backendTrafficPolicy.Status).IsZero()) { r.ProviderResources.BackendTrafficPolicyStatuses.Store(key, &backendTrafficPolicy.Status) @@ -189,7 +181,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) { delete(statusesToDelete.BackendTrafficPolicyStatusKeys, key) } for _, securityPolicy := range result.SecurityPolicies { - securityPolicy := securityPolicy key := utils.NamespacedName(securityPolicy) if !(reflect.ValueOf(securityPolicy.Status).IsZero()) { r.ProviderResources.SecurityPolicyStatuses.Store(key, &securityPolicy.Status) diff --git a/internal/gatewayapi/runner/runner_test.go b/internal/gatewayapi/runner/runner_test.go index 772f0372a3c..a48188cccb7 100644 --- a/internal/gatewayapi/runner/runner_test.go +++ b/internal/gatewayapi/runner/runner_test.go @@ -59,7 +59,6 @@ func TestRunner(t *testing.T) { // Ensure ir is empty return (reflect.DeepEqual(xdsIR.LoadAll(), map[string]*ir.Xds{})) && (reflect.DeepEqual(infraIR.LoadAll(), map[string]*ir.Infra{})) }, time.Second*1, time.Millisecond*20) - } func TestGetIRKeysToDelete(t *testing.T) { @@ -75,7 +74,8 @@ func TestGetIRKeysToDelete(t *testing.T) { newKeys: []string{}, delKeys: []string{}, }, - {name: "no new keys", + { + name: "no new keys", curKeys: []string{"one", "two"}, newKeys: []string{}, delKeys: []string{"one", "two"}, diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index b0c0976534d..6723376c00c 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -45,7 +45,8 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security gateways []*GatewayContext, routes []RouteContext, resources *Resources, - xdsIR XdsIRMap) []*egv1a1.SecurityPolicy { + xdsIR XdsIRMap, +) []*egv1a1.SecurityPolicy { var res []*egv1a1.SecurityPolicy // Sort based on timestamp @@ -225,7 +226,8 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security func resolveSecurityPolicyGatewayTargetRef( policy *egv1a1.SecurityPolicy, - gateways map[types.NamespacedName]*policyGatewayTargetContext) (*GatewayContext, *status.PolicyResolveError) { + gateways map[types.NamespacedName]*policyGatewayTargetContext, +) (*GatewayContext, *status.PolicyResolveError) { targetNs := policy.Spec.TargetRef.Namespace // If empty, default to namespace of policy if targetNs == nil { @@ -278,7 +280,8 @@ func resolveSecurityPolicyGatewayTargetRef( func resolveSecurityPolicyRouteTargetRef( policy *egv1a1.SecurityPolicy, - routes map[policyTargetRouteKey]*policyRouteTargetContext) (RouteContext, *status.PolicyResolveError) { + routes map[policyTargetRouteKey]*policyRouteTargetContext, +) (RouteContext, *status.PolicyResolveError) { targetNs := policy.Spec.TargetRef.Namespace // If empty, default to namespace of policy if targetNs == nil { @@ -333,7 +336,8 @@ func resolveSecurityPolicyRouteTargetRef( func (t *Translator) translateSecurityPolicyForRoute( policy *egv1a1.SecurityPolicy, route RouteContext, - resources *Resources, xdsIR XdsIRMap) error { + resources *Resources, xdsIR XdsIRMap, +) error { // Build IR var ( cors *ir.CORS @@ -380,19 +384,21 @@ func (t *Translator) translateSecurityPolicyForRoute( // Note: there are multiple features in a security policy, even if some of them // are invalid, we still want to apply the valid ones. prefix := irRoutePrefix(route) - for _, ir := range xdsIR { - for _, http := range ir.HTTP { - for _, r := range http.Routes { + for _, x := range xdsIR { + for _, h := range x.HTTP { + for _, r := range h.Routes { // Apply if there is a match - // TODO zhaohuabing: extract a utils function to check if an HTTP // route is associated with a Gateway API xRoute if strings.HasPrefix(r.Name, prefix) { - // This security policy matches the current route. It should only be accepted if it doesn't match any other route - r.CORS = cors - r.JWT = jwt - r.OIDC = oidc - r.BasicAuth = basicAuth - r.ExtAuth = extAuth + // This security policy matches the current route. + // It should only be accepted if it doesn't match any other route + r.Security = &ir.SecurityFeatures{ + CORS: cors, + JWT: jwt, + OIDC: oidc, + BasicAuth: basicAuth, + ExtAuth: extAuth, + } } } } @@ -402,7 +408,8 @@ func (t *Translator) translateSecurityPolicyForRoute( func (t *Translator) translateSecurityPolicyForGateway( policy *egv1a1.SecurityPolicy, gateway *GatewayContext, - resources *Resources, xdsIR XdsIRMap) error { + resources *Resources, xdsIR XdsIRMap, +) error { // Build IR var ( cors *ir.CORS @@ -454,44 +461,32 @@ func (t *Translator) translateSecurityPolicyForGateway( // are invalid, we still want to apply the valid ones. irKey := t.getIRKey(gateway.Gateway) // Should exist since we've validated this - ir := xdsIR[irKey] + x := xdsIR[irKey] policyTarget := irStringKey( string(ptr.Deref(policy.Spec.TargetRef.Namespace, gwv1a2.Namespace(policy.Namespace))), string(policy.Spec.TargetRef.Name), ) - for _, http := range ir.HTTP { - gatewayName := http.Name[0:strings.LastIndex(http.Name, "/")] + for _, h := range x.HTTP { + gatewayName := h.Name[0:strings.LastIndex(h.Name, "/")] if t.MergeGateways && gatewayName != policyTarget { continue } // A Policy targeting the most specific scope(xRoute) wins over a policy // targeting a lesser specific scope(Gateway). - for _, r := range http.Routes { + for _, r := range h.Routes { // If any of the features are already set, it means that a more specific // policy(targeting xRoute) has already set it, so we skip it. - // TODO: zhaohuabing group the features into a struct and check if all of them are set - if r.CORS != nil || - r.JWT != nil || - r.OIDC != nil || - r.BasicAuth != nil || - r.ExtAuth != nil { + if !r.Security.Empty() { continue } - if r.CORS == nil { - r.CORS = cors - } - if r.JWT == nil { - r.JWT = jwt - } - if r.OIDC == nil { - r.OIDC = oidc - } - if r.BasicAuth == nil { - r.BasicAuth = basicAuth - } - if r.ExtAuth == nil { - r.ExtAuth = extAuth + + r.Security = &ir.SecurityFeatures{ + CORS: cors, + JWT: jwt, + OIDC: oidc, + BasicAuth: basicAuth, + ExtAuth: extAuth, } } } @@ -537,13 +532,15 @@ func wildcard2regex(wildcard string) string { func (t *Translator) buildJWT(jwt *egv1a1.JWT) *ir.JWT { return &ir.JWT{ - Providers: jwt.Providers, + AllowMissing: ptr.Deref(jwt.Optional, false), + Providers: jwt.Providers, } } func (t *Translator) buildOIDC( policy *egv1a1.SecurityPolicy, - resources *Resources) (*ir.OIDC, error) { + resources *Resources, +) (*ir.OIDC, error) { var ( oidc = policy.Spec.OIDC clientSecret *v1.Secret @@ -735,7 +732,8 @@ func validateTokenEndpoint(tokenEndpoint string) error { func (t *Translator) buildBasicAuth( policy *egv1a1.SecurityPolicy, - resources *Resources) (*ir.BasicAuth, error) { + resources *Resources, +) (*ir.BasicAuth, error) { var ( basicAuth = policy.Spec.BasicAuth usersSecret *v1.Secret @@ -767,7 +765,8 @@ func (t *Translator) buildBasicAuth( func (t *Translator) buildExtAuth( policy *egv1a1.SecurityPolicy, - resources *Resources) (*ir.ExtAuth, error) { + resources *Resources, +) (*ir.ExtAuth, error) { var ( http = policy.Spec.ExtAuth.HTTP grpc = policy.Spec.ExtAuth.GRPC diff --git a/internal/gatewayapi/sort.go b/internal/gatewayapi/sort.go index 75d9ebc503a..c11787a60dc 100644 --- a/internal/gatewayapi/sort.go +++ b/internal/gatewayapi/sort.go @@ -16,7 +16,6 @@ type XdsIRRoutes []*ir.HTTPRoute func (x XdsIRRoutes) Len() int { return len(x) } func (x XdsIRRoutes) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func (x XdsIRRoutes) Less(i, j int) bool { - // 1. Sort based on path match type // Exact > RegularExpression > PathPrefix if x[i].PathMatch != nil && x[i].PathMatch.Exact != nil { diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml index eb1d0a7ff99..13b0f649be7 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only.out.yaml @@ -119,7 +119,7 @@ infraIR: name: envoy-gateway/gateway-btls/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml index e26e069dfd2..515b77057bc 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns.out.yaml @@ -118,7 +118,7 @@ infraIR: name: envoy-gateway/gateway-btls/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml index ae583f55e47..47e7c66c07e 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml @@ -119,7 +119,7 @@ infraIR: name: envoy-gateway/gateway-btls/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml index bc1904e2b46..a28101f7810 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-system-truststore.out.yaml @@ -115,7 +115,7 @@ infraIR: name: envoy-gateway/gateway-btls/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml index 57382ac7650..6922e60d7c8 100755 --- a/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-without-referencegrant.out.yaml @@ -120,7 +120,7 @@ infraIR: name: envoy-gateway/gateway-btls/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml index 23c2e1c1f5c..18879240a3c 100755 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-override-replace.out.yaml @@ -196,7 +196,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml index 2adaa229dd6..64c6932c2a3 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml @@ -505,7 +505,7 @@ infraIR: name: another-namespace/not-same-namespace-gateway/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -520,7 +520,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -535,14 +535,14 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-2/tcp ports: - containerPort: 10053 - name: tcp + name: tcp-53 protocol: TCP servicePort: 53 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml index 7cbbb266058..b322ce55192 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml @@ -303,7 +303,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -318,7 +318,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.in.yaml new file mode 100644 index 00000000000..5cb15cfc3c6 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.in.yaml @@ -0,0 +1,49 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + useClientProtocol: true + diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml new file mode 100644 index 00000000000..e2f632b1a52 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-use-client-protocol.out.yaml @@ -0,0 +1,160 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + useClientProtocol: true + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + useClientProtocol: true diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml index 867a99f85bc..45d95e8aaf9 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers-error.out.yaml @@ -285,7 +285,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -300,7 +300,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml index 1324a75e0ef..1c0c622624e 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-circuitbreakers.out.yaml @@ -226,7 +226,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -241,7 +241,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml index 34b5a13021e..2205a1cc1b6 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml @@ -436,7 +436,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -451,7 +451,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml index f47f84a874a..f3836170e44 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml @@ -325,7 +325,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -340,7 +340,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml index 26e2ac288e9..4f4cb6d5165 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-default-route-level-limit.out.yaml @@ -137,7 +137,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml index 3100a7e26df..0b81c2dd0de 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-limit-unit.out.yaml @@ -141,7 +141,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml index 853a1ac1c5f..68ed3affde6 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-match-type.out.yaml @@ -137,7 +137,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml index 7acba1f616b..32d1661ea55 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit-invalid-multiple-route-level-limits.out.yaml @@ -144,7 +144,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml index 624ffa15384..11012aa6940 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-local-ratelimit.out.yaml @@ -140,7 +140,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml index b43f116ef08..2344cae4a31 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-proxyprotocol.out.yaml @@ -218,7 +218,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -233,7 +233,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml index 50bf055b039..360544da250 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit-invalid-regex.out.yaml @@ -123,7 +123,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml index 21a149aa542..750b4243777 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-ratelimit.out.yaml @@ -238,7 +238,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -253,7 +253,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml index b3c699e39a3..206b93b9f6a 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml @@ -237,7 +237,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -252,7 +252,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml index aa69f61da8e..130958f4d46 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-same-prefix-httproutes.out.yaml @@ -156,7 +156,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml index 62a0ec8fc75..99e076b98ab 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml @@ -146,14 +146,14 @@ infraIR: name: default/tcp-gateway/foo ports: - containerPort: 8162 - name: foo + name: udp-8162 protocol: UDP servicePort: 8162 - address: null name: default/tcp-gateway/bar ports: - containerPort: 8089 - name: bar + name: tcp-8089 protocol: TCP servicePort: 8089 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml index 774e7e0525b..14eea34c492 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml @@ -221,14 +221,14 @@ infraIR: name: default/tcp-gateway/foo ports: - containerPort: 8162 - name: foo + name: udp-8162 protocol: UDP servicePort: 8162 - address: null name: default/tcp-gateway/bar ports: - containerPort: 8089 - name: bar + name: tcp-8089 protocol: TCP servicePort: 8089 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml index 0610f61fb9c..ea98b67e005 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcpkeepalive.out.yaml @@ -222,7 +222,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -237,7 +237,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml index d54df2b9e25..3adff744df7 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout-error.out.yaml @@ -114,7 +114,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml index 4af65e3ca35..58ea2d64060 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-timeout.out.yaml @@ -226,7 +226,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -241,7 +241,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml index 85ec2d02e9d..f82580ce39f 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-format-error.out.yaml @@ -140,14 +140,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml index 2c9cb161ebf..08c7f6dbbd9 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit-with-out-of-range-error.out.yaml @@ -24,7 +24,7 @@ clientTrafficPolicies: sectionName: http-1 conditions: - lastTransitionTime: null - message: BufferLimit value 100G is out of range + message: BufferLimit value 100G is out of range, must be between 0 and 4294967295 reason: Invalid status: "False" type: Accepted @@ -140,14 +140,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml index 8788cfd2e6c..6969904a40f 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-buffer-limit.out.yaml @@ -140,14 +140,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml index 308d12d7948..61ff96bfeca 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml @@ -230,28 +230,28 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 8081 - name: http-1 + name: http-8081 protocol: HTTP servicePort: 8081 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8082 - name: http-2 + name: http-8082 protocol: HTTP servicePort: 8082 - address: null name: envoy-gateway/gateway-1/http-3 ports: - containerPort: 8083 - name: http-3 + name: http-8083 protocol: HTTP servicePort: 8083 - address: null name: envoy-gateway/gateway-1/http-4 ports: - containerPort: 8084 - name: http-4 + name: http-8084 protocol: HTTP servicePort: 8084 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml index a08fe4b1191..2dfb99f691e 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit-error.out.yaml @@ -142,14 +142,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml index 3ccf5385eb8..651f18ecd1c 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-limit.out.yaml @@ -142,14 +142,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml index 005487ada5b..4a71a59d6d0 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml @@ -106,14 +106,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml index 1165ba87e91..df2e0592b6b 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml @@ -199,21 +199,21 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 - address: null name: envoy-gateway/gateway-1/http-3 ports: - containerPort: 8081 - name: http-3 + name: http-8081 protocol: HTTP servicePort: 8081 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml new file mode 100644 index 00000000000..150b652d513 --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.in.yaml @@ -0,0 +1,55 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1-section-http-1 + spec: + http2: + initialStreamWindowSize: 64Ki + initialConnectionWindowSize: 32Mi + maxConcurrentStreams: 200 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-1 + namespace: envoy-gateway +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1-section-http-2 + spec: + http2: + initialStreamWindowSize: 1Ki + initialConnectionWindowSize: 1Ti + maxConcurrentStreams: 200 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-2 + namespace: envoy-gateway +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-1 + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + - name: http-2 + protocol: HTTP + hostname: www.example.com + port: 8080 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml new file mode 100755 index 00000000000..96d1fc82fec --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2.out.yaml @@ -0,0 +1,191 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1-section-http-1 + namespace: envoy-gateway + spec: + http2: + initialConnectionWindowSize: 32Mi + initialStreamWindowSize: 64Ki + maxConcurrentStreams: 200 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1-section-http-2 + namespace: envoy-gateway + spec: + http2: + initialConnectionWindowSize: 1Ti + initialStreamWindowSize: 1Ki + maxConcurrentStreams: 200 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-2 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-2 + conditions: + - lastTransitionTime: null + message: |- + InitialStreamWindowSize value 1Ki is out of range, must be between 65535 and 2147483647 + InitialConnectionWindowSize value 1Ti is out of range, must be between 65535 and 2147483647 + reason: Invalid + status: "False" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http-1 + port: 80 + protocol: HTTP + - allowedRoutes: + namespaces: + from: Same + hostname: www.example.com + name: http-2 + port: 8080 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-2 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http-1 + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + - address: null + name: envoy-gateway/gateway-1/http-2 + ports: + - containerPort: 8080 + name: http-8080 + protocol: HTTP + servicePort: 8080 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + http2: + initialConnectionWindowSize: 65536 + initialStreamWindowSize: 33554432 + maxConcurrentStreams: 200 + isHTTP2: false + name: envoy-gateway/gateway-1/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + - address: 0.0.0.0 + hostnames: + - www.example.com + http2: + maxConcurrentStreams: 200 + isHTTP2: false + name: envoy-gateway/gateway-1/http-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8080 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml index bfdd73846a2..a58801dd58b 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http3.out.yaml @@ -118,7 +118,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10443 - name: tls + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml index 21cb15d7f46..0854e41ef4d 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout-with-error.out.yaml @@ -77,7 +77,7 @@ infraIR: name: envoy-gateway/gateway/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml index 182fec065b0..efd85a62185 100755 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-idle-timeout.out.yaml @@ -108,14 +108,14 @@ infraIR: name: envoy-gateway/gateway/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.in.yaml new file mode 100644 index 00000000000..9d7c42676b7 --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.in.yaml @@ -0,0 +1,120 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + tls: + clientValidation: + optional: false + caCertificateRefs: + - name: tls-secret-1 + namespace: envoy-gateway +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-2 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + tls: + clientValidation: + optional: true + caCertificateRefs: + - kind: ConfigMap + name: ca-configmap + namespace: envoy-gateway +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-1 + protocol: HTTPS + port: 443 + allowedRoutes: + namespaces: + from: Same + tls: + mode: Terminate + certificateRefs: + - name: tls-secret-1 + namespace: envoy-gateway + - name: http-2 + protocol: HTTP + port: 8080 + allowedRoutes: + namespaces: + from: Same +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-2 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-1 + protocol: HTTPS + port: 443 + allowedRoutes: + namespaces: + from: Same + tls: + mode: Terminate + certificateRefs: + - name: tls-secret-1 + namespace: envoy-gateway +configMaps: +- apiVersion: v1 + kind: ConfigMap + metadata: + name: ca-configmap + namespace: envoy-gateway + data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDOzCCAiOgAwIBAgIUc41kpE9wK+NHgRGvBIgw8SCaz/8wDQYJKoZIhvcNAQEL + BQAwLTEVMBMGA1UECgwMZXhhbXBsZSBJbmMuMRQwEgYDVQQDDAtleGFtcGxlLmNv + bTAeFw0yNDAxMjYyMzE1MzFaFw0yNTAxMjUyMzE1MzFaMC0xFTATBgNVBAoMDGV4 + YW1wbGUgSW5jLjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEB + AQUAA4IBDwAwggEKAoIBAQDCLhZ5DnCVE5JJ97yOocpRwclbl0UwX3cI+1ZZNltl + W6jRgy1GuN6Vr7CBmI/mPtgGs9T7DNRMl5gJJkNHSZomI6GjuP1KUhuvlfbZPWNo + p45T235Z82Gg8ORJHT5mn1QRK+bz9ruJfyldMMlicUJv/Yft6zNURxQ7BU9ciGe1 + tM+UMSxkop3dovVptELnkTDJSwt5dn+nj6j/Gr95z90/e2gjfVTtmArAG3xh/2B1 + /D6NXhwPMzYrplnM3lOpxzflOVgjMUloL1oI7sm6c+2A14NeBrW/ofB9RD7DWBHd + 76j+hcAWFsxYmsHo5Ox/tFeTk7GRdkHEELLWFBvYG0BTAgMBAAGjUzBRMB0GA1Ud + DgQWBBSrLbcQPpEx+Dt+hYE/yrjt6rOV6TAfBgNVHSMEGDAWgBSrLbcQPpEx+Dt+ + hYE/yrjt6rOV6TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCF + 4jltqxVaKZaVML7HNQSwegy+gZ1xalymMNo7Ipc8zOyUUI47weEf/p+nkq8oxi/m + mLZoeMSdXg+gebYMMcURgtl9QfuF0aYCB3AlCxlpdH4Lk3uXNTLQXJiLQRTNsBu/ + LJ6UYvLFKPwodvRKL8KWKEgLVJmrTe3g8iL3SSnw00hWieuCdSsxNl/47ThgYXrg + u1PRBUt5g+XoWpUSOCMOFWlBJqwJYKfRA3E6ff44IUJsb7qUHHAe1wa1YDfuD+T5 + At9/m+M7GyW9oEbSQsPTGfYqP59QE+1iei6qiG+7kn4iRxJqhgm5N5o86QSk0Maz + Cz4jTEKdNvXYVFfh6Zqr + -----END CERTIFICATE----- +secrets: +- apiVersion: v1 + kind: Secret + metadata: + namespace: envoy-gateway + name: tls-secret-1 + type: kubernetes.io/tls + data: + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml new file mode 100644 index 00000000000..f288cfcff8f --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls-client-verification.out.yaml @@ -0,0 +1,289 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1 + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + tls: + clientValidation: + caCertificateRefs: + - group: null + kind: null + name: tls-secret-1 + namespace: envoy-gateway + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-2 + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + tls: + clientValidation: + caCertificateRefs: + - group: null + kind: ConfigMap + name: ca-configmap + namespace: envoy-gateway + optional: true + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http-1 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: null + kind: null + name: tls-secret-1 + namespace: envoy-gateway + mode: Terminate + - allowedRoutes: + namespaces: + from: Same + name: http-2 + port: 8080 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-2 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http-1 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: null + kind: null + name: tls-secret-1 + namespace: envoy-gateway + mode: Terminate + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http-1 + ports: + - containerPort: 10443 + name: https-443 + protocol: HTTPS + servicePort: 443 + - address: null + name: envoy-gateway/gateway-1/http-2 + ports: + - containerPort: 8080 + name: http-8080 + protocol: HTTP + servicePort: 8080 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 + envoy-gateway/gateway-2: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-2/http-1 + ports: + - containerPort: 10443 + name: https-443 + protocol: HTTPS + servicePort: 443 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-2 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-2 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10443 + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + name: envoy-gateway/target-gateway-1/ca.crt + certificates: + - name: envoy-gateway/tls-secret-1 + privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + maxVersion: "1.3" + minVersion: "1.2" + requireClientCertificate: true + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8080 + envoy-gateway/gateway-2: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-2/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10443 + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPekNDQWlPZ0F3SUJBZ0lVYzQxa3BFOXdLK05IZ1JHdkJJZ3c4U0Nhei84d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkpibU11TVJRd0VnWURWUVFEREF0bGVHRnRjR3hsTG1OdgpiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeE1qVXlNekUxTXpGYU1DMHhGVEFUQmdOVkJBb01ER1Y0CllXMXdiR1VnU1c1akxqRVVNQklHQTFVRUF3d0xaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURDTGhaNURuQ1ZFNUpKOTd5T29jcFJ3Y2xibDBVd1gzY0krMVpaTmx0bApXNmpSZ3kxR3VONlZyN0NCbUkvbVB0Z0dzOVQ3RE5STWw1Z0pKa05IU1pvbUk2R2p1UDFLVWh1dmxmYlpQV05vCnA0NVQyMzVaODJHZzhPUkpIVDVtbjFRUksrYno5cnVKZnlsZE1NbGljVUp2L1lmdDZ6TlVSeFE3QlU5Y2lHZTEKdE0rVU1TeGtvcDNkb3ZWcHRFTG5rVERKU3d0NWRuK25qNmovR3I5NXo5MC9lMmdqZlZUdG1BckFHM3hoLzJCMQovRDZOWGh3UE16WXJwbG5NM2xPcHh6ZmxPVmdqTVVsb0wxb0k3c202YysyQTE0TmVCclcvb2ZCOVJEN0RXQkhkCjc2aitoY0FXRnN4WW1zSG81T3gvdEZlVGs3R1Jka0hFRUxMV0ZCdllHMEJUQWdNQkFBR2pVekJSTUIwR0ExVWQKRGdRV0JCU3JMYmNRUHBFeCtEdCtoWUUveXJqdDZyT1Y2VEFmQmdOVkhTTUVHREFXZ0JTckxiY1FQcEV4K0R0KwpoWUUveXJqdDZyT1Y2VEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGCjRqbHRxeFZhS1phVk1MN0hOUVN3ZWd5K2daMXhhbHltTU5vN0lwYzh6T3lVVUk0N3dlRWYvcCtua3E4b3hpL20KbUxab2VNU2RYZytnZWJZTU1jVVJndGw5UWZ1RjBhWUNCM0FsQ3hscGRINExrM3VYTlRMUVhKaUxRUlROc0J1LwpMSjZVWXZMRktQd29kdlJLTDhLV0tFZ0xWSm1yVGUzZzhpTDNTU253MDBoV2lldUNkU3N4TmwvNDdUaGdZWHJnCnUxUFJCVXQ1ZytYb1dwVVNPQ01PRldsQkpxd0pZS2ZSQTNFNmZmNDRJVUpzYjdxVUhIQWUxd2ExWURmdUQrVDUKQXQ5L20rTTdHeVc5b0ViU1FzUFRHZllxUDU5UUUrMWllaTZxaUcrN2tuNGlSeEpxaGdtNU41bzg2UVNrME1hegpDejRqVEVLZE52WFlWRmZoNlpxcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + name: envoy-gateway/target-gateway-2/ca.crt + certificates: + - name: envoy-gateway/tls-secret-1 + privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzc3aHZBUEFlRlJucS8KdHBHVmRKTmVjYWFqSzZrUXlDalk1ci9wWHhOQmE5dldWUUhVbkNXVk95bHBFZGg2T2ZZbUdnb0phdE1UVFlBWAorVml2TFM5WHBIOG5QQ1lhWm9CZGkyUDQxZGtuazJSekZabWwvWFI1SFp0RFpqZURPM3d2Qkpvbm0rTXhQN0JrCjVMZ2U5aEZIUndqRWJMY1k3dys3enE4QkRBeUlIdjdPSjNhN3g5L2pYMlJaRnU3TzVyNXlmRVE2RnNLY3pURG8Kb0N4ZFVrTklndHBWQ29ETEt2Ykw2MW5kTnVsZTMvbURtL3YyU3lUSHVkMVM1ZHFzcDhrSmR1OFhVUmZjMllFbApGS1d2QnRuamgvanJMTVhGY2FoVi9veEpyQ0h1dC9QQ0xiQlRBalRldVNEYXVTN09IYkpSREt3bUg3b1Z2eUlDCmFJeWFZY1pOQWdNQkFBRUNnZ0VBSG1McVd4NHZCbk9ybHFLMGVNLzM5c1lLOEVpTTlra0c5eHRJWGVSTGxCWnIKM2dTeUNSTStXRzk2ZGZkaFkxSDFPa1ZDUGpJOFNEQzRkMzA2Ymw0Ris2RW93TXFrUytjcTlrcDYzYTg3aE5TbQpOMGdxSnl3TGV5YzRXdll2ZFA2c25scnd6MXE3Vk5QbXpQUXJ6b1hIQVc2N2tpeHA1cFF3OG1oVzVQcHlidkp5Clo2TERCZGRSZkVma2ZXVnZUUk5YWUVDUEllUStST05jR3JvVzZ5RXRrbk1BWUJjdjRlNUhCQkkrcHdyYmsrOVMKY2FQYUVjdm4vS0lyT3NpVW1FT2wwb3JXVnhkbjRmMy9MNmlFZFgyZHhIdXlwYkFiL0Qwak1MSzBwb3kyaXYyTApyOGI5VUQrRVZFNmFTVnp0MFRHbVpJYUdRVVZDQnVDTDhodlYwSU9PV1FLQmdRRGplL3JXdmk4Rndia3BRNDA0CnFQcitBaEFwaG1pV3l1a1B1VmJLN2Q5ZkdURzRHOW9Bd2wzYlFoRGVUNHhjMzd0cjlkcCtpamJuWnpKWHczL1cKcm5xTDlGWkZsVXZCYXN6c05VK1lRNmJVOE9zTXl6cURSdGJaaytVWEowUEx6QzZKWHFkNTFZdVVDM3NwL2lmNwpqWEZrME55aHcrdkY3VU51N0ZFSzVuWEUwd0tCZ1FEVGZOT0RLYmZyalNkZEhkV05iOHhkN2pGMlZSY3hTTnRUCit0L0FmbkRjZG8zK1NBUnJaRi9TM0hZWUxxL0l4dmZ5ZHdIblUxdC9INkxDZjBnQ2RXS2NXL1hway93ZUo1QXYKWmdaZjBPTXZsOXF0THJhTU44OG1HblV4K2IxdHZLWm4xQVcySFNuYXd2Z0kvMWVjSldNRUJiYkREbkx4cUpMegowTHJhT2pYVVh3S0JnRGlBbE44OXdjUTJSOTFkNy9mQTBRYkNVRzFmK3g1cEs5WkIvTExPdm9xS1lYVVBSZWltClhsV1ZaVWN5anZTS2hhemRGZllVTW1ycmtPK0htWHNqUDBELzRXWExIVlBmU1NMcVl1aTQ5UGt6RmM3SnM3RGoKcVgzRlpFT0o5eWJwZ2kyUW14eUIwL2RqbXFYbGdOelVWdlBwaE1PUlBFQ2ZHLzZ6SjdZRFpBRU5Bb0dBSElVcQo2UGRKVEVTKzJEbmJ3TFVnOUZIWTdjSlAzRitjNUZoaXNFemMzMzVGYTlNK2RWVVY3eE80QVU3YWVkTUxRUEYzCm1rQ05pRGsxODlEQ1gwS0JSK0RHNnZiLyt2a080clY1aXBaYTdPSW5wVTgxWXZkcndoR3pXRWY3bWI3bEdmOW4KdmNWMURZRlpmYTBoblhjVlFVZWIrL1lJM2pvRGgwblF5UGtzcFRVQ2dZRUF0NERNajdZbStRS2J2bTJXaWNlcAo1Q2s3YWFMSUxuVHZqbGRLMkdjM2loOGVGRlE2Vy9pcUc1UUEzeHMwem8xVnhlUkhPWGkrK01xWjVWTVZMZFRWCjMxWXZOeUdPbVByTitZemVINmlTYXd5VXo2dW1UN1ZkMXRuUEJ1SmdPMFM3RnRlb01BckE3TGtDcUVhMDc4bS8KRXNxNzZjYW1WdW5kRXFTRWhGMllYNkU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + maxVersion: "1.3" + minVersion: "1.2" diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml index e5ee7a11a3c..98db6708cf7 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-mtls.out.yaml @@ -197,14 +197,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10443 - name: http-1 + name: https-443 protocol: HTTPS servicePort: 443 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: @@ -219,7 +219,7 @@ infraIR: name: envoy-gateway/gateway-2/http-1 ports: - containerPort: 10443 - name: http-1 + name: https-443 protocol: HTTPS servicePort: 443 metadata: @@ -252,6 +252,7 @@ xdsIR: serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= maxVersion: "1.3" minVersion: "1.2" + requireClientCertificate: true - address: 0.0.0.0 hostnames: - '*' @@ -285,3 +286,4 @@ xdsIR: serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0RENDQWNnQ0FRQXdEUVlKS29aSWh2Y05BUUVMQlFBd0xURVZNQk1HQTFVRUNnd01aWGhoYlhCc1pTQkoKYm1NdU1SUXdFZ1lEVlFRRERBdGxlR0Z0Y0d4bExtTnZiVEFlRncweU5EQXhNall5TXpFMU16RmFGdzB5TlRBeApNalV5TXpFMU16RmFNRDh4R1RBWEJnTlZCQU1NRUdWa1oyVXVaWGhoYlhCc1pTNWpiMjB4SWpBZ0JnTlZCQW9NCkdXVmtaMlVnWlhoaGJYQnNaU0J2Y21kaGJtbDZZWFJwYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFDNzdodkFQQWVGUm5xL3RwR1ZkSk5lY2Fhaks2a1F5Q2pZNXIvcFh4TkJhOXZXVlFIVQpuQ1dWT3lscEVkaDZPZlltR2dvSmF0TVRUWUFYK1ZpdkxTOVhwSDhuUENZYVpvQmRpMlA0MWRrbmsyUnpGWm1sCi9YUjVIWnREWmplRE8zd3ZCSm9ubStNeFA3Qms1TGdlOWhGSFJ3akViTGNZN3crN3pxOEJEQXlJSHY3T0ozYTcKeDkvalgyUlpGdTdPNXI1eWZFUTZGc0tjelREb29DeGRVa05JZ3RwVkNvRExLdmJMNjFuZE51bGUzL21EbS92MgpTeVRIdWQxUzVkcXNwOGtKZHU4WFVSZmMyWUVsRktXdkJ0bmpoL2pyTE1YRmNhaFYvb3hKckNIdXQvUENMYkJUCkFqVGV1U0RhdVM3T0hiSlJES3dtSDdvVnZ5SUNhSXlhWWNaTkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQUQKZ2dFQkFHeW5yNGNPMWFZbjRNQk90aVJ2WHFJdllHNnpxZXNrNGpQbU96TjdiUTdyRzdNUngzSVQ2SW4zVFI4RApHbFAxVE54TTg5cXZRcXp4VERsdER3bXluTlV1SEdEUW4yV1Z1OFEyK0RqRnFoc3B1WHp0NnhVK2RoVVBxUnV1Ckt6c1l4TDNpMVlWZ2pDQWtBUmp4SGhMWHYwdkFUWUVRMlJ6Uko5c2ZGcWVCMHVxSk5WL0lHamJFSzQ2eTQ5QU0KNzU4TUY4T0R6cVR2Q3hMRjJYd3BScjdjSDFuZ2J4eUJ6cEdlbkpsVTI2Q2hJT1BMZUV1NTUyUVJYVGwrU2JlQQpXUzNpS01Pb3F5NGV0b0ExNWFueW43Zm01YnpINEcyZ3Yxd1pWYlBkT1dNQWRZU2I5NDIvR09CSWUzSnIyVHo3CjRJdDRROWFERnF1aG9iOTVQMUhHQkxSQ2Y5QT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= maxVersion: "1.3" minVersion: "1.2" + requireClientCertificate: true diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml index 419fbf076aa..e16a5cf2344 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-path-settings.out.yaml @@ -106,14 +106,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml index 7deea550663..af97e2397ca 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-preserve-case.out.yaml @@ -106,14 +106,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml index dd61eb7fe89..7b57484d3df 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml @@ -106,14 +106,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml index 5527116ad7d..fddae6e6c9e 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml @@ -458,7 +458,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -473,14 +473,14 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-2/tcp ports: - containerPort: 10053 - name: tcp + name: tcp-53 protocol: TCP servicePort: 53 metadata: @@ -495,7 +495,7 @@ infraIR: name: envoy-gateway/gateway-3/bar-foo ports: - containerPort: 10080 - name: bar-foo + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -510,7 +510,7 @@ infraIR: name: not-same-namespace/not-same-namespace-gateway/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml index fa977c27444..c7557020382 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tcp-keepalive.out.yaml @@ -142,14 +142,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml index 245a10810b3..eaf13c0af18 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout-with-error.out.yaml @@ -77,7 +77,7 @@ infraIR: name: envoy-gateway/gateway/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml index d4fedc92372..9c83084ce76 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-timeout.out.yaml @@ -108,14 +108,14 @@ infraIR: name: envoy-gateway/gateway/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml index e4fcd514d15..924a9a14920 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-tls-settings.out.yaml @@ -123,14 +123,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10443 - name: http-1 + name: https-443 protocol: HTTPS servicePort: 443 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml index cf3abc4f51d..b2c1145c06c 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-trailers.out.yaml @@ -105,14 +105,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8080 - name: http-2 + name: http-8080 protocol: HTTP servicePort: 8080 metadata: diff --git a/internal/gatewayapi/testdata/conflicting-policies.out.yaml b/internal/gatewayapi/testdata/conflicting-policies.out.yaml index d8b882d368a..3f2a1d53418 100644 --- a/internal/gatewayapi/testdata/conflicting-policies.out.yaml +++ b/internal/gatewayapi/testdata/conflicting-policies.out.yaml @@ -215,7 +215,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: default/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -308,20 +308,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowCredentials: true - allowMethods: - - PUT - - GET - - POST - - DELETE - - PATCH - - OPTIONS - allowOrigins: - - distinct: false - name: "" - safeRegex: http://.*\.foo\.com - maxAge: 10m0s destination: name: httproute/default/mfqjpuycbgjrtdww/rule/0 settings: @@ -338,3 +324,18 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowCredentials: true + allowMethods: + - PUT + - GET + - POST + - DELETE + - PATCH + - OPTIONS + allowOrigins: + - distinct: false + name: "" + safeRegex: http://.*\.foo\.com + maxAge: 10m0s diff --git a/internal/gatewayapi/testdata/disable-accesslog.out.yaml b/internal/gatewayapi/testdata/disable-accesslog.out.yaml index c48bad79000..10a49651a17 100644 --- a/internal/gatewayapi/testdata/disable-accesslog.out.yaml +++ b/internal/gatewayapi/testdata/disable-accesslog.out.yaml @@ -108,7 +108,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml index 0f6d26cf62c..6f4ed53ab78 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.in.yaml @@ -26,6 +26,6 @@ envoyExtensionPolicies: name: gateway-1 namespace: envoy-gateway extProc: - - backendRef: - name: grpc-backend-4 + - backendRefs: + - name: grpc-backend-4 port: 4000 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml index 983b95a6114..a545e58625b 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-invalid-cross-ns-ref.out.yaml @@ -7,8 +7,8 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend-4 + - backendRefs: + - name: grpc-backend-4 port: 4000 targetRef: group: gateway.networking.k8s.io @@ -79,7 +79,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml index ce4ecde3766..1d4c61cc7f7 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.in.yaml @@ -86,8 +86,8 @@ envoyExtensionPolicies: name: gateway-1 namespace: envoy-gateway extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend port: 9000 - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy @@ -101,6 +101,6 @@ envoyExtensionPolicies: name: httproute-1 namespace: default extProc: - - backendRef: - name: grpc-backend-2 + - backendRefs: + - name: grpc-backend-2 port: 8000 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml index 1adc83f74aa..cc9921a6bd7 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml @@ -7,8 +7,8 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend-2 + - backendRefs: + - name: grpc-backend-2 port: 8000 targetRef: group: gateway.networking.k8s.io @@ -38,8 +38,8 @@ envoyExtensionPolicies: namespace: envoy-gateway spec: extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend port: 9000 targetRef: group: gateway.networking.k8s.io @@ -192,7 +192,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -231,7 +231,7 @@ xdsIR: extProc: - authority: grpc-backend-2.default:8000 destination: - name: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 + name: envoyextensionpolicy/default/policy-for-route-1/0 settings: - protocol: GRPC weight: 1 @@ -258,7 +258,7 @@ xdsIR: extProc: - authority: grpc-backend.envoy-gateway:9000 destination: - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0 settings: - protocol: GRPC weight: 1 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml index 9d6ba198049..b2abfba7c21 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml @@ -505,7 +505,7 @@ infraIR: name: another-namespace/not-same-namespace-gateway/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -520,7 +520,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -535,14 +535,14 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-2/tcp ports: - containerPort: 10053 - name: tcp + name: tcp-53 protocol: TCP servicePort: 53 metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml index 78989127328..982d7da84e6 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.in.yaml @@ -55,6 +55,6 @@ envoyExtensionPolicies: name: gateway-1 namespace: default extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend port: 4000 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml index 394ccff73d5..740230fbf21 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-matching-port.out.yaml @@ -7,8 +7,8 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend port: 4000 targetRef: group: gateway.networking.k8s.io @@ -117,7 +117,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml index b2420abfa9d..abb0bf36596 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.in.yaml @@ -55,5 +55,5 @@ envoyExtensionPolicies: name: gateway-1 namespace: default extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml index ea8098edd07..50c1a7371d4 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-port.out.yaml @@ -7,8 +7,8 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend targetRef: group: gateway.networking.k8s.io kind: Gateway @@ -117,7 +117,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml index 6d3ec1fdd7e..71f453ec95b 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.in.yaml @@ -55,7 +55,7 @@ envoyExtensionPolicies: name: gateway-1 namespace: default extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend namespace: envoy-gateway port: 9000 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml index 50535c1a392..f62b31daa94 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-reference-grant.out.yaml @@ -7,8 +7,8 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend namespace: envoy-gateway port: 9000 targetRef: @@ -119,7 +119,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml index eff5a17efd2..b58eeee0978 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.in.yaml @@ -46,7 +46,7 @@ envoyExtensionPolicies: name: gateway-1 namespace: default extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend namespace: envoy-gateway port: 9000 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml index 27519cb0302..3ea2c40f4d9 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-invalid-no-service.out.yaml @@ -7,8 +7,8 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend namespace: envoy-gateway port: 9000 targetRef: @@ -118,7 +118,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml index 21c6fab4506..fb3d3cab153 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml @@ -201,10 +201,17 @@ envoyExtensionPolicies: name: gateway-1 namespace: default extProc: - - backendRef: - Name: grpc-backend + - backendRefs: + - Name: grpc-backend Namespace: envoy-gateway Port: 8000 + processingMode: + request: + body: Buffered + response: + body: Streamed + messageTimeout: 5s + failOpen: true - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -217,6 +224,9 @@ envoyExtensionPolicies: name: httproute-1 namespace: default extProc: - - backendRef: - Name: grpc-backend-2 + - backendRefs: + - Name: grpc-backend-2 Port: 9000 + processingMode: + request: {} + response: {} diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml index 66063672452..e33b83f0ec4 100755 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml @@ -73,9 +73,12 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend-2 + - backendRefs: + - name: grpc-backend-2 port: 9000 + processingMode: + request: {} + response: {} targetRef: group: gateway.networking.k8s.io kind: HTTPRoute @@ -104,10 +107,17 @@ envoyExtensionPolicies: namespace: default spec: extProc: - - backendRef: - name: grpc-backend + - backendRefs: + - name: grpc-backend namespace: envoy-gateway port: 8000 + failOpen: true + messageTimeout: 5s + processingMode: + request: + body: Buffered + response: + body: Streamed targetRef: group: gateway.networking.k8s.io kind: Gateway @@ -259,7 +269,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -298,7 +308,7 @@ xdsIR: extProc: - authority: grpc-backend-2.default:9000 destination: - name: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend-2 + name: envoyextensionpolicy/default/policy-for-http-route/0 settings: - addressType: IP endpoints: @@ -312,6 +322,8 @@ xdsIR: sni: grpc-backend-2 weight: 1 name: envoyextensionpolicy/default/policy-for-http-route/0 + requestHeaderProcessing: true + responseHeaderProcessing: true hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_foo_com @@ -334,7 +346,7 @@ xdsIR: extProc: - authority: grpc-backend.envoy-gateway:8000 destination: - name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + name: envoyextensionpolicy/default/policy-for-gateway/0 settings: - addressType: IP protocol: GRPC @@ -344,7 +356,13 @@ xdsIR: name: policy-btls-grpc/default-ca sni: grpc-backend weight: 1 + failOpen: true + messageTimeout: 5s name: envoyextensionpolicy/default/policy-for-gateway/0 + requestBodyProcessingMode: Buffered + requestHeaderProcessing: true + responseBodyProcessingMode: Streamed + responseHeaderProcessing: true hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml new file mode 100644 index 00000000000..a278b45a903 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml @@ -0,0 +1,192 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: default + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - www.foo.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /foo + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - www.bar.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /bar + backendRefs: + - name: service-1 + port: 8080 +services: +- apiVersion: v1 + kind: Service + metadata: + namespace: envoy-gateway + name: grpc-backend + spec: + ports: + - port: 8000 + name: grpc + protocol: TCP +- apiVersion: v1 + kind: Service + metadata: + namespace: default + name: grpc-backend-2 + spec: + ports: + - port: 9000 + name: grpc + protocol: TCP +endpointSlices: +- apiVersion: discovery.k8s.io/v1 + kind: EndpointSlice + metadata: + name: endpointslice-grpc-backend + namespace: envoy-gateway + labels: + kubernetes.io/service-name: grpc-backend + addressType: IPv4 + ports: + - name: http + protocol: TCP + port: 8000 + endpoints: + - addresses: + - 7.7.7.7 + conditions: + ready: true +- apiVersion: discovery.k8s.io/v1 + kind: EndpointSlice + metadata: + name: endpointslice-grpc-backend-2 + namespace: default + labels: + kubernetes.io/service-name: grpc-backend-2 + addressType: IPv4 + ports: + - name: grpc + protocol: TCP + port: 9000 + endpoints: + - addresses: + - 8.8.8.8 + conditions: + ready: true +referenceGrants: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: ReferenceGrant + metadata: + namespace: envoy-gateway + name: referencegrant-1 + spec: + from: + - group: gateway.envoyproxy.io + kind: SecurityPolicy + namespace: default + - group: gateway.networking.k8s.io + kind: BackendTLSPolicy + namespace: default + to: + - group: '' + kind: Service +configMaps: +- apiVersion: v1 + kind: ConfigMap + metadata: + name: ca-cmap + namespace: default + data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL + BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw + MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G + A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc + 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM + yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b + kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU + Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq + ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR + bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48 + 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/ + BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz + 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J + i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE + A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg + d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1 + 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q== + -----END CERTIFICATE----- +backendTLSPolicies: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + name: policy-btls-grpc + namespace: default + spec: + targetRef: + group: '' + kind: Service + name: grpc-backend + namespace: envoy-gateway + sectionName: "8000" + tls: + caCertRefs: + - name: ca-cmap + group: '' + kind: ConfigMap + hostname: grpc-backend +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: default + name: policy-for-http-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + namespace: default + extProc: + - backendRefs: + - Name: grpc-backend + Namespace: envoy-gateway + Port: 8000 + - Name: grpc-backend-2 + Port: 9000 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml new file mode 100755 index 00000000000..a26a321d6e6 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.out.yaml @@ -0,0 +1,277 @@ +backendTLSPolicies: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + creationTimestamp: null + name: policy-btls-grpc + namespace: default + spec: + targetRef: + group: "" + kind: Service + name: grpc-backend + namespace: envoy-gateway + sectionName: "8000" + tls: + caCertRefs: + - group: "" + kind: ConfigMap + name: ca-cmap + hostname: grpc-backend + status: + ancestors: + - ancestorRef: + group: gateway.envoyproxy.io + kind: EnvoyExtensionPolicy + name: policy-for-http-route + namespace: default + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + creationTimestamp: null + name: policy-for-http-route + namespace: default + spec: + extProc: + - backendRefs: + - name: grpc-backend + namespace: envoy-gateway + port: 8000 + - name: grpc-backend-2 + port: 9000 + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + namespace: default + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: default + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 2 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - www.foo.com + parentRefs: + - name: gateway-1 + namespace: default + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: default + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-2 + namespace: default + spec: + hostnames: + - www.bar.com + parentRefs: + - name: gateway-1 + namespace: default + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /bar + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: default + sectionName: http +infraIR: + default/gateway-1: + proxy: + listeners: + - address: null + name: default/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: default + name: default/gateway-1 +xdsIR: + default/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: default/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + extProc: + - authority: grpc-backend.envoy-gateway:8000 + destination: + name: envoyextensionpolicy/default/policy-for-http-route/0 + settings: + - addressType: IP + protocol: GRPC + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/default-ca + sni: grpc-backend + weight: 1 + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + name: envoyextensionpolicy/default/policy-for-http-route/0 + hostname: www.foo.com + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.bar.com + isHTTP2: false + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + pathMatch: + distinct: false + name: "" + prefix: /bar diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml new file mode 100644 index 00000000000..640e1bc189e --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.in.yaml @@ -0,0 +1,112 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - www.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - www.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/bar" + backendRefs: + - name: service-1 + port: 8080 +envoyextensionpolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway # This policy should attach httproute-2 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + wasm: + - name: wasm-filter-1 + code: + type: HTTP + http: + url: https://www.example.com/wasm-filter-1.wasm + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + - name: wasm-filter-2 + code: + type: HTTP + http: + url: https://www.example.com/wasm-filter-2.wasm + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + config: + parameter1: value1 + parameter2: value2 +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: default + name: policy-for-http-route # This policy should attach httproute-1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + namespace: default + wasm: + - name: wasm-filter-3 + code: + type: HTTP + http: + url: https://www.test.com/wasm-filter-3.wasm + sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 + config: + parameter1: + key1: value1 + parameter2: + key2: + key3: value3 + failOpen: true diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml new file mode 100755 index 00000000000..24b531e70f5 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml @@ -0,0 +1,317 @@ +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + creationTimestamp: null + name: policy-for-http-route + namespace: default + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + namespace: default + wasm: + - code: + http: + url: https://www.test.com/wasm-filter-3.wasm + sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 + type: HTTP + config: + parameter1: + key1: value1 + parameter2: + key2: + key3: value3 + failOpen: true + name: wasm-filter-3 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + wasm: + - code: + http: + url: https://www.example.com/wasm-filter-1.wasm + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + type: HTTP + config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + name: wasm-filter-1 + - code: + http: + url: https://www.example.com/wasm-filter-2.wasm + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + type: HTTP + config: + parameter1: value1 + parameter2: value2 + name: wasm-filter-2 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: 'This policy is being overridden by other envoyExtensionPolicies + for these routes: [default/httproute-1]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 2 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - www.example.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-2 + namespace: default + spec: + hostnames: + - www.example.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /bar + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + wasm: + - config: + parameter1: + key1: value1 + parameter2: + key2: + key3: value3 + failOpen: true + httpWasmCode: + sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 + url: https://www.test.com/wasm-filter-3.wasm + name: envoyextensionpolicy/default/policy-for-http-route/0 + wasmName: wasm-filter-3 + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-2/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /bar + wasm: + - config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + failOpen: false + httpWasmCode: + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + url: https://www.example.com/wasm-filter-1.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + wasmName: wasm-filter-1 + - config: + parameter1: value1 + parameter2: value2 + failOpen: false + httpWasmCode: + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + url: https://www.example.com/wasm-filter-2.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + wasmName: wasm-filter-2 diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml index 4d003c79e01..b91f140014a 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-cross-ns-target.out.yaml @@ -47,7 +47,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.out.yaml index eee41351ea5..b1ca7a29071 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.out.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-feature-disabled.out.yaml @@ -58,7 +58,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: envoy-gateway/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.out.yaml index 740bfb7800f..b63636dac9b 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.out.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind-merge-gateways.out.yaml @@ -58,7 +58,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: envoy-gateway/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.out.yaml index 5375d43d51a..a820898caa0 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.out.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-invalid-target-kind.out.yaml @@ -47,7 +47,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml index 69a919f4ccb..8200430befc 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml @@ -58,7 +58,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: envoy-gateway/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml index ccba87e5c50..9a13040a8e9 100644 --- a/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml +++ b/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml @@ -47,7 +47,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml new file mode 100644 index 00000000000..4dccf1a36d3 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.in.yaml @@ -0,0 +1,89 @@ +envoyproxy: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + telemetry: + accessLog: + settings: + - format: + type: Text + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + sinks: + - type: File + file: + path: /dev/stdout + - type: OpenTelemetry + openTelemetry: + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 + resources: + k8s.cluster.name: "cluster-1" + provider: + type: Kubernetes + kubernetes: + envoyService: + type: LoadBalancer + envoyDeployment: + replicas: 2 + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: "envoyproxy/envoy:distroless-dev" + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + pod: + annotations: + key1: val1 + key2: val2 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: "router" + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + fsGroupChangePolicy: "OnRootMismatch" + volumes: + - name: certs + secret: + secretName: envoy-cert +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml new file mode 100755 index 00000000000..265b1a19887 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-backend.out.yaml @@ -0,0 +1,158 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway-system + spec: + logging: {} + provider: + kubernetes: + envoyDeployment: + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: envoyproxy/envoy:distroless-dev + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + runAsUser: 2000 + pod: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + annotations: + key1: val1 + key2: val2 + securityContext: + fsGroup: 2000 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 3000 + runAsUser: 1000 + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: router + volumes: + - name: certs + secret: + secretName: envoy-cert + replicas: 2 + envoyService: + type: LoadBalancer + type: Kubernetes + telemetry: + accessLog: + settings: + - format: + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + type: Text + sinks: + - file: + path: /dev/stdout + type: File + - openTelemetry: + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 + resources: + k8s.cluster.name: cluster-1 + type: OpenTelemetry + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + openTelemetry: + - host: otel-collector.monitoring.svc + port: 4317 + resources: + k8s.cluster.name: cluster-1 + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + text: + - format: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml index 7b6af7c2fd3..76f758a594e 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml @@ -114,7 +114,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json.out.yaml index 73566a7adec..995153edd62 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json.out.yaml @@ -117,7 +117,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml index 583ce720c9a..05a1560000c 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml @@ -115,7 +115,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml index 74a090dc6e8..b219623c2ed 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml @@ -122,7 +122,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/envoyproxy-tls-settings.in.yaml b/internal/gatewayapi/testdata/envoyproxy-tls-settings.in.yaml new file mode 100644 index 00000000000..f46ecc052e2 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-tls-settings.in.yaml @@ -0,0 +1,136 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-tls + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + namespace: envoy-gateway + group: "" + name: default-cert +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-tls + namespace: envoy-gateway + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-tls + rules: + - backendRefs: + - name: https-backend + namespace: default + port: 443 +referenceGrants: + - apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: ReferenceGrant + metadata: + name: refg-route-svc + namespace: default + spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: envoy-gateway + - group: gateway.networking.k8s.io + kind: Gateway + namespace: envoy-gateway + - group: gateway.networking.k8s.io + kind: BackendTLSPolicy + namespace: default + to: + - group: "" + kind: Service +services: + - apiVersion: v1 + kind: Service + metadata: + name: https-backend + namespace: default + spec: + clusterIP: 10.11.12.13 + ports: + - port: 443 + name: https + protocol: TCP + targetPort: 443 + +endpointSlices: + - apiVersion: discovery.k8s.io/v1 + kind: EndpointSlice + metadata: + name: endpointslice-https-backend + namespace: default + labels: + kubernetes.io/service-name: https-backend + addressType: IPv4 + ports: + - name: https + protocol: TCP + port: 443 + endpoints: + - addresses: + - "10.244.0.11" + conditions: + ready: true +backendTLSPolicies: + - apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + name: policy-tls + namespace: default + spec: + targetRef: + group: '' + kind: Service + name: https-backend + tls: + wellKnownCACerts: System + hostname: example.com +envoyproxy: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + backendTLS: + clientCertificateRef: + group: "" + kind: Secret + namespace: default + name: secret.yaml + ciphers: + - ECDHE-RSA-AES128-GCM-SHA256 + - ECDHE-ECDSA-AES256-GCM-SHA384 + ecdhCurves: + - ECDHE-RSA-AES128-GCM-SHA256 + - ECDHE-ECDSA-AES256-GCM-SHA384 + maxVersion: tls1.3 + minVersion: tls1.2 + SignatureAlgorithms: + - RSA-PSS-RSAE-SHA256 + - ECDSA-SECP256R1-SHA256 + alpnProtocols: + - HTTP/1.1 + - HTTP/2 +secrets: + - apiVersion: v1 + kind: Secret + metadata: + name: default-cert + namespace: envoy-gateway + type: kubernetes.io/tls + data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= diff --git a/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml new file mode 100644 index 00000000000..36ecc443361 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-tls-settings.out.yaml @@ -0,0 +1,204 @@ +backendTLSPolicies: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + creationTimestamp: null + name: policy-tls + namespace: default + spec: + targetRef: + group: "" + kind: Service + name: https-backend + tls: + hostname: example.com + wellKnownCACerts: System + status: + ancestors: + - ancestorRef: + name: gateway-tls + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-tls + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: "" + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - group: "" + kind: Secret + name: default-cert + namespace: envoy-gateway + mode: Terminate + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: "" + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-tls + namespace: envoy-gateway + spec: + parentRefs: + - name: gateway-tls + namespace: envoy-gateway + rules: + - backendRefs: + - name: https-backend + namespace: default + port: 443 + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-tls + namespace: envoy-gateway +infraIR: + envoy-gateway/gateway-tls: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway-system + spec: + backendTLS: + alpnProtocols: + - HTTP/1.1 + - HTTP/2 + ciphers: + - ECDHE-RSA-AES128-GCM-SHA256 + - ECDHE-ECDSA-AES256-GCM-SHA384 + clientCertificateRef: + group: "" + kind: Secret + name: secret.yaml + namespace: default + ecdhCurves: + - ECDHE-RSA-AES128-GCM-SHA256 + - ECDHE-ECDSA-AES256-GCM-SHA384 + maxVersion: tls1.3 + minVersion: tls1.2 + signatureAlgorithms: + - RSA-PSS-RSAE-SHA256 + - ECDSA-SECP256R1-SHA256 + logging: {} + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-tls/ + ports: + - containerPort: 10443 + name: https-443 + protocol: HTTPS + servicePort: 443 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-tls + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-tls +xdsIR: + envoy-gateway/gateway-tls: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-tls/ + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10443 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/envoy-gateway/httproute-tls/rule/0 + settings: + - addressType: IP + endpoints: + - host: 10.244.0.11 + port: 443 + protocol: HTTP + tls: + alpnProtocols: + - HTTP/1.1 + - HTTP/2 + ciphers: + - ECDHE-RSA-AES128-GCM-SHA256 + - ECDHE-ECDSA-AES256-GCM-SHA384 + ecdhCurves: + - ECDHE-RSA-AES128-GCM-SHA256 + - ECDHE-ECDSA-AES256-GCM-SHA384 + maxVersion: tls1.3 + minVersion: tls1.2 + signatureAlgorithms: + - RSA-PSS-RSAE-SHA256 + - ECDSA-SECP256R1-SHA256 + sni: example.com + useSystemTrustStore: true + weight: 1 + hostname: '*' + isHTTP2: false + name: httproute/envoy-gateway/httproute-tls/rule/0/match/-1/* + tls: + certificates: + - name: envoy-gateway/default-cert + privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV1Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktRd2dnU2dBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dmbWszUW8xbnRBVTMzamprUQpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZjk2Zy9QWXh2YVp5NEJuMU5ySkJkOExaT2djYlpjMmdueDZJa3YvVVhaME5obHgKRVlpS2plRmpWNkhXNW9FWHJaKy9tUGY0ZHVzVmFMNzRVOVZvanVQSmNlQWVScmpMM2VPaGJIdGN4KzBnY0dMZwpYeEY5VFJhcDY1VHVVZDFhaTA0aEd3WWY3NXNiUDdSS2JQaXZ3WmdVQWUwQ3BWdWZjaG5YcXJzWXI4cEpZNTFPCldWa1NxejRSWTlXbTBrNUcxSkZ5SXlFQzl1bURsdWpjSE50UlZtYWZrTmZBdENsaVByRktjL245bkpmTzZSRlAKN2c3Vi9JdnFudUlyN1BFM0duNlBhVCtCZ2c0NDh0ZDVKelBwVEE1WkJjQm8yb3J6L2t4WVBGcHIvZ1BVQnFRZApvNm5XcXc3Nlp4d1BsZHdMaEorWFlOWDdvdWN0VVNDTDl1NzdmeUVDZ1lFQXl2N0RseGYrS1FsZkR3bW8vcjFUCjBMMVpuSDQ3MmhpSWVkU2hleVZCSGJFVlRTbXI0MkJSbGpXNERiUmNRTTRWY3h4RGtHclI3NlJHZTlvZzZtemMKUnY4K1ZsQ1gyK3F5OXA1bTZaWHJiQXczMHpDLzVtUGtSV3ViaFVoaSs5ZUNNWmEvaEFJL1JGdjI2OURyQkQyLwo2a2cwRjhYME8vNndJK1dwYXRLM1cwY0NnWUVBd1U5QTZiSnBmYVhLS1hQR21PRy9uVXhUeXp5cVlqS05aSmQvCjlHaEVudUdqSzVDQUVWUEphOGtadmZRemxXbXdaYWZxMERocUk4dkxhRkNEZjhZOEU5OU1hbjNHV2hVYjNWL0oKcU5RUVMzNTZOQ2ZadzdseG9LS0JJdlQ2Y3dpaFRuc0UvUjRIQ3NhbDJ3d040Wmw5SFdOQmdhbVM3VExrejFMaApmd1JEa0wwQ2dZQlo0OWorNW53QTlncG5JVkw1Z3lORGN5WGtlNjNMVlVQU0YwdHV1YitOQTJhNFpiU2RHb0RtCmNHRlJpRVcxMk14OHpjNUpmRlA4dDVVU3NUUVVPeUtNT2VrRDFlcDVVd1B1MjVRYzZldDNUQzNJVW5VWDg3SVkKMzU3ZHRZRkhubFlqMldwemJYOVFxUnk5cmlUMEd0Z0tTZkR2ZWhRK0lQa2szRVZhYlhjT2J3S0JnR0d4QzcwTwp6UUVTcC9nSzZuS1lvNTE2MVY0QWFwcjFzVDhFMFVWUzdGcmU3UGMzTDRHU05saWlhTC8yaVpzWXJteXhUNW1xCjZQanVKUDJ5c3NJQURKeCtYTC8wa0NrMlFiNitpY3NvWUpQR2R6dWthQWpoenVxL05VUFZTanlZUCt6SmZ0dnMKTU9MaFFUQlNCekhidjc3NlNrQ2MwZ1BObEpTeDdnT2l4QUtCQW9HQUpCR1VuM2U1QWZDb21BMUUxRHhSeUxaagpUMFBrQUNlUGpEK3hrRkpod0RoQ2dzd2htNFVKZzFmQW8xaEJRUkZ0dHBWQy91QkxjazE4TUVBSTF2ZGZTeVB2CmtTZzVrVnFQanUzc2czOVRNZ09WZXdqUDNFM0FNUUd1ZzFQNzFZazJ6WUpQbGg5NWRMVTVISlZubzZvdkIrUG0KTHF5K016eDN3a0YwZDhlUFhRND0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVU3JTYktMZjBiTEVHb2dXeC9nQ3cyR0N0dnhFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0V6RVJNQThHQTFVRUF3d0lWR1Z6ZENCSmJtTXdIaGNOTWpRd01qSTVNRGt6TURFd1doY05NelF3TWpJMgpNRGt6TURFd1dqQVRNUkV3RHdZRFZRUUREQWhVWlhOMElFbHVZekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBSzFKempQSWlXZzNxb0hTckFkZGtlSmphTVA5aXlNVGkvQlBvOWNKUG9SRThaaTcKV2FwVXJYTC85QTlyK2pITXlHSVpOWk5kY1o1Y1kyWHYwTFA4WnhWeTJsazArM3d0WXpIbnBHWUdWdHlxMnRldApEaEZzaVBsODJZUmpDMG16V2E0UU16NFNYekZITmdJRHBSZGhmcm92bXNldVdHUUU4cFY0VWQ5VUsvU0tpbE1PCnF0QjVKaXJMUDJWczVUMW9XaWNXTFF2ZmJHd3Y3c0ZEZHI5YkcwWHRTUXAxN0hTZ281MFNERTUrQmpTbXB0RncKMVZjS0xscWFoTVhCRERpb3Jnd2hJaEdHS3BFU2VNMFA3YkZoVm1rTTNhc2gyeFNUQnVGVUJEbEU0Sk9haHp3cwpEWHJ1cFVoRGRTMWhkYzJmUHJqaEZBbEpmV0VZWjZCbFpqeXNpVlVDQXdFQUFhTndNRzR3SFFZRFZSME9CQllFCkZCUXVmSzFMaWJ1Vm05VHMvVmpCeDhMM3VpTmVNQjhHQTFVZEl3UVlNQmFBRkJRdWZLMUxpYnVWbTlUcy9WakIKeDhMM3VpTmVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdHd1lEVlIwUkJCUXdFb0lCS29JTktpNWxlR0Z0Y0d4bApMbU52YlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWZQUzQxYWdldldNVjNaWHQwQ09GRzN1WWZQRlhuVnc2ClA0MXA5TzZHa2RZc3VxRnZQZVR5eUgyL2RBSUtLd1N6TS9wdGhnOEtuOExabG1KeUZObkExc3RKeG41WGRiVjEKcFBxajhVdllDQnp5ak1JcW1SeW9peUxpUWxib2hNYTBVZEVCS2NIL1BkTEU5SzhUR0pyWmdvR1hxcTFXbWl0RAozdmNQalNlUEtFaVVKVlM5bENoeVNzMEtZNUIraFVRRDBKajZucEZENFprMHhxZHhoMHJXdWVDcXE3dmpxRVl6CnBqNFB3cnVmbjFQQlRtZnhNdVYvVUpWNWViaWtldVpQMzVrV3pMUjdaV0FMN3d1RGRXcC82bzR5azNRTGFuRFEKQ3dnQ0ZjWCtzcyswVnl1TTNZZXJUT1VVOFFWSkp4NFVaQU5aeDYrNDNwZEpaT2NudFBaNENBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= diff --git a/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml b/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml index b5a1347f4fc..2343d936160 100644 --- a/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml @@ -105,7 +105,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml index b772bd943c9..0607032af8f 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-extension-filter-invalid-group.out.yaml @@ -95,7 +95,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml index 8bab973f1e6..0a691324cda 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-non-matching-extension-filter.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml index 4f318617bed..2f8e19d300e 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-unsupported-extension-filter.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml index b468c423db5..ed697a91ad0 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-valid-extension-filter.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml index 4b5c58da3f1..7ec08cdd2c8 100644 --- a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-allowed-httproute.out.yaml @@ -82,7 +82,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml index 4d0863926db..e04a9abcc61 100644 --- a/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-allows-same-namespace-with-disallowed-httproute.out.yaml @@ -82,7 +82,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml b/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml index 2eac73861c6..2cca7a21513 100644 --- a/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml +++ b/internal/gatewayapi/testdata/gateway-infrastructure.out.yaml @@ -95,7 +95,7 @@ infraIR: name: default/gateway-1/https ports: - containerPort: 10443 - name: https + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml b/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml index 7424d6332bf..1001026c2be 100644 --- a/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-addresses-with-ipaddress.out.yaml @@ -52,7 +52,7 @@ infraIR: name: envoy-gateway/gateway-1/tcp ports: - containerPort: 10080 - name: tcp + name: tcp-80 protocol: TCP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml index 9ad4d5f2eb1..00a01a90dfe 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-mismatch-port-protocol.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/tcp ports: - containerPort: 10162 - name: tcp + name: tcp-162 protocol: TCP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml index d68f758d473..d87a590cc69 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-backends.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/tcp ports: - containerPort: 10080 - name: tcp + name: tcp-80 protocol: TCP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml index 73accd49f5b..0298d8e8bc7 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tcproute-with-multiple-rules.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/tcp ports: - containerPort: 10080 - name: tcp + name: tcp-80 protocol: TCP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml index b1f4d6530d0..a501e2a7ccd 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-secret-in-other-namespace-allowed-by-refgrant.out.yaml @@ -89,7 +89,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10443 - name: tls + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml index 88856e37f64..bb6c6d082bb 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-terminate-and-passthrough.out.yaml @@ -119,14 +119,14 @@ infraIR: name: envoy-gateway/gateway-1/tls-passthrough ports: - containerPort: 10090 - name: tls-passthrough + name: tls-90 protocol: TLS servicePort: 90 - address: null name: envoy-gateway/gateway-1/tls-terminate ports: - containerPort: 10443 - name: tls-terminate + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml index 86546252947..ddbf1400ee6 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/udp ports: - containerPort: 10162 - name: udp + name: udp-162 protocol: UDP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml index bed2cc4aa37..69ece808c6b 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/udp ports: - containerPort: 10080 - name: udp + name: udp-80 protocol: UDP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml index 51b01238520..56d9c366b02 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/udp ports: - containerPort: 10080 - name: udp + name: udp-80 protocol: UDP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml index 74e11eb415a..dd31bd501ea 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-tcproute.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/tcp ports: - containerPort: 10080 - name: tcp + name: tcp-80 protocol: TCP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml index cee2e52e84e..27d949d622e 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/udp ports: - containerPort: 10080 - name: udp + name: udp-80 protocol: UDP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml index 6d6ac8724c6..e197d01d60b 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration-with-same-algorithm-different-fqdn.out.yaml @@ -91,7 +91,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10443 - name: tls + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml index a4499bc066e..e9534d5bd7b 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-multiple-tls-configuration.out.yaml @@ -91,7 +91,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10443 - name: tls + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml index 9380a03ce6c..cdc613c4a9a 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-valid-tls-configuration.out.yaml @@ -88,7 +88,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10443 - name: tls + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml index d2dce6e0af7..aefd53705de 100644 --- a/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml @@ -82,7 +82,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml index f332997f2c5..0bd36bdaac1 100644 --- a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-tcproutes.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/tcp ports: - containerPort: 10162 - name: tcp + name: tcp-162 protocol: TCP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml index 708916becce..22e840d232a 100644 --- a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml @@ -45,7 +45,7 @@ infraIR: name: envoy-gateway/gateway-1/udp ports: - containerPort: 10162 - name: udp + name: udp-162 protocol: UDP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml index 05ae433a1a5..acb517c5b82 100644 --- a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml @@ -88,7 +88,7 @@ infraIR: name: default/gateway-1/https ports: - containerPort: 10443 - name: https + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml index 532e03227db..0e65142eb85 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-tcp-or-tls-port.out.yaml @@ -74,7 +74,7 @@ infraIR: name: envoy-gateway/gateway-1/tcp1 ports: - containerPort: 10162 - name: tcp1 + name: tcp-162 protocol: TCP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml index 64b52d04f8e..68f755e99ab 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml @@ -72,7 +72,7 @@ infraIR: name: envoy-gateway/gateway-1/udp1 ports: - containerPort: 10162 - name: udp1 + name: udp-162 protocol: UDP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml index 267296982ad..e43457681d5 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-multiple-httproutes.out.yaml @@ -147,14 +147,14 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 10081 - name: http-2 + name: http-81 protocol: HTTP servicePort: 81 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml index 61119e9b76a..0233225bb98 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-tcp-protocol.out.yaml @@ -110,14 +110,14 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/tcp ports: - containerPort: 10080 - name: tcp + name: tcp-80 protocol: TCP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml index fb19c1102f6..7ac4c4e14b3 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml @@ -110,14 +110,14 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/udp ports: - containerPort: 10080 - name: udp + name: udp-80 protocol: UDP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml index 246d53aa32f..bf49b0dafaa 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-with-sectionname.out.yaml @@ -72,14 +72,14 @@ infraIR: name: envoy-gateway/gateway-1/tcp1 ports: - containerPort: 10162 - name: tcp1 + name: tcp-162 protocol: TCP servicePort: 162 - address: null name: envoy-gateway/gateway-1/tcp2 ports: - containerPort: 10163 - name: tcp2 + name: tcp-163 protocol: TCP servicePort: 163 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml index 1ee22061b3d..733f4e76b16 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-tcproutes-without-sectionname.out.yaml @@ -72,14 +72,14 @@ infraIR: name: envoy-gateway/gateway-1/tcp1 ports: - containerPort: 10161 - name: tcp1 + name: tcp-161 protocol: TCP servicePort: 161 - address: null name: envoy-gateway/gateway-1/tcp2 ports: - containerPort: 10162 - name: tcp2 + name: tcp-162 protocol: TCP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml index b9a54af4594..418f7a0ad4e 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml @@ -72,14 +72,14 @@ infraIR: name: envoy-gateway/gateway-1/udp1 ports: - containerPort: 10162 - name: udp1 + name: udp-162 protocol: UDP servicePort: 162 - address: null name: envoy-gateway/gateway-1/udp2 ports: - containerPort: 10163 - name: udp2 + name: udp-163 protocol: UDP servicePort: 163 metadata: diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml index 12fe93bd326..17b9d4e2253 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml @@ -72,14 +72,14 @@ infraIR: name: envoy-gateway/gateway-1/udp1 ports: - containerPort: 10161 - name: udp1 + name: udp-161 protocol: UDP servicePort: 161 - address: null name: envoy-gateway/gateway-1/udp2 ports: - containerPort: 10162 - name: udp2 + name: udp-162 protocol: UDP servicePort: 162 metadata: diff --git a/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml index 57d5ad03bf5..23d899faad6 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-empty-backends.out.yaml @@ -82,7 +82,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml index d2abc957458..2c5ecc13bf0 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-header-match.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml index 45acfd7e614..eb7ce849a96 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-method-and-service-match.out.yaml @@ -90,7 +90,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml index 67ed17a35f4..82a2584d195 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-method-match.out.yaml @@ -88,7 +88,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml index 76f8148dce5..ad5e96b684b 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml @@ -87,7 +87,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml index ca598b9d046..aa2ef46b259 100644 --- a/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml +++ b/internal/gatewayapi/testdata/grpcroute-with-service-match.out.yaml @@ -88,7 +88,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml index 001de5ea84e..88becd8a82a 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout-error.out.yaml @@ -121,7 +121,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml index 5ca518d493d..6ece1834d62 100644 --- a/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-and-backendtrafficpolicy-with-timeout.out.yaml @@ -227,7 +227,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -242,7 +242,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml index 9d0c0d570c9..197503b51c5 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-different-listeners.out.yaml @@ -293,56 +293,56 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10081 - name: http-1 + name: http-81 protocol: HTTP servicePort: 81 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 10082 - name: http-2 + name: http-82 protocol: HTTP servicePort: 82 - address: null name: envoy-gateway/gateway-1/http-3 ports: - containerPort: 10083 - name: http-3 + name: http-83 protocol: HTTP servicePort: 83 - address: null name: envoy-gateway/gateway-1/http-4 ports: - containerPort: 10084 - name: http-4 + name: http-84 protocol: HTTP servicePort: 84 - address: null name: envoy-gateway/gateway-1/http-5 ports: - containerPort: 10085 - name: http-5 + name: http-85 protocol: HTTP servicePort: 85 - address: null name: envoy-gateway/gateway-1/http-6 ports: - containerPort: 10086 - name: http-6 + name: http-86 protocol: HTTP servicePort: 86 - address: null name: envoy-gateway/gateway-1/http-7 ports: - containerPort: 10087 - name: http-7 + name: http-87 protocol: HTTP servicePort: 87 - address: null name: envoy-gateway/gateway-1/http-8 ports: - containerPort: 10088 - name: http-8 + name: http-88 protocol: HTTP servicePort: 88 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml index 90041233336..1c238cdf039 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-more-listeners.out.yaml @@ -293,7 +293,7 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml index 2fd05635ddf..e16ff66b0ea 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners-with-different-ports.out.yaml @@ -117,14 +117,14 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/tls ports: - containerPort: 10443 - name: tls + name: https-443 protocol: HTTPS servicePort: 443 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml index cda246ecc6c..1d39beaf5e7 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway-with-two-listeners.out.yaml @@ -113,7 +113,7 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml index 39834ebc86e..352a6da41a5 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-gateway.out.yaml @@ -82,7 +82,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml index 813d9250277..6ddbd88af2a 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-matching-port.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml index bbc2f85502a..3e2ef78a015 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-on-gateway-with-two-listeners.out.yaml @@ -115,7 +115,7 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml index 967713517a0..e2a3401c217 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-diff-address-type.out.yaml @@ -90,7 +90,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml index 2a60e150ec6..a1e080d6482 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-multiple-serviceimport-backendrefs-same-address-type.out.yaml @@ -90,7 +90,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml index 369959e0c7d..134162f6b5c 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-fqdn-address-type.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml index cd98ee93cc8..8a3c4a0587a 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref-mixed-address-type.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml index 8ffa5793822..c1bb62b6797 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-serviceimport-backendref.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml index 55c1ac1b83d..0d0d1755ef4 100644 --- a/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml +++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener.out.yaml @@ -84,7 +84,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml index e448a02bf2d..f56835ccb2e 100644 --- a/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-backend-request-timeout.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml b/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml index 783b3be7b30..e7474693b36 100644 --- a/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-not-attaching-to-listener-non-matching-port.out.yaml @@ -85,7 +85,7 @@ infraIR: name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 - name: http-1 + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml index ec80e30e1e8..3d3f73076ee 100644 --- a/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml +++ b/internal/gatewayapi/testdata/httproute-request-timeout.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml index d49bb265d46..6a99fbe90e3 100644 --- a/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-rule-with-empty-backends-and-no-filters.out.yaml @@ -79,7 +79,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml index 048b705766e..8a8b799c552 100644 --- a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml +++ b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-no-weights.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml index 53038b2348b..b962d108c8b 100644 --- a/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml +++ b/internal/gatewayapi/testdata/httproute-rule-with-multiple-backends-and-weights.out.yaml @@ -92,7 +92,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml index b827af53150..a170bf0e21f 100644 --- a/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml @@ -84,7 +84,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml index 485d59bcde1..2501f9d8c20 100644 --- a/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-backendref-serviceimport-in-other-namespace-allowed-by-refgrant.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml b/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml index 5ef60eccf6a..d345186e64c 100644 --- a/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-empty-matches.out.yaml @@ -81,7 +81,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml index 9d439afa3c6..d1b3c41b858 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml @@ -102,7 +102,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml index 7d69c437116..ec57fd25d09 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml @@ -112,7 +112,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml index f8a325b46ee..c290d1a96c5 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-remove-multiple-filters.out.yaml @@ -98,7 +98,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml index 53c939f2b0d..d6d97d8e7d4 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-removes.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml index b5193139bbe..c74c9294dab 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml @@ -96,7 +96,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml index c95a7df7e41..5065aa523df 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml @@ -98,7 +98,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml index 949dce73540..93f152ffea8 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml @@ -99,7 +99,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml index c3ab6b9f021..d06a9820f7a 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-no-headers.out.yaml @@ -90,7 +90,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml index 6102adbb08e..3329848de05 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml index 3ac50c40bac..f0e08c90108 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-remove.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml index 9c3bab389cf..d976cb93f38 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-bad-port.out.yaml @@ -83,7 +83,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml index 5f78538385f..fe064903ada 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-group.out.yaml @@ -87,7 +87,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml index b38425e7563..bee00784ac7 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-kind.out.yaml @@ -84,7 +84,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml index 6668252cdbc..417f53c7dfb 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-port.out.yaml @@ -83,7 +83,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml index da0bce317d6..a6c22425e84 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.import.out.yaml @@ -85,7 +85,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml index ddaccd43a10..2bf53591ed3 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-no-service.out.yaml @@ -83,7 +83,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml index f916d303053..26c803f9d91 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-unsupported-filter.out.yaml @@ -89,7 +89,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml index 8d622b36680..cc0cc881a87 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-backendref-in-other-namespace.out.yaml @@ -84,7 +84,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml index 8e676db62f1..a8e06b4fa54 100644 --- a/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-invalid-regex.out.yaml @@ -119,7 +119,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -134,7 +134,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10081 - name: http + name: http-81 protocol: HTTP servicePort: 81 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml index 431a85a1dca..8ed5fe11eff 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-duplicates.out.yaml @@ -100,7 +100,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml index 8588726a36e..425bebf34b3 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml @@ -112,7 +112,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml index a5b71817a08..60b599dcdd7 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-no-port.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml index a9fb238b04f..724d00e1ecc 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-service-not-found.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml index d324d246514..d98e16bd4d3 100644 --- a/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml index 293b36390b1..ebe71a52556 100644 --- a/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-non-matching-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml index 95a7cbdc1d4..c1f9030ef3c 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-full-path-replace-https.out.yaml @@ -92,7 +92,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml index 77254975bde..0cc17703e29 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-hostname.out.yaml @@ -90,7 +90,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml index 2491b007b73..a7a57501a4e 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml index 96974409276..c408f51ffb5 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml @@ -90,7 +90,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml index e330972e2a8..99c291b14ae 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml @@ -89,7 +89,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml index 961afbb26f1..bb9d2644130 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-prefix-replace-with-port-http.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml index 43c7a116b4b..b3625b41e1a 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml @@ -108,7 +108,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml index 4fba4eb7b99..05f34deb133 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml @@ -102,7 +102,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml index 61441d6a1d6..6c95d3dbc5f 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml @@ -112,7 +112,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml index 4f58c01222d..3183508ec02 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-remove-multiple-filters.out.yaml @@ -98,7 +98,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml index 0cd94a754a4..e20ab6f52fc 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-removes.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml index b7f3e26ef42..4de5380a305 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml @@ -96,7 +96,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml index 50fe9f29aed..c0a449536bd 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-headers.out.yaml @@ -98,7 +98,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml index bb974df71b8..14f957bb880 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml @@ -99,7 +99,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml index 48c3b5f8f5b..41667e93380 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-headers.out.yaml @@ -90,7 +90,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml index e3c8a6dbec0..2ee89577ab9 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-no-valid-headers.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml index 1ea53e4797d..4e06010a1a2 100644 --- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-remove.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml index 0b9bc1037ec..9f7d91d4ec7 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-exact-path-match.out.yaml @@ -83,7 +83,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml index 291e21eebcc..55059d9d6ee 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-http-method-match.out.yaml @@ -81,7 +81,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml index 6cdc1ed6c56..7cae3475b67 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-multiple-rules.out.yaml @@ -109,7 +109,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml b/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml index b16e4cfe932..f48725ca3ce 100644 --- a/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-single-rule-with-path-prefix-and-exact-header-matches.out.yaml @@ -87,7 +87,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml b/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml index ad7e977d4a8..da444284df0 100644 --- a/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-some-invalid-backend-refs-no-service.out.yaml @@ -87,7 +87,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml index 2beec1c17f5..f2aab324c92 100644 --- a/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-specific-hostname-attaching-to-gateway-with-wildcard-hostname.out.yaml @@ -85,7 +85,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml index a2a913ec417..f07df0591d4 100644 --- a/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-two-specific-hostnames-attaching-to-gateway-with-wildcard-hostname.out.yaml @@ -86,7 +86,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml index 8b2138f2100..e2cbea3dd90 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-full-path-replace-http.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml index 9ea570c292b..2b59d98a5b1 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname-prefix-replace.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml index bf682e88b35..6a2571e0e26 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-hostname.out.yaml @@ -91,7 +91,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml index b85ff6e2db3..79131ac54f1 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml @@ -91,7 +91,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml index 448b7518fc0..21596a52d42 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-hostname.out.yaml @@ -97,7 +97,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml index cac49f264af..7f25b160719 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-multiple-filters.out.yaml @@ -99,7 +99,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml index a8e83b7761e..6429820c1a3 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path-type.out.yaml @@ -95,7 +95,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml index 9633fa077b5..0cf9358e1ac 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-path.out.yaml @@ -94,7 +94,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml index 7ff23ecae5d..8d3cb231dd9 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-missing-path.out.yaml @@ -92,7 +92,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml index bc23aabd4d7..44067c28c56 100644 --- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-prefix-replace-http.out.yaml @@ -93,7 +93,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml b/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml index 8d436c384cb..0353ec71963 100644 --- a/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-wildcard-hostname-attaching-to-gateway-with-unset-hostname.out.yaml @@ -84,7 +84,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml b/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml index 325c79da51d..58921ad7474 100644 --- a/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml +++ b/internal/gatewayapi/testdata/httproutes-with-multiple-matches.out.yaml @@ -269,7 +269,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml b/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml index 8e65705fc44..c37bd4038e5 100644 --- a/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml +++ b/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml @@ -116,14 +116,14 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: envoy-gateway/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-2/udp ports: - containerPort: 10080 - name: envoy-gateway/gateway-2/udp + name: udp-80 protocol: UDP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-listeners-same-ports.out.yaml b/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-listeners-same-ports.out.yaml index 94ab094ec2e..085d78dd41c 100755 --- a/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-listeners-same-ports.out.yaml +++ b/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-listeners-same-ports.out.yaml @@ -152,14 +152,14 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: envoy-gateway/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-1/http-2 ports: - containerPort: 8888 - name: envoy-gateway/gateway-1/http-2 + name: http-8888 protocol: HTTP servicePort: 8888 metadata: diff --git a/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml b/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml index 073d47f8cfc..e02cf0852f4 100644 --- a/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/merge-valid-multiple-gateways-multiple-routes.out.yaml @@ -203,14 +203,14 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: envoy-gateway/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-2/http-2 ports: - containerPort: 8888 - name: envoy-gateway/gateway-2/http-2 + name: http-8888 protocol: HTTP servicePort: 8888 metadata: diff --git a/internal/gatewayapi/testdata/merge-valid-multiple-gateways.out.yaml b/internal/gatewayapi/testdata/merge-valid-multiple-gateways.out.yaml index 1346f408115..e91403b3cf4 100644 --- a/internal/gatewayapi/testdata/merge-valid-multiple-gateways.out.yaml +++ b/internal/gatewayapi/testdata/merge-valid-multiple-gateways.out.yaml @@ -125,14 +125,14 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: envoy-gateway/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-2/http-2 ports: - containerPort: 8888 - name: envoy-gateway/gateway-2/http-2 + name: http-8888 protocol: HTTP servicePort: 8888 metadata: diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml index 15e35504f91..f8797d895ca 100755 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml @@ -406,14 +406,14 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: default/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: default/gateway-2/http ports: - containerPort: 10081 - name: default/gateway-2/http + name: http-81 protocol: HTTP servicePort: 81 metadata: @@ -519,21 +519,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -550,6 +535,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s tcpKeepalive: idleTime: 1200 interval: 60 @@ -570,21 +571,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-2/rule/0 settings: @@ -601,6 +587,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s tcpKeepalive: idleTime: 1200 interval: 60 @@ -621,21 +623,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-3/rule/0 settings: @@ -652,6 +639,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s - address: 0.0.0.0 hostnames: - foo.example.com diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml index 2da58361ab6..8eb08db7bfd 100644 --- a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml +++ b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml @@ -236,14 +236,14 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: default/gateway-1/http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: default/gateway-2/http-2 ports: - containerPort: 8888 - name: default/gateway-2/http-2 + name: http-8888 protocol: HTTP servicePort: 8888 metadata: @@ -309,21 +309,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -340,6 +325,22 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s tcpKeepalive: idleTime: 1200 interval: 60 diff --git a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml index 3bb9ae1338d..fd0c493464e 100755 --- a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml @@ -47,7 +47,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml index 1224320c631..f7c7b74db9c 100755 --- a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml @@ -124,7 +124,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -251,24 +251,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: https://.*\.test\.com:8080 - - distinct: false - exact: https://www.test.org:8080 - name: "" - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -285,30 +267,28 @@ xdsIR: distinct: false name: "" prefix: /foo + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: https://.*\.test\.com:8080 + - distinct: false + exact: https://www.test.org:8080 + name: "" + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-1 - - x-header-2 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: http://.*\.example\.com - - distinct: false - exact: http://foo.bar.com - name: "" - - distinct: false - name: "" - safeRegex: https://.* - exposeHeaders: - - x-header-3 - - x-header-4 - maxAge: 16m40s destination: name: httproute/default/httproute-2/rule/0 settings: @@ -320,19 +300,41 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /bar + security: + cors: + allowHeaders: + - x-header-1 + - x-header-2 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: http://.*\.example\.com + - distinct: false + exact: http://foo.bar.com + name: "" + - distinct: false + name: "" + safeRegex: https://.* + exposeHeaders: + - x-header-3 + - x-header-4 + maxAge: 16m40s + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml index 853da756488..026f00b4317 100755 --- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml @@ -210,7 +210,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -225,14 +225,14 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 - address: null name: envoy-gateway/gateway-2/tcp ports: - containerPort: 10053 - name: tcp + name: tcp-53 protocol: TCP servicePort: 53 metadata: @@ -435,6 +435,7 @@ xdsIR: distinct: false name: "" prefix: / + security: {} envoy-gateway/gateway-2: accessLog: text: @@ -462,3 +463,4 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/envoy-gateway/grpcroute-1/rule/0/match/0/* + security: {} diff --git a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml index 3681d60e018..cc05125f7ee 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-basic-auth.out.yaml @@ -130,7 +130,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -227,9 +227,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= destination: name: httproute/default/httproute-1/rule/0 settings: @@ -246,12 +243,13 @@ xdsIR: distinct: false name: "" prefix: /foo1 + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - backendWeights: invalid: 0 valid: 0 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= destination: name: httproute/default/httproute-1/rule/1 settings: @@ -268,12 +266,13 @@ xdsIR: distinct: false name: "" prefix: /foo2 + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - backendWeights: invalid: 0 valid: 0 - basicAuth: - name: securitypolicy/default/policy-for-gateway-1 - users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= destination: name: httproute/default/httproute-2/rule/0 settings: @@ -290,3 +289,7 @@ xdsIR: distinct: false name: "" prefix: /bar + security: + basicAuth: + name: securitypolicy/default/policy-for-gateway-1 + users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= diff --git a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml index 943ea81307a..1d11e3a4cda 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml @@ -238,7 +238,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -253,7 +253,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -268,7 +268,7 @@ infraIR: name: envoy-gateway/gateway-3/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -418,27 +418,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-1 - - x-header-2 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: http://.*\.example\.com - - distinct: false - exact: http://foo.bar.com - name: "" - - distinct: false - name: "" - safeRegex: https://.* - exposeHeaders: - - x-header-3 - - x-header-4 - maxAge: 16m40s destination: name: grpcroute/default/grpcroute-1/rule/0 settings: @@ -451,6 +430,28 @@ xdsIR: hostname: '*' isHTTP2: true name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + security: + cors: + allowHeaders: + - x-header-1 + - x-header-2 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: http://.*\.example\.com + - distinct: false + exact: http://foo.bar.com + name: "" + - distinct: false + name: "" + safeRegex: https://.* + exposeHeaders: + - x-header-3 + - x-header-4 + maxAge: 16m40s envoy-gateway/gateway-2: accessLog: text: @@ -469,24 +470,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: https://.*\.test\.com:8080 - - distinct: false - exact: https://www.test.org:8080 - name: "" - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-1/rule/0 settings: @@ -503,6 +486,25 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: https://.*\.test\.com:8080 + - distinct: false + exact: https://www.test.org:8080 + name: "" + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s envoy-gateway/gateway-3: accessLog: text: @@ -521,21 +523,6 @@ xdsIR: - backendWeights: invalid: 0 valid: 0 - cors: - allowHeaders: - - x-header-5 - - x-header-6 - allowMethods: - - GET - - POST - allowOrigins: - - distinct: false - name: "" - safeRegex: .* - exposeHeaders: - - x-header-7 - - x-header-8 - maxAge: 33m20s destination: name: httproute/default/httproute-2/rule/0 settings: @@ -552,3 +539,19 @@ xdsIR: distinct: false name: "" prefix: / + security: + cors: + allowHeaders: + - x-header-5 + - x-header-6 + allowMethods: + - GET + - POST + allowOrigins: + - distinct: false + name: "" + safeRegex: .* + exposeHeaders: + - x-header-7 + - x-header-8 + maxAge: 33m20s diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml index 20a44008251..d23b2a7d8f7 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-matching-port.out.yaml @@ -86,7 +86,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -166,3 +166,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml index 4ade06fec09..fb8d90097a0 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-port.out.yaml @@ -86,7 +86,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -166,3 +166,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml index 82fc12d534c..5d31bd10a9b 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-reference-grant.out.yaml @@ -86,7 +86,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -167,3 +167,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml index 980d29cce01..da185ff74a0 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-invalid-no-service.out.yaml @@ -86,7 +86,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -166,3 +166,4 @@ xdsIR: distinct: false name: "" prefix: /foo + security: {} diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml index e964b48155c..a30a343eaee 100755 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.out.yaml @@ -190,7 +190,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -306,28 +306,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: true - grpc: - authority: grpc-backend.default:9000 - destination: - name: securitypolicy/default/policy-for-http-route/default/grpc-backend - settings: - - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - protocol: GRPC - tls: - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/default-ca - sni: grpc-backend - weight: 1 - headersToExtAuth: - - header1 - - header2 - name: securitypolicy/default/policy-for-http-route hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_foo_com @@ -335,6 +313,29 @@ xdsIR: distinct: false name: "" prefix: /foo + security: + extAuth: + failOpen: true + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/default-ca + sni: grpc-backend + weight: 1 + headersToExtAuth: + - header1 + - header2 + name: securitypolicy/default/policy-for-http-route - backendWeights: invalid: 0 valid: 0 @@ -347,29 +348,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: false - http: - authority: http-backend.envoy-gateway:80 - destination: - name: securitypolicy/default/policy-for-gateway/envoy-gateway/http-backend - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - tls: - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-http/default-ca - sni: http-backend - weight: 1 - headersToBackend: - - header1 - - header2 - path: /auth - name: securitypolicy/default/policy-for-gateway hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com @@ -377,3 +355,27 @@ xdsIR: distinct: false name: "" prefix: /bar + security: + extAuth: + failOpen: false + http: + authority: http-backend.envoy-gateway:80 + destination: + name: securitypolicy/default/policy-for-gateway/envoy-gateway/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-http/default-ca + sni: http-backend + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth + name: securitypolicy/default/policy-for-gateway diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml index f9243d6f420..4628a35cc11 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth.out.yaml @@ -130,7 +130,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -246,23 +246,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: true - grpc: - authority: grpc-backend.default:9000 - destination: - name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend - settings: - - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - protocol: GRPC - weight: 1 - headersToExtAuth: - - header1 - - header2 - name: securitypolicy/default/policy-for-http-route-1 hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_foo_com @@ -270,6 +253,24 @@ xdsIR: distinct: false name: "" prefix: /foo1 + security: + extAuth: + failOpen: true + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + name: securitypolicy/default/policy-for-http-route-1 - backendWeights: invalid: 0 valid: 0 @@ -282,23 +283,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: true - grpc: - authority: grpc-backend.default:9000 - destination: - name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend - settings: - - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - protocol: GRPC - weight: 1 - headersToExtAuth: - - header1 - - header2 - name: securitypolicy/default/policy-for-http-route-1 hostname: www.foo.com isHTTP2: false name: httproute/default/httproute-1/rule/1/match/0/www_foo_com @@ -306,6 +290,24 @@ xdsIR: distinct: false name: "" prefix: /foo2 + security: + extAuth: + failOpen: true + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + name: securitypolicy/default/policy-for-http-route-1 - backendWeights: invalid: 0 valid: 0 @@ -318,24 +320,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - extAuth: - failOpen: false - http: - authority: http-backend.envoy-gateway:80 - destination: - name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - weight: 1 - headersToBackend: - - header1 - - header2 - path: /auth - name: securitypolicy/default/policy-for-gateway-1 hostname: www.bar.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_bar_com @@ -343,3 +327,22 @@ xdsIR: distinct: false name: "" prefix: /bar + security: + extAuth: + failOpen: false + http: + authority: http-backend.envoy-gateway:80 + destination: + name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth + name: securitypolicy/default/policy-for-gateway-1 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml index a8e01e48023..b4e2932f294 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-and-invalid-oidc.out.yaml @@ -124,7 +124,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -260,22 +260,23 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /foo + security: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json - backendWeights: invalid: 0 valid: 0 @@ -290,19 +291,20 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - two.foo.com - claimToHeaders: - - claim: claim2 - header: one-route-example-key - issuer: https://two.example.com - name: example2 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: /bar + security: + jwt: + providers: + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: one-route-example-key + issuer: https://two.example.com + name: example2 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.in.yaml new file mode 100644 index 00000000000..1ae633f805c --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.in.yaml @@ -0,0 +1,127 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-2 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +grpcRoutes: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: GRPCRoute + metadata: + namespace: default + name: grpcroute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-2 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + jwt: + providers: + - name: example1 + issuer: https://one.example.com + audiences: + - one.foo.com + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + claimToHeaders: + - header: one-route-example-key + claim: claim1 + - name: example2 + issuer: https://two.example.com + audiences: + - two.foo.com + remoteJWKS: + uri: https://two.example.com/jwt/public-key/jwks.json + claimToHeaders: + - header: two-route-example-key + claim: claim2 +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + namespace: default + jwt: + providers: + - name: example3 + issuer: https://three.example.com + audiences: + - three.foo.com + remoteJWKS: + uri: https://three.example.com/jwt/public-key/jwks.json + claimToHeaders: + - header: three-route-example-key + claim: claim3 + extractFrom: + headers: + - name: Authorization + valuePrefix: 'Bearer ' + cookies: + - session_access_token + params: + - token + optional: true diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.out.yaml new file mode 100644 index 00000000000..caf5e85171f --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-optional.out.yaml @@ -0,0 +1,386 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +grpcRoutes: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: GRPCRoute + metadata: + creationTimestamp: null + name: grpcroute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-2 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-2 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 + envoy-gateway/gateway-2: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-2/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-2 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-2 +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + creationTimestamp: null + name: policy-for-route + namespace: default + spec: + jwt: + optional: true + providers: + - audiences: + - three.foo.com + claimToHeaders: + - claim: claim3 + header: three-route-example-key + extractFrom: + cookies: + - session_access_token + headers: + - name: Authorization + valuePrefix: 'Bearer ' + params: + - token + issuer: https://three.example.com + name: example3 + remoteJWKS: + uri: https://three.example.com/jwt/public-key/jwks.json + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + namespace: default + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + spec: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: https://two.example.com + name: example2 + remoteJWKS: + uri: https://two.example.com/jwt/public-key/jwks.json + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: true + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: grpcroute/default/grpcroute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: GRPC + weight: 1 + hostname: '*' + isHTTP2: true + name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + security: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: https://two.example.com + name: example2 + remoteJWKS: + uri: https://two.example.com/jwt/public-key/jwks.json + envoy-gateway/gateway-2: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-2/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + security: + jwt: + allowMissing: true + providers: + - audiences: + - three.foo.com + claimToHeaders: + - claim: claim3 + header: three-route-example-key + extractFrom: + cookies: + - session_access_token + headers: + - name: Authorization + valuePrefix: 'Bearer ' + params: + - token + issuer: https://three.example.com + name: example3 + remoteJWKS: + uri: https://three.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml index 2ea03bafc0b..73a2e8e33a0 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-with-custom-extractor.out.yaml @@ -160,7 +160,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -175,7 +175,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -306,27 +306,28 @@ xdsIR: weight: 1 hostname: '*' isHTTP2: true - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json - - audiences: - - two.foo.com - claimToHeaders: - - claim: claim2 - header: two-route-example-key - issuer: https://two.example.com - name: example2 - remoteJWKS: - uri: https://two.example.com/jwt/public-key/jwks.json name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + security: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: https://two.example.com + name: example2 + remoteJWKS: + uri: https://two.example.com/jwt/public-key/jwks.json envoy-gateway/gateway-2: accessLog: text: @@ -356,27 +357,28 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - three.foo.com - claimToHeaders: - - claim: claim3 - header: three-route-example-key - extractFrom: - cookies: - - session_access_token - headers: - - name: Authorization - valuePrefix: 'Bearer ' - params: - - token - issuer: https://three.example.com - name: example3 - remoteJWKS: - uri: https://three.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: / + security: + jwt: + providers: + - audiences: + - three.foo.com + claimToHeaders: + - claim: claim3 + header: three-route-example-key + extractFrom: + cookies: + - session_access_token + headers: + - name: Authorization + valuePrefix: 'Bearer ' + params: + - token + issuer: https://three.example.com + name: example3 + remoteJWKS: + uri: https://three.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml index 6af406789f9..d2bb96f0d8d 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt.out.yaml @@ -160,7 +160,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -175,7 +175,7 @@ infraIR: name: envoy-gateway/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -298,27 +298,28 @@ xdsIR: weight: 1 hostname: '*' isHTTP2: true - jwt: - providers: - - audiences: - - one.foo.com - claimToHeaders: - - claim: claim1 - header: one-route-example-key - issuer: https://one.example.com - name: example1 - remoteJWKS: - uri: https://one.example.com/jwt/public-key/jwks.json - - audiences: - - two.foo.com - claimToHeaders: - - claim: claim2 - header: two-route-example-key - issuer: http://two.example.com - name: example2 - remoteJWKS: - uri: http://two.example.com/jwt/public-key/jwks.json name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + security: + jwt: + providers: + - audiences: + - one.foo.com + claimToHeaders: + - claim: claim1 + header: one-route-example-key + issuer: https://one.example.com + name: example1 + remoteJWKS: + uri: https://one.example.com/jwt/public-key/jwks.json + - audiences: + - two.foo.com + claimToHeaders: + - claim: claim2 + header: two-route-example-key + issuer: http://two.example.com + name: example2 + remoteJWKS: + uri: http://two.example.com/jwt/public-key/jwks.json envoy-gateway/gateway-2: accessLog: text: @@ -348,19 +349,20 @@ xdsIR: weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false - jwt: - providers: - - audiences: - - three.foo.com - claimToHeaders: - - claim: claim3 - header: three-route-example-key - issuer: https://three.example.com - name: example3 - remoteJWKS: - uri: https://three.example.com/jwt/public-key/jwks.json name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io pathMatch: distinct: false name: "" prefix: / + security: + jwt: + providers: + - audiences: + - three.foo.com + claimToHeaders: + - claim: claim3 + header: three-route-example-key + issuer: https://three.example.com + name: example3 + remoteJWKS: + uri: https://three.example.com/jwt/public-key/jwks.json diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-issuer.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-issuer.out.yaml index bc8e64eeeda..d2a6d6afab3 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-issuer.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-issuer.out.yaml @@ -47,7 +47,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml index 34c9a927508..2ea3ac2420d 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml @@ -127,7 +127,7 @@ infraIR: name: default/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -142,7 +142,7 @@ infraIR: name: default/gateway-2/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -157,7 +157,7 @@ infraIR: name: default/gateway-3/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml index b0cff9eac83..2015f492d63 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml @@ -124,7 +124,7 @@ infraIR: name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 - name: http + name: http-80 protocol: HTTP servicePort: 80 metadata: @@ -253,28 +253,29 @@ xdsIR: hostname: www.example.com isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/www_example_com - oidc: - clientID: client2.oauth.foo.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - cookieSuffix: 5f93c2e4 - hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= - logoutPath: /foo/logout - name: securitypolicy/default/policy-for-http-route - provider: - authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth - tokenEndpoint: https://oauth.foo.com/token - redirectPath: /foo/oauth2/callback - redirectURL: https://www.example.com/foo/oauth2/callback - resources: - - api - scopes: - - openid - - email - - profile pathMatch: distinct: false name: "" prefix: /foo + security: + oidc: + clientID: client2.oauth.foo.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + cookieSuffix: 5f93c2e4 + hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= + logoutPath: /foo/logout + name: securitypolicy/default/policy-for-http-route + provider: + authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + tokenEndpoint: https://oauth.foo.com/token + redirectPath: /foo/oauth2/callback + redirectURL: https://www.example.com/foo/oauth2/callback + resources: + - api + scopes: + - openid + - email + - profile - backendWeights: invalid: 0 valid: 0 @@ -290,21 +291,22 @@ xdsIR: hostname: www.example.com isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/www_example_com - oidc: - clientID: client1.apps.googleusercontent.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - cookieSuffix: b0a1b740 - hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= - logoutPath: /bar/logout - name: securitypolicy/envoy-gateway/policy-for-gateway - provider: - authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth - tokenEndpoint: https://oauth2.googleapis.com/token - redirectPath: /bar/oauth2/callback - redirectURL: https://www.example.com/bar/oauth2/callback - scopes: - - openid pathMatch: distinct: false name: "" prefix: /bar + security: + oidc: + clientID: client1.apps.googleusercontent.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + cookieSuffix: b0a1b740 + hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= + logoutPath: /bar/logout + name: securitypolicy/envoy-gateway/policy-for-gateway + provider: + authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth + tokenEndpoint: https://oauth2.googleapis.com/token + redirectPath: /bar/oauth2/callback + redirectURL: https://www.example.com/bar/oauth2/callback + scopes: + - openid diff --git a/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml b/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml index b4ac4a13faa..44fe206db9b 100644 --- a/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml +++ b/internal/gatewayapi/testdata/tcproute-attaching-to-gateway-with-listener-tls-terminate.out.yaml @@ -51,7 +51,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10090 - name: tls + name: tls-90 protocol: TLS servicePort: 90 metadata: diff --git a/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml b/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml index c5156d74c40..7438edad63a 100644 --- a/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-attaching-to-gateway.out.yaml @@ -48,7 +48,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10090 - name: tls + name: tls-90 protocol: TLS servicePort: 90 metadata: diff --git a/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml b/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml index ada467afc07..4b53cc38e3c 100644 --- a/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-multiple.out.yaml @@ -47,7 +47,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10091 - name: tls + name: tls-91 protocol: TLS servicePort: 91 metadata: diff --git a/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml index c4a9bb0ee13..f7839533321 100644 --- a/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-with-backendref-in-other-namespace-allowed-by-refgrant.out.yaml @@ -48,7 +48,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10090 - name: tls + name: tls-90 protocol: TLS servicePort: 90 metadata: diff --git a/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml index 8b6843bf49a..7444d808de3 100644 --- a/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-with-empty-hostname.out.yaml @@ -47,7 +47,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10091 - name: tls + name: tls-91 protocol: TLS servicePort: 91 metadata: diff --git a/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml b/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml index 493fbf296d4..1a45b65bb80 100644 --- a/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml +++ b/internal/gatewayapi/testdata/tlsroute-with-empty-listener-hostname.out.yaml @@ -47,7 +47,7 @@ infraIR: name: envoy-gateway/gateway-1/tls ports: - containerPort: 10091 - name: tls + name: tls-91 protocol: TLS servicePort: 91 metadata: diff --git a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.in.yaml b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.in.yaml new file mode 100644 index 00000000000..0f89e2f86d1 --- /dev/null +++ b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.in.yaml @@ -0,0 +1,88 @@ +envoyproxy: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway + name: test + spec: + mergeGateways: true + telemetry: + tracing: + samplingRate: 100 + provider: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + type: OpenTelemetry +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-2 + port: 8888 + protocol: HTTP + - name: http-3 + hostname: example.com + port: 8888 + protocol: HTTP + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-2 + sectionName: http-3 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-2 + port: 8080 diff --git a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml new file mode 100755 index 00000000000..08e2e85c06e --- /dev/null +++ b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml @@ -0,0 +1,304 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + hostname: '*.envoyproxy.io' + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-2 + port: 8888 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + hostname: example.com + name: http-3 + port: 8888 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-2 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-3 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-2 + namespace: default + spec: + hostnames: + - example.com + parentRefs: + - name: gateway-2 + namespace: envoy-gateway + sectionName: http-3 + rules: + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-2 + namespace: envoy-gateway + sectionName: http-3 +infraIR: + envoy-gateway-class: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway + spec: + logging: {} + mergeGateways: true + telemetry: + tracing: + provider: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + type: OpenTelemetry + samplingRate: 100 + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + - address: null + name: envoy-gateway/gateway-2/http-2 + ports: + - containerPort: 8888 + name: http-8888 + protocol: HTTP + servicePort: 8888 + metadata: + labels: + gateway.envoyproxy.io/owning-gatewayclass: envoy-gateway-class + name: envoy-gateway-class +xdsIR: + envoy-gateway-class: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*.envoyproxy.io' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-2/http-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8888 + - address: 0.0.0.0 + hostnames: + - example.com + isHTTP2: false + name: envoy-gateway/gateway-2/http-3 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8888 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: example.com + isHTTP2: false + name: httproute/default/httproute-2/rule/0/match/0/example_com + pathMatch: + distinct: false + name: "" + prefix: / + tracing: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + samplingRate: 100 + serviceName: envoy-gateway-class diff --git a/internal/gatewayapi/testdata/tracing-multiple-routes.in.yaml b/internal/gatewayapi/testdata/tracing-multiple-routes.in.yaml new file mode 100644 index 00000000000..a647019a9a9 --- /dev/null +++ b/internal/gatewayapi/testdata/tracing-multiple-routes.in.yaml @@ -0,0 +1,87 @@ +envoyproxy: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway + name: test + spec: + telemetry: + tracing: + samplingRate: 100 + provider: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + type: OpenTelemetry +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-2 + port: 8888 + protocol: HTTP + - name: http-3 + hostname: example.com + port: 8888 + protocol: HTTP + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-2 + sectionName: http-3 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-2 + port: 8080 diff --git a/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml new file mode 100755 index 00000000000..fb5c6f89acc --- /dev/null +++ b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml @@ -0,0 +1,339 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + hostname: '*.envoyproxy.io' + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-2 + port: 8888 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + hostname: example.com + name: http-3 + port: 8888 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-2 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-3 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-2 + namespace: default + spec: + hostnames: + - example.com + parentRefs: + - name: gateway-2 + namespace: envoy-gateway + sectionName: http-3 + rules: + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-2 + namespace: envoy-gateway + sectionName: http-3 +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway + spec: + logging: {} + telemetry: + tracing: + provider: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + type: OpenTelemetry + samplingRate: 100 + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 + envoy-gateway/gateway-2: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway + spec: + logging: {} + telemetry: + tracing: + provider: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + type: OpenTelemetry + samplingRate: 100 + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-2/http-2 + ports: + - containerPort: 8888 + name: http-8888 + protocol: HTTP + servicePort: 8888 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-2 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-2 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*.envoyproxy.io' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + tracing: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + samplingRate: 100 + serviceName: gateway-1.envoy-gateway + envoy-gateway/gateway-2: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-2/http-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8888 + - address: 0.0.0.0 + hostnames: + - example.com + isHTTP2: false + name: envoy-gateway/gateway-2/http-3 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8888 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: example.com + isHTTP2: false + name: httproute/default/httproute-2/rule/0/match/0/example_com + pathMatch: + distinct: false + name: "" + prefix: / + tracing: + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + samplingRate: 100 + serviceName: gateway-2.envoy-gateway diff --git a/internal/gatewayapi/tls.go b/internal/gatewayapi/tls.go index f37c53b9526..cc01c4c56c1 100644 --- a/internal/gatewayapi/tls.go +++ b/internal/gatewayapi/tls.go @@ -57,7 +57,6 @@ func validateTLSSecretsData(secrets []*corev1.Secret, host *v1.Hostname) error { if matchedFQDN, ok := pkaSecretSet[pkaSecretKey]; ok { return fmt.Errorf("%s/%s public key algorithm must be unique, matched certificate FQDN %s has a conflicting algorithm [%s]", secret.Namespace, secret.Name, matchedFQDN, publicKeyAlgorithm) - } pkaSecretSet[pkaSecretKey] = matchedFQDN diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 9dc93532479..1827d962d57 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -115,7 +115,8 @@ func newTranslateResult(gateways []*GatewayContext, securityPolicies []*egv1a1.SecurityPolicy, backendTLSPolicies []*egv1a2.BackendTLSPolicy, envoyExtensionPolicies []*egv1a1.EnvoyExtensionPolicy, - xdsIR XdsIRMap, infraIR InfraIRMap) *TranslateResult { + xdsIR XdsIRMap, infraIR InfraIRMap, +) *TranslateResult { translateResult := &TranslateResult{ XdsIR: xdsIR, InfraIR: infraIR, @@ -220,7 +221,6 @@ func (t *Translator) Translate(resources *Resources) *TranslateResult { tcpRoutes, udpRoutes, clientTrafficPolicies, backendTrafficPolicies, securityPolicies, resources.BackendTLSPolicies, envoyExtensionPolicies, xdsIR, infraIR) - } // GetRelevantGateways returns GatewayContexts, containing a copy of the original diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go index a22b69b534f..23ade13da9b 100644 --- a/internal/gatewayapi/translator_test.go +++ b/internal/gatewayapi/translator_test.go @@ -34,9 +34,7 @@ import ( "github.com/envoyproxy/gateway/internal/utils/file" ) -var ( - overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") -) +var overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") func mustUnmarshal(t *testing.T, val []byte, out interface{}) { require.NoError(t, yaml.UnmarshalStrict(val, out, yaml.DisallowUnknownFields)) @@ -444,7 +442,7 @@ func TestTranslateWithExtensionKinds(t *testing.T) { func overrideOutputConfig(t *testing.T, data string, filepath string) { t.Helper() - file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755) + file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o755) require.NoError(t, err) defer file.Close() write := bufio.NewWriter(file) diff --git a/internal/gatewayapi/validate.go b/internal/gatewayapi/validate.go index e7ddb427a15..09561698c66 100644 --- a/internal/gatewayapi/validate.go +++ b/internal/gatewayapi/validate.go @@ -23,7 +23,8 @@ import ( ) func (t *Translator) validateBackendRef(backendRefContext BackendRefContext, parentRef *RouteParentContext, route RouteContext, - resources *Resources, backendNamespace string, routeKind gwapiv1.Kind) bool { + resources *Resources, backendNamespace string, routeKind gwapiv1.Kind, +) bool { if !t.validateBackendRefFilters(backendRefContext, parentRef, route, routeKind) { return false } @@ -112,7 +113,8 @@ func (t *Translator) validateBackendRefFilters(backendRef BackendRefContext, par } func (t *Translator) validateBackendNamespace(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, route RouteContext, - resources *Resources, routeKind gwapiv1.Kind) bool { + resources *Resources, routeKind gwapiv1.Kind, +) bool { if backendRef.Namespace != nil && string(*backendRef.Namespace) != "" && string(*backendRef.Namespace) != route.GetNamespace() { if !t.validateCrossNamespaceRef( crossNamespaceFrom{ @@ -152,8 +154,10 @@ func (t *Translator) validateBackendPort(backendRef *gwapiv1a2.BackendRef, paren } return true } + func (t *Translator) validateBackendService(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, resources *Resources, - serviceNamespace string, route RouteContext, protocol v1.Protocol) bool { + serviceNamespace string, route RouteContext, protocol v1.Protocol, +) bool { service := resources.GetService(serviceNamespace, string(backendRef.Name)) if service == nil { parentRef.SetCondition(route, @@ -191,7 +195,8 @@ func (t *Translator) validateBackendService(backendRef *gwapiv1a2.BackendRef, pa } func (t *Translator) validateBackendServiceImport(backendRef *gwapiv1a2.BackendRef, parentRef *RouteParentContext, resources *Resources, - serviceImportNamespace string, route RouteContext, protocol v1.Protocol) bool { + serviceImportNamespace string, route RouteContext, protocol v1.Protocol, +) bool { serviceImport := resources.GetServiceImport(serviceImportNamespace, string(backendRef.Name)) if serviceImport == nil { parentRef.SetCondition(route, @@ -767,8 +772,8 @@ func (t *Translator) validateSecretRef( allowCrossNamespace bool, from crossNamespaceFrom, secretObjRef gwapiv1b1.SecretObjectReference, - resources *Resources) (*v1.Secret, error) { - + resources *Resources, +) (*v1.Secret, error) { if err := t.validateSecretObjectRef(allowCrossNamespace, from, secretObjRef, resources); err != nil { return nil, err } @@ -791,8 +796,8 @@ func (t *Translator) validateConfigMapRef( allowCrossNamespace bool, from crossNamespaceFrom, secretObjRef gwapiv1b1.SecretObjectReference, - resources *Resources) (*v1.ConfigMap, error) { - + resources *Resources, +) (*v1.ConfigMap, error) { if err := t.validateSecretObjectRef(allowCrossNamespace, from, secretObjRef, resources); err != nil { return nil, err } @@ -815,7 +820,8 @@ func (t *Translator) validateSecretObjectRef( allowCrossNamespace bool, from crossNamespaceFrom, secretRef gwapiv1b1.SecretObjectReference, - resources *Resources) error { + resources *Resources, +) error { var kind string if secretRef.Group != nil && string(*secretRef.Group) != "" { return errors.New("secret ref group must be unspecified/empty") @@ -875,8 +881,8 @@ func (t *Translator) validateSecretObjectRef( func (t *Translator) validateExtServiceBackendReference( backendRef *gwapiv1.BackendObjectReference, ownerNamespace string, - resources *Resources) error { - + resources *Resources, +) error { // These are sanity checks, they should never happen because the API server // should have caught them if backendRef.Group != nil && *backendRef.Group != "" { diff --git a/internal/infrastructure/kubernetes/infra.go b/internal/infrastructure/kubernetes/infra.go index 882d29ef8b4..03e8e412caa 100644 --- a/internal/infrastructure/kubernetes/infra.go +++ b/internal/infrastructure/kubernetes/infra.go @@ -26,6 +26,7 @@ type ResourceRender interface { Service() (*corev1.Service, error) ConfigMap() (*corev1.ConfigMap, error) Deployment() (*appsv1.Deployment, error) + DaemonSet() (*appsv1.DaemonSet, error) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPodAutoscaler, error) } @@ -66,6 +67,10 @@ func (i *Infra) createOrUpdate(ctx context.Context, r ResourceRender) error { return fmt.Errorf("failed to create or update deployment %s/%s: %w", i.Namespace, r.Name(), err) } + if err := i.createOrUpdateDaemonSet(ctx, r); err != nil { + return fmt.Errorf("failed to create or update daemonset %s/%s: %w", i.Namespace, r.Name(), err) + } + if err := i.createOrUpdateService(ctx, r); err != nil { return fmt.Errorf("failed to create or update service %s/%s: %w", i.Namespace, r.Name(), err) } @@ -91,6 +96,10 @@ func (i *Infra) delete(ctx context.Context, r ResourceRender) error { return fmt.Errorf("failed to delete deployment %s/%s: %w", i.Namespace, r.Name(), err) } + if err := i.deleteDaemonSet(ctx, r); err != nil { + return fmt.Errorf("failed to delete daemonset %s/%s: %w", i.Namespace, r.Name(), err) + } + if err := i.deleteService(ctx, r); err != nil { return fmt.Errorf("failed to delete service %s/%s: %w", i.Namespace, r.Name(), err) } diff --git a/internal/infrastructure/kubernetes/infra_resource.go b/internal/infrastructure/kubernetes/infra_resource.go index 20f5ea9929c..91b880d5d54 100644 --- a/internal/infrastructure/kubernetes/infra_resource.go +++ b/internal/infrastructure/kubernetes/infra_resource.go @@ -48,9 +48,34 @@ func (i *Infra) createOrUpdateDeployment(ctx context.Context, r ResourceRender) return err } + // delete the deployment and return early + // this handles the case where a daemonset has been + // congured + if deployment == nil { + return i.deleteDeployment(ctx, r) + } + return i.Client.ServerSideApply(ctx, deployment) } +// createOrUpdateDaemonSet creates a DaemonSet in the kube api server based on the provided +// ResourceRender, if it doesn't exist and updates it if it does. +func (i *Infra) createOrUpdateDaemonSet(ctx context.Context, r ResourceRender) error { + daemonSet, err := r.DaemonSet() + if err != nil { + return err + } + + // delete the daemonset and return early + // this handles the case where a deployment has been + // congured + if daemonSet == nil { + return i.deleteDaemonSet(ctx, r) + } + + return i.Client.ServerSideApply(ctx, daemonSet) +} + // createOrUpdateHPA creates HorizontalPodAutoscaler object in the kube api server based on // the provided ResourceRender, if it doesn't exist and updates it if it does, // and delete hpa if not set. @@ -104,6 +129,18 @@ func (i *Infra) deleteDeployment(ctx context.Context, r ResourceRender) error { return i.Client.Delete(ctx, deployment) } +// deleteDaemonSet deletes the Envoy DaemonSet in the kube api server, if it exists. +func (i *Infra) deleteDaemonSet(ctx context.Context, r ResourceRender) error { + daemonSet := &appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: i.Namespace, + Name: r.Name(), + }, + } + + return i.Client.Delete(ctx, daemonSet) +} + // deleteConfigMap deletes the ConfigMap in the kube api server, if it exists. func (i *Infra) deleteConfigMap(ctx context.Context, r ResourceRender) error { cm := &corev1.ConfigMap{ diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go index 0e5f40191da..f74481f281b 100644 --- a/internal/infrastructure/kubernetes/proxy/resource.go +++ b/internal/infrastructure/kubernetes/proxy/resource.go @@ -101,8 +101,9 @@ func enablePrometheus(infra *ir.ProxyInfra) bool { // expectedProxyContainers returns expected proxy containers. func expectedProxyContainers(infra *ir.ProxyInfra, - deploymentConfig *egv1a1.KubernetesDeploymentSpec, - shutdownConfig *egv1a1.ShutdownConfig) ([]corev1.Container, error) { + containerSpec *egv1a1.KubernetesContainerSpec, + shutdownConfig *egv1a1.ShutdownConfig, +) ([]corev1.Container, error) { // Define slice to hold container ports var ports []corev1.ContainerPort @@ -119,8 +120,7 @@ func expectedProxyContainers(infra *ir.ProxyInfra, return nil, fmt.Errorf("invalid protocol %q", p.Protocol) } port := corev1.ContainerPort{ - // hashed container port name including up to the 6 characters of the port name and the maximum of 15 characters. - Name: utils.GetHashedName(p.Name, 6), + Name: p.Name, ContainerPort: p.ContainerPort, Protocol: protocol, } @@ -144,7 +144,7 @@ func expectedProxyContainers(infra *ir.ProxyInfra, proxyMetrics = infra.Config.Spec.Telemetry.Metrics } - maxHeapSizeBytes := caclulateMaxHeapSizeBytes(deploymentConfig.Container.Resources) + maxHeapSizeBytes := caclulateMaxHeapSizeBytes(containerSpec.Resources) // Get the default Bootstrap bootstrapConfigurations, err := bootstrap.GetRenderedBootstrapConfig(&bootstrap.RenderBootsrapConfigOptions{ @@ -194,15 +194,15 @@ func expectedProxyContainers(infra *ir.ProxyInfra, containers := []corev1.Container{ { Name: envoyContainerName, - Image: *deploymentConfig.Container.Image, + Image: *containerSpec.Image, ImagePullPolicy: corev1.PullIfNotPresent, Command: []string{"envoy"}, Args: args, - Env: expectedContainerEnv(deploymentConfig.Container), - Resources: *deploymentConfig.Container.Resources, - SecurityContext: deploymentConfig.Container.SecurityContext, + Env: expectedContainerEnv(containerSpec), + Resources: *containerSpec.Resources, + SecurityContext: containerSpec.SecurityContext, Ports: ports, - VolumeMounts: expectedContainerVolumeMounts(deploymentConfig.Container), + VolumeMounts: expectedContainerVolumeMounts(containerSpec), TerminationMessagePolicy: corev1.TerminationMessageReadFile, TerminationMessagePath: "/dev/termination-log", ReadinessProbe: &corev1.Probe{ @@ -327,8 +327,8 @@ func expectedContainerVolumeMounts(containerSpec *egv1a1.KubernetesContainerSpec return resource.ExpectedContainerVolumeMounts(containerSpec, volumeMounts) } -// expectedDeploymentVolumes returns expected proxy deployment volumes. -func expectedDeploymentVolumes(name string, deploymentSpec *egv1a1.KubernetesDeploymentSpec) []corev1.Volume { +// expectedVolumes returns expected proxy deployment volumes. +func expectedVolumes(name string, pod *egv1a1.KubernetesPodSpec) []corev1.Volume { volumes := []corev1.Volume{ { Name: "certs", @@ -363,7 +363,7 @@ func expectedDeploymentVolumes(name string, deploymentSpec *egv1a1.KubernetesDep }, } - return resource.ExpectedDeploymentVolumes(deploymentSpec.Pod, volumes) + return resource.ExpectedVolumes(pod, volumes) } // expectedContainerEnv returns expected proxy container envs. diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go index 2a11f7317d3..607aa117e7b 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go @@ -76,7 +76,7 @@ func (r *ResourceRender) Service() (*corev1.Service, error) { } p := corev1.ServicePort{ - Name: ExpectedResourceHashedName(port.Name), + Name: port.Name, Protocol: protocol, Port: port.ServicePort, TargetPort: target, @@ -86,7 +86,7 @@ func (r *ResourceRender) Service() (*corev1.Service, error) { if port.Protocol == ir.HTTPSProtocolType { if listener.HTTP3 != nil { p := corev1.ServicePort{ - Name: ExpectedResourceHashedName(port.Name + "-h3"), + Name: port.Name + "-h3", Protocol: corev1.ProtocolUDP, Port: port.ServicePort, TargetPort: target, @@ -193,36 +193,27 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { } deploymentConfig := provider.GetEnvoyProxyKubeProvider().EnvoyDeployment + // If deployment config is nil, it's not Deployment installation. + if deploymentConfig == nil { + return nil, nil + } + // Get expected bootstrap configurations rendered ProxyContainers - containers, err := expectedProxyContainers(r.infra, deploymentConfig, proxyConfig.Spec.Shutdown) + containers, err := expectedProxyContainers(r.infra, deploymentConfig.Container, proxyConfig.Spec.Shutdown) if err != nil { return nil, err } - // Set the labels based on the owning gateway name. dpAnnotations := r.infra.GetProxyMetadata().Annotations - labels := r.infra.GetProxyMetadata().Labels - dpLabels := envoyLabels(labels) - if OwningGatewayLabelsAbsent(dpLabels) { - return nil, fmt.Errorf("missing owning gateway labels") - } + podAnnotations := r.getPodAnnotations(dpAnnotations, deploymentConfig.Pod) - maps.Copy(labels, deploymentConfig.Pod.Labels) - podLabels := envoyLabels(labels) - selector := resource.GetSelector(podLabels) - - // Get annotations - podAnnotations := map[string]string{} - maps.Copy(podAnnotations, dpAnnotations) - maps.Copy(podAnnotations, deploymentConfig.Pod.Annotations) - if enablePrometheus(r.infra) { - podAnnotations["prometheus.io/path"] = "/stats/prometheus" // TODO: make this configurable - podAnnotations["prometheus.io/scrape"] = "true" - podAnnotations["prometheus.io/port"] = strconv.Itoa(bootstrap.EnvoyReadinessPort) - } - if len(podAnnotations) == 0 { - podAnnotations = nil + // Set the labels based on the owning gateway name. + dpLabels, err := r.getLabels() + if err != nil { + return nil, err } + podLabels := r.getPodLabels(deploymentConfig.Pod) + selector := resource.GetSelector(podLabels) deployment := &appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ @@ -256,7 +247,7 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { SecurityContext: deploymentConfig.Pod.SecurityContext, Affinity: deploymentConfig.Pod.Affinity, Tolerations: deploymentConfig.Pod.Tolerations, - Volumes: expectedDeploymentVolumes(r.infra.Name, deploymentConfig), + Volumes: expectedVolumes(r.infra.Name, deploymentConfig.Pod), ImagePullSecrets: deploymentConfig.Pod.ImagePullSecrets, NodeSelector: deploymentConfig.Pod.NodeSelector, TopologySpreadConstraints: deploymentConfig.Pod.TopologySpreadConstraints, @@ -280,12 +271,69 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { return deployment, nil } -func expectedTerminationGracePeriodSeconds(cfg *egv1a1.ShutdownConfig) *int64 { - s := 900 // default - if cfg != nil && cfg.DrainTimeout != nil { - s = int(cfg.DrainTimeout.Seconds() + 300) // 5 minutes longer than drain timeout +func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) { + proxyConfig := r.infra.GetProxyConfig() + + // Get the EnvoyProxy config to configure the daemonset. + provider := proxyConfig.GetEnvoyProxyProvider() + if provider.Type != egv1a1.ProviderTypeKubernetes { + return nil, fmt.Errorf("invalid provider type %v for Kubernetes infra manager", provider.Type) } - return ptr.To(int64(s)) + + daemonSetConfig := provider.GetEnvoyProxyKubeProvider().EnvoyDaemonSet + + // If daemonset config is nil, it's not DaemonSet installation. + if daemonSetConfig == nil { + return nil, nil + } + + // Get expected bootstrap configurations rendered ProxyContainers + containers, err := expectedProxyContainers(r.infra, daemonSetConfig.Container, proxyConfig.Spec.Shutdown) + if err != nil { + return nil, err + } + + dsAnnotations := r.infra.GetProxyMetadata().Annotations + podAnnotations := r.getPodAnnotations(dsAnnotations, daemonSetConfig.Pod) + + // Set the labels based on the owning gateway name. + dsLabels, err := r.getLabels() + if err != nil { + return nil, err + } + podLabels := r.getPodLabels(daemonSetConfig.Pod) + selector := resource.GetSelector(podLabels) + + daemonSet := &appsv1.DaemonSet{ + TypeMeta: metav1.TypeMeta{ + Kind: "DaemonSet", + APIVersion: "apps/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: r.Namespace, + Name: r.Name(), + Labels: dsLabels, + Annotations: dsAnnotations, + }, + Spec: appsv1.DaemonSetSpec{ + Selector: selector, + UpdateStrategy: *daemonSetConfig.Strategy, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: selector.MatchLabels, + Annotations: podAnnotations, + }, + Spec: r.getPodSpec(containers, nil, daemonSetConfig.Pod, proxyConfig), + }, + }, + } + + // apply merge patch to daemonset + if daemonSet, err = daemonSetConfig.ApplyMergePatch(daemonSet); err != nil { + return nil, err + } + + return daemonSet, nil } func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPodAutoscaler, error) { @@ -326,6 +374,73 @@ func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPod return hpa, nil } +func expectedTerminationGracePeriodSeconds(cfg *egv1a1.ShutdownConfig) *int64 { + s := 900 // default + if cfg != nil && cfg.DrainTimeout != nil { + s = int(cfg.DrainTimeout.Seconds() + 300) // 5 minutes longer than drain timeout + } + return ptr.To(int64(s)) +} + +func (r *ResourceRender) getPodSpec( + containers, initContainers []corev1.Container, + pod *egv1a1.KubernetesPodSpec, + proxyConfig *egv1a1.EnvoyProxy, +) corev1.PodSpec { + return corev1.PodSpec{ + Containers: containers, + InitContainers: initContainers, + ServiceAccountName: ExpectedResourceHashedName(r.infra.Name), + AutomountServiceAccountToken: ptr.To(false), + TerminationGracePeriodSeconds: expectedTerminationGracePeriodSeconds(proxyConfig.Spec.Shutdown), + DNSPolicy: corev1.DNSClusterFirst, + RestartPolicy: corev1.RestartPolicyAlways, + SchedulerName: "default-scheduler", + SecurityContext: pod.SecurityContext, + Affinity: pod.Affinity, + Tolerations: pod.Tolerations, + Volumes: expectedVolumes(r.infra.Name, pod), + ImagePullSecrets: pod.ImagePullSecrets, + NodeSelector: pod.NodeSelector, + TopologySpreadConstraints: pod.TopologySpreadConstraints, + } +} + +func (r *ResourceRender) getPodAnnotations(resourceAnnotation map[string]string, pod *egv1a1.KubernetesPodSpec) map[string]string { + podAnnotations := map[string]string{} + maps.Copy(podAnnotations, resourceAnnotation) + maps.Copy(podAnnotations, pod.Annotations) + + if enablePrometheus(r.infra) { + podAnnotations["prometheus.io/path"] = "/stats/prometheus" // TODO: make this configurable + podAnnotations["prometheus.io/scrape"] = "true" + podAnnotations["prometheus.io/port"] = strconv.Itoa(bootstrap.EnvoyReadinessPort) + } + + if len(podAnnotations) == 0 { + podAnnotations = nil + } + + return podAnnotations +} + +func (r *ResourceRender) getLabels() (map[string]string, error) { + // Set the labels based on the owning gateway name. + resourceLabels := envoyLabels(r.infra.GetProxyMetadata().Labels) + if OwningGatewayLabelsAbsent(resourceLabels) { + return nil, fmt.Errorf("missing owning gateway labels") + } + + return resourceLabels, nil +} + +func (r *ResourceRender) getPodLabels(pod *egv1a1.KubernetesPodSpec) map[string]string { + labels := r.infra.GetProxyMetadata().Labels + maps.Copy(labels, pod.Labels) + + return envoyLabels(labels) +} + // OwningGatewayLabelsAbsent Check if labels are missing some OwningGatewayLabels func OwningGatewayLabelsAbsent(labels map[string]string) bool { return (len(labels[gatewayapi.OwningGatewayNameLabel]) == 0 || diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go index 3b105cc96c3..0d4a5999368 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go @@ -30,9 +30,7 @@ import ( "github.com/envoyproxy/gateway/internal/ir" ) -var ( - overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") -) +var overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") const ( // envoyHTTPPort is the container port number of Envoy's HTTP endpoint. @@ -565,7 +563,7 @@ func TestDeployment(t *testing.T) { deploymentYAML, err := yaml.Marshal(dp) require.NoError(t, err) // nolint: gosec - err = os.WriteFile(fmt.Sprintf("testdata/deployments/%s.yaml", tc.caseName), deploymentYAML, 0644) + err = os.WriteFile(fmt.Sprintf("testdata/deployments/%s.yaml", tc.caseName), deploymentYAML, 0o644) require.NoError(t, err) return } @@ -587,6 +585,427 @@ func loadDeployment(caseName string) (*appsv1.Deployment, error) { return deployment, nil } +func TestDaemonSet(t *testing.T) { + cfg, err := config.New() + require.NoError(t, err) + + cases := []struct { + caseName string + infra *ir.Infra + daemonset *egv1a1.KubernetesDaemonSetSpec + shutdown *egv1a1.ShutdownConfig + proxyLogging map[egv1a1.ProxyLogComponent]egv1a1.LogLevel + bootstrap string + telemetry *egv1a1.ProxyTelemetry + concurrency *int32 + extraArgs []string + }{ + { + caseName: "default", + infra: newTestInfra(), + daemonset: nil, + }, + { + caseName: "custom", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Strategy: egv1a1.DefaultKubernetesDaemonSetStrategy(), + Pod: &egv1a1.KubernetesPodSpec{ + Annotations: map[string]string{ + "prometheus.io/scrape": "true", + }, + Labels: map[string]string{ + "foo.bar": "custom-label", + }, + SecurityContext: &corev1.PodSecurityContext{ + RunAsUser: ptr.To[int64](1000), + }, + }, + Container: &egv1a1.KubernetesContainerSpec{ + Image: ptr.To("envoyproxy/envoy:v1.2.3"), + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("400m"), + corev1.ResourceMemory: resource.MustParse("2Gi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("200m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + SecurityContext: &corev1.SecurityContext{ + Privileged: ptr.To(true), + }, + }, + }, + }, + { + caseName: "patch-daemonset", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Patch: &egv1a1.KubernetesPatchSpec{ + Type: ptr.To(egv1a1.StrategicMerge), + Value: v1.JSON{ + Raw: []byte("{\"spec\":{\"template\":{\"spec\":{\"hostNetwork\":true,\"dnsPolicy\":\"ClusterFirstWithHostNet\"}}}}"), + }, + }, + }, + }, + { + caseName: "shutdown-manager", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Patch: &egv1a1.KubernetesPatchSpec{ + Type: ptr.To(egv1a1.StrategicMerge), + Value: v1.JSON{ + Raw: []byte(`{ + "spec":{ + "template":{ + "spec":{ + "containers":[{ + "name":"shutdown-manager", + "resources":{ + "requests":{"cpu":"100m","memory":"64Mi"}, + "limits":{"cpu":"200m","memory":"96Mi"} + }, + "securityContext":{"runAsUser":1234}, + "env":[ + {"name":"env_a","value":"env_a_value"}, + {"name":"env_b","value":"env_b_value"} + ], + "image":"envoyproxy/gateway-dev:v1.2.3" + }] + } + } + } + }`), + }, + }, + }, + shutdown: &egv1a1.ShutdownConfig{ + DrainTimeout: &metav1.Duration{ + Duration: 30 * time.Second, + }, + MinDrainDuration: &metav1.Duration{ + Duration: 15 * time.Second, + }, + }, + }, + { + caseName: "extension-env", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Strategy: egv1a1.DefaultKubernetesDaemonSetStrategy(), + Pod: &egv1a1.KubernetesPodSpec{ + Annotations: map[string]string{ + "prometheus.io/scrape": "true", + }, + SecurityContext: &corev1.PodSecurityContext{ + RunAsUser: ptr.To[int64](1000), + }, + }, + Container: &egv1a1.KubernetesContainerSpec{ + Env: []corev1.EnvVar{ + { + Name: "env_a", + Value: "env_a_value", + }, + { + Name: "env_b", + Value: "env_b_value", + }, + }, + Image: ptr.To("envoyproxy/envoy:v1.2.3"), + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("400m"), + corev1.ResourceMemory: resource.MustParse("2Gi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("200m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + SecurityContext: &corev1.SecurityContext{ + Privileged: ptr.To(true), + }, + }, + }, + }, + { + caseName: "default-env", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Strategy: egv1a1.DefaultKubernetesDaemonSetStrategy(), + Pod: &egv1a1.KubernetesPodSpec{ + Annotations: map[string]string{ + "prometheus.io/scrape": "true", + }, + SecurityContext: &corev1.PodSecurityContext{ + RunAsUser: ptr.To[int64](1000), + }, + }, + Container: &egv1a1.KubernetesContainerSpec{ + Env: nil, + Image: ptr.To("envoyproxy/envoy:v1.2.3"), + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("400m"), + corev1.ResourceMemory: resource.MustParse("2Gi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("200m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + SecurityContext: &corev1.SecurityContext{ + Privileged: ptr.To(true), + }, + }, + }, + }, + { + caseName: "volumes", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Strategy: egv1a1.DefaultKubernetesDaemonSetStrategy(), + Pod: &egv1a1.KubernetesPodSpec{ + Annotations: map[string]string{ + "prometheus.io/scrape": "true", + }, + SecurityContext: &corev1.PodSecurityContext{ + RunAsUser: ptr.To[int64](1000), + }, + Volumes: []corev1.Volume{ + { + Name: "certs", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "custom-envoy-cert", + DefaultMode: ptr.To[int32](420), + }, + }, + }, + }, + }, + Container: &egv1a1.KubernetesContainerSpec{ + Env: []corev1.EnvVar{ + { + Name: "env_a", + Value: "env_a_value", + }, + { + Name: "env_b", + Value: "env_b_value", + }, + }, + Image: ptr.To("envoyproxy/envoy:v1.2.3"), + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("400m"), + corev1.ResourceMemory: resource.MustParse("2Gi"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("200m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + SecurityContext: &corev1.SecurityContext{ + Privileged: ptr.To(true), + }, + }, + }, + }, + { + caseName: "component-level", + infra: newTestInfra(), + daemonset: nil, + proxyLogging: map[egv1a1.ProxyLogComponent]egv1a1.LogLevel{ + egv1a1.LogComponentDefault: egv1a1.LogLevelError, + egv1a1.LogComponentFilter: egv1a1.LogLevelInfo, + }, + bootstrap: `test bootstrap config`, + }, + { + caseName: "disable-prometheus", + infra: newTestInfra(), + telemetry: &egv1a1.ProxyTelemetry{ + Metrics: &egv1a1.ProxyMetrics{ + Prometheus: &egv1a1.ProxyPrometheusProvider{ + Disable: true, + }, + }, + }, + }, + { + caseName: "with-concurrency", + infra: newTestInfra(), + daemonset: nil, + concurrency: ptr.To[int32](4), + bootstrap: `test bootstrap config`, + }, + { + caseName: "with-annotations", + infra: newTestInfraWithAnnotations(map[string]string{ + "anno1": "value1", + "anno2": "value2", + }), + daemonset: nil, + }, + { + caseName: "override-labels-and-annotations", + infra: newTestInfraWithAnnotationsAndLabels(map[string]string{ + "anno1": "value1", + "anno2": "value2", + }, map[string]string{ + "label1": "value1", + "label2": "value2", + }), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Pod: &egv1a1.KubernetesPodSpec{ + Annotations: map[string]string{ + "anno1": "value1-override", + }, + Labels: map[string]string{ + "label1": "value1-override", + }, + }, + }, + }, + { + caseName: "with-image-pull-secrets", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Pod: &egv1a1.KubernetesPodSpec{ + ImagePullSecrets: []corev1.LocalObjectReference{ + { + Name: "aaa", + }, + { + Name: "bbb", + }, + }, + }, + }, + }, + { + caseName: "with-node-selector", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Pod: &egv1a1.KubernetesPodSpec{ + NodeSelector: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + }, + }, + }, + { + caseName: "with-topology-spread-constraints", + infra: newTestInfra(), + daemonset: &egv1a1.KubernetesDaemonSetSpec{ + Pod: &egv1a1.KubernetesPodSpec{ + TopologySpreadConstraints: []corev1.TopologySpreadConstraint{ + { + MaxSkew: 1, + TopologyKey: "kubernetes.io/hostname", + WhenUnsatisfiable: corev1.DoNotSchedule, + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "foo"}, + }, + MatchLabelKeys: []string{"pod-template-hash"}, + }, + }, + }, + }, + }, + { + caseName: "with-extra-args", + infra: newTestInfra(), + extraArgs: []string{"--key1 val1", "--key2 val2"}, + }, + } + for _, tc := range cases { + t.Run(tc.caseName, func(t *testing.T) { + kube := tc.infra.GetProxyInfra().GetProxyConfig().GetEnvoyProxyProvider().GetEnvoyProxyKubeProvider() + + // fill deploument, use daemonset + kube.EnvoyDeployment = nil + kube.EnvoyDaemonSet = egv1a1.DefaultKubernetesDaemonSet(egv1a1.DefaultEnvoyProxyImage) + + if tc.daemonset != nil { + kube.EnvoyDaemonSet = tc.daemonset + } + + replace := egv1a1.BootstrapTypeReplace + if tc.bootstrap != "" { + tc.infra.Proxy.Config.Spec.Bootstrap = &egv1a1.ProxyBootstrap{ + Type: &replace, + Value: tc.bootstrap, + } + } + + if tc.telemetry != nil { + tc.infra.Proxy.Config.Spec.Telemetry = tc.telemetry + } + + if len(tc.proxyLogging) > 0 { + tc.infra.Proxy.Config.Spec.Logging = egv1a1.ProxyLogging{ + Level: tc.proxyLogging, + } + } + + if tc.concurrency != nil { + tc.infra.Proxy.Config.Spec.Concurrency = tc.concurrency + } + + if tc.shutdown != nil { + tc.infra.Proxy.Config.Spec.Shutdown = tc.shutdown + } + + if len(tc.extraArgs) > 0 { + tc.infra.Proxy.Config.Spec.ExtraArgs = tc.extraArgs + } + + r := NewResourceRender(cfg.Namespace, tc.infra.GetProxyInfra()) + ds, err := r.DaemonSet() + require.NoError(t, err) + + expected, err := loadDaemonSet(tc.caseName) + require.NoError(t, err) + + sortEnv := func(env []corev1.EnvVar) { + sort.Slice(env, func(i, j int) bool { + return env[i].Name > env[j].Name + }) + } + + if *overrideTestData { + deploymentYAML, err := yaml.Marshal(ds) + require.NoError(t, err) + // nolint: gosec + err = os.WriteFile(fmt.Sprintf("testdata/daemonsets/%s.yaml", tc.caseName), deploymentYAML, 0o644) + require.NoError(t, err) + return + } + + sortEnv(ds.Spec.Template.Spec.Containers[0].Env) + sortEnv(expected.Spec.Template.Spec.Containers[0].Env) + assert.Equal(t, expected, ds) + }) + } +} + +func loadDaemonSet(caseName string) (*appsv1.DaemonSet, error) { + daemonsetYAML, err := os.ReadFile(fmt.Sprintf("testdata/daemonsets/%s.yaml", caseName)) + if err != nil { + return nil, err + } + daemonset := &appsv1.DaemonSet{} + _ = yaml.Unmarshal(daemonsetYAML, daemonset) + return daemonset, nil +} + func TestService(t *testing.T) { cfg, err := config.New() require.NoError(t, err) @@ -729,7 +1148,6 @@ func loadConfigmap(tc string) (*corev1.ConfigMap, error) { } func TestServiceAccount(t *testing.T) { - cfg, err := config.New() require.NoError(t, err) cases := []struct { @@ -855,7 +1273,6 @@ func loadHPA(caseName string) (*autoscalingv2.HorizontalPodAutoscaler, error) { } func TestOwningGatewayLabelsAbsent(t *testing.T) { - cases := []struct { caseName string labels map[string]string @@ -903,5 +1320,4 @@ func TestOwningGatewayLabelsAbsent(t *testing.T) { require.Equal(t, tc.expect, actual) }) } - } diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml new file mode 100644 index 00000000000..c15140c1b53 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml @@ -0,0 +1,173 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - --config-yaml test bootstrap config + - --log-level error + - --cpuset-threads + - --component-log-level filter:info + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml new file mode 100644 index 00000000000..8c49a94297c --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml @@ -0,0 +1,326 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + foo.bar: custom-label + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + foo.bar: custom-label + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - name: "envoy.resource_monitors.fixed_heap" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.fixed_heap.v3.FixedHeapConfig + max_heap_size_bytes: 1717986918 + actions: + - name: "envoy.overload_actions.shrink_heap" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.95 + - name: "envoy.overload_actions.stop_accepting_requests" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.98 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:v1.2.3 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + securityContext: + privileged: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + runAsUser: 1000 + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml new file mode 100644 index 00000000000..ac875d88b8e --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml @@ -0,0 +1,324 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - name: "envoy.resource_monitors.fixed_heap" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.fixed_heap.v3.FixedHeapConfig + max_heap_size_bytes: 1717986918 + actions: + - name: "envoy.overload_actions.shrink_heap" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.95 + - name: "envoy.overload_actions.stop_accepting_requests" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.98 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:v1.2.3 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + securityContext: + privileged: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + runAsUser: 1000 + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml new file mode 100644 index 00000000000..b27d515a915 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml @@ -0,0 +1,302 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml new file mode 100644 index 00000000000..842407c32c7 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml @@ -0,0 +1,273 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml new file mode 100644 index 00000000000..97a00431c75 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml @@ -0,0 +1,328 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - name: "envoy.resource_monitors.fixed_heap" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.fixed_heap.v3.FixedHeapConfig + max_heap_size_bytes: 1717986918 + actions: + - name: "envoy.overload_actions.shrink_heap" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.95 + - name: "envoy.overload_actions.stop_accepting_requests" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.98 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: env_a + value: env_a_value + - name: env_b + value: env_b_value + image: envoyproxy/envoy:v1.2.3 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + securityContext: + privileged: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + runAsUser: 1000 + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml new file mode 100644 index 00000000000..5a19dc72f0d --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml @@ -0,0 +1,313 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + annotations: + anno1: value1 + anno2: value2 + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + label1: value1 + label2: value2 + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + label1: value1-override + label2: value2 + template: + metadata: + annotations: + anno1: value1-override + anno2: value2 + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + label1: value1-override + label2: value2 + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml new file mode 100644 index 00000000000..4728969d70b --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml @@ -0,0 +1,303 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml new file mode 100644 index 00000000000..a5a5e85e728 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml @@ -0,0 +1,315 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + - --drain-time-s 30 + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + - --ready-timeout=40s + command: + - envoy-gateway + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_value + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:v1.2.3 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + - --drain-timeout=30s + - --min-drain-duration=15s + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 200m + memory: 96Mi + requests: + cpu: 100m + memory: 64Mi + securityContext: + runAsUser: 1234 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 330 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml new file mode 100644 index 00000000000..8553fda9705 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml @@ -0,0 +1,328 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - name: "envoy.resource_monitors.fixed_heap" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.fixed_heap.v3.FixedHeapConfig + max_heap_size_bytes: 1717986918 + actions: + - name: "envoy.overload_actions.shrink_heap" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.95 + - name: "envoy.overload_actions.stop_accepting_requests" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.98 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: env_a + value: env_a_value + - name: env_b + value: env_b_value + image: envoyproxy/envoy:v1.2.3 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + securityContext: + privileged: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + runAsUser: 1000 + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: custom-envoy-cert + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml new file mode 100644 index 00000000000..bd8b749a1d3 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml @@ -0,0 +1,307 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + annotations: + anno1: value1 + anno2: value2 + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + anno1: value1 + anno2: value2 + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml new file mode 100644 index 00000000000..893fdf3d447 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml @@ -0,0 +1,173 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - --config-yaml test bootstrap config + - --log-level warn + - --cpuset-threads + - --concurrency 4 + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml new file mode 100644 index 00000000000..8e7a529ce1c --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml @@ -0,0 +1,304 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + - --key1 val1 + - --key2 val2 + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml new file mode 100644 index 00000000000..1469fb21616 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml @@ -0,0 +1,305 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: aaa + - name: bbb + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml new file mode 100644 index 00000000000..d0618604cf5 --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml @@ -0,0 +1,305 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + nodeSelector: + key1: value1 + key2: value2 + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml new file mode 100644 index 00000000000..0986faca79a --- /dev/null +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml @@ -0,0 +1,311 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + name: envoy-default-37a8eec1 + namespace: envoy-gateway-system +spec: + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + template: + metadata: + annotations: + prometheus.io/path: /stats/prometheus + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: proxy + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy + gateway.envoyproxy.io/owning-gateway-name: default + gateway.envoyproxy.io/owning-gateway-namespace: default + spec: + automountServiceAccountToken: false + containers: + - args: + - --service-cluster default + - --service-node $(ENVOY_POD_NAME) + - | + --config-yaml admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 + dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 + static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 + overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + - --log-level warn + - --cpuset-threads + command: + - envoy + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/envoy:distroless-dev + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + httpGet: + path: /shutdown/ready + port: 19002 + scheme: HTTP + name: envoy + ports: + - containerPort: 8080 + name: EnvoyHTTPPort + protocol: TCP + - containerPort: 8443 + name: EnvoyHTTPSPort + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 19001 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - mountPath: /sds + name: sds + - args: + - envoy + - shutdown-manager + command: + - envoy-gateway + env: + - name: ENVOY_GATEWAY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: ENVOY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: envoyproxy/gateway-dev:latest + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - envoy-gateway + - envoy + - shutdown + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: shutdown-manager + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 19002 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 10m + memory: 32Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-default-37a8eec1 + terminationGracePeriodSeconds: 900 + topologySpreadConstraints: + - labelSelector: + matchLabels: + app: foo + matchLabelKeys: + - pod-template-hash + maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy + - configMap: + defaultMode: 420 + items: + - key: xds-trusted-ca.json + path: xds-trusted-ca.json + - key: xds-certificate.json + path: xds-certificate.json + name: envoy-default-37a8eec1 + optional: false + name: sds + updateStrategy: + type: RollingUpdate +status: + currentNumberScheduled: 0 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml index e40e9f75a6d..25ead478c0d 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml @@ -68,10 +68,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml index eaaa4fe3070..79f39763a5c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml @@ -69,10 +69,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml index a2b36699624..be6b2d5d225 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml @@ -216,10 +216,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml index 2a179f2e7b4..d340fce372d 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml @@ -216,10 +216,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml index c255d72fee5..ea0fa6907a0 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml @@ -214,10 +214,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml index 68730b25dca..3fd0948f2ee 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml @@ -198,10 +198,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml index a048b3247b6..14342f83286 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml @@ -172,10 +172,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP readinessProbe: failureThreshold: 3 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml index 56cc469846f..2c371d90811 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml @@ -218,10 +218,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml index 398deeefc8f..1e65cc299ec 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml @@ -209,10 +209,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml index f47f6b5e114..72757a325b7 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml @@ -198,10 +198,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml index 66709926358..7bcb064cdee 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml @@ -199,10 +199,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml index a452cb55c8a..2fecd59712f 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml @@ -218,10 +218,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml index d56f8a2b267..65cea34a8d9 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml @@ -203,10 +203,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml index 30dbb84616a..b5ce902f529 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml @@ -69,10 +69,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml index 050ed47b5d3..f60fec2e8eb 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml @@ -198,10 +198,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml index b077bd33364..2085acacc0e 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml @@ -200,10 +200,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml index 13cdfe76c1a..e1e2b22b957 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml @@ -198,10 +198,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml index 5e7d0144baf..08f9e6a0b85 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml @@ -198,10 +198,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml index 44d3bcfdb4e..1b734654109 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml @@ -198,10 +198,10 @@ spec: name: envoy ports: - containerPort: 8080 - name: EnvoyH-d76a15e2 + name: EnvoyHTTPPort protocol: TCP - containerPort: 8443 - name: EnvoyH-6658f727 + name: EnvoyHTTPSPort protocol: TCP - containerPort: 19001 name: metrics diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/clusterIP-custom-addresses.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/clusterIP-custom-addresses.yaml index 336e3fe8ee0..f6730ec0439 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/services/clusterIP-custom-addresses.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/services/clusterIP-custom-addresses.yaml @@ -14,11 +14,11 @@ spec: clusterIPs: - 10.102.168.100 ports: - - name: envoy-EnvoyHTTPPort-d76a15e2 + - name: EnvoyHTTPPort port: 0 protocol: TCP targetPort: 8080 - - name: envoy-EnvoyHTTPSPort-6658f727 + - name: EnvoyHTTPSPort port: 0 protocol: TCP targetPort: 8443 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml index 4139ac4f6b1..e898ccb1aff 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/services/custom.yaml @@ -13,11 +13,11 @@ metadata: namespace: envoy-gateway-system spec: ports: - - name: envoy-EnvoyHTTPPort-d76a15e2 + - name: EnvoyHTTPPort port: 0 protocol: TCP targetPort: 8080 - - name: envoy-EnvoyHTTPSPort-6658f727 + - name: EnvoyHTTPSPort port: 0 protocol: TCP targetPort: 8443 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/default.yaml index 6efc4ee4aaf..8b4bd40b87f 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/services/default.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/services/default.yaml @@ -12,11 +12,11 @@ metadata: spec: externalTrafficPolicy: Local ports: - - name: envoy-EnvoyHTTPPort-d76a15e2 + - name: EnvoyHTTPPort port: 0 protocol: TCP targetPort: 8080 - - name: envoy-EnvoyHTTPSPort-6658f727 + - name: EnvoyHTTPSPort port: 0 protocol: TCP targetPort: 8443 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/override-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/override-annotations.yaml index 8953b5d9590..be487a5f96e 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/services/override-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/services/override-annotations.yaml @@ -17,11 +17,11 @@ metadata: spec: externalTrafficPolicy: Local ports: - - name: envoy-EnvoyHTTPPort-d76a15e2 + - name: EnvoyHTTPPort port: 0 protocol: TCP targetPort: 8080 - - name: envoy-EnvoyHTTPSPort-6658f727 + - name: EnvoyHTTPSPort port: 0 protocol: TCP targetPort: 8443 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/patch-service.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/patch-service.yaml index 3dd093ffff6..8d904a9eb6c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/services/patch-service.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/services/patch-service.yaml @@ -12,11 +12,11 @@ metadata: spec: externalTrafficPolicy: Local ports: - - name: envoy-EnvoyHTTPPort-d76a15e2 + - name: EnvoyHTTPPort port: 0 protocol: TCP targetPort: 8080 - - name: envoy-EnvoyHTTPSPort-6658f727 + - name: EnvoyHTTPSPort port: 0 protocol: TCP targetPort: 8443 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/services/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/services/with-annotations.yaml index 75635bc5fcd..9121cf5fe71 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/services/with-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/services/with-annotations.yaml @@ -15,11 +15,11 @@ metadata: spec: externalTrafficPolicy: Local ports: - - name: envoy-EnvoyHTTPPort-d76a15e2 + - name: EnvoyHTTPPort port: 0 protocol: TCP targetPort: 8080 - - name: envoy-EnvoyHTTPSPort-6658f727 + - name: EnvoyHTTPSPort port: 0 protocol: TCP targetPort: 8443 diff --git a/internal/infrastructure/kubernetes/proxy_infra_test.go b/internal/infrastructure/kubernetes/proxy_infra_test.go index d39f8059799..5c8a8d34695 100644 --- a/internal/infrastructure/kubernetes/proxy_infra_test.go +++ b/internal/infrastructure/kubernetes/proxy_infra_test.go @@ -192,7 +192,6 @@ func TestCreateProxyInfra(t *testing.T) { } func TestDeleteProxyInfra(t *testing.T) { - testCases := []struct { name string in *ir.Infra diff --git a/internal/infrastructure/kubernetes/ratelimit/resource.go b/internal/infrastructure/kubernetes/ratelimit/resource.go index 32dfba94c1b..6ab5b19433f 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource.go @@ -79,6 +79,18 @@ const ( ConfigGrpcXdsServerURLEnvVar = "CONFIG_GRPC_XDS_SERVER_URL" // ConfigGrpcXdsNodeIDEnvVar is the id of ratelimit node. ConfigGrpcXdsNodeIDEnvVar = "CONFIG_GRPC_XDS_NODE_ID" + // TracingEnabledVar is enabled the tracing feature + TracingEnabledVar = "TRACING_ENABLED" + // TracingServiceNameVar is service name appears in tracing span + TracingServiceNameVar = "TRACING_SERVICE_NAME" + // TracingServiceNamespaceVar is service namespace appears in tracing span + TracingServiceNamespaceVar = "TRACING_SERVICE_NAMESPACE" + // TracingServiceInstanceIDVar is service instance id appears in tracing span + TracingServiceInstanceIDVar = "TRACING_SERVICE_INSTANCE_ID" + // TracingSamplingRateVar is trace sampling rate + TracingSamplingRateVar = "TRACING_SAMPLING_RATE" + // OTELExporterOTLPTraceEndpointVar is target url to which the trace exporter is going to send + OTELExporterOTLPTraceEndpointVar = "OTEL_EXPORTER_OTLP_ENDPOINT" // InfraName is the name for rate-limit resources. InfraName = "envoy-ratelimit" @@ -103,7 +115,6 @@ func GetServiceURL(namespace string, dnsDomain string) string { // LabelSelector returns the string slice form labels used for all envoy rate limit resources. func LabelSelector() []string { - rlLabelMap := rateLimitLabels() retLabels := make([]string, 0, len(rlLabelMap)) @@ -125,7 +136,9 @@ func rateLimitLabels() map[string]string { } // expectedRateLimitContainers returns expected rateLimit containers. -func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec) []corev1.Container { +func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec, + namespace string, +) []corev1.Container { ports := []corev1.ContainerPort{ { Name: "grpc", @@ -142,7 +155,7 @@ func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeploymen Command: []string{ "/bin/ratelimit", }, - Env: expectedRateLimitContainerEnv(rateLimit, rateLimitDeployment), + Env: expectedRateLimitContainerEnv(rateLimit, rateLimitDeployment, namespace), Ports: ports, Resources: *rateLimitDeployment.Container.Resources, SecurityContext: rateLimitDeployment.Container.SecurityContext, @@ -271,11 +284,13 @@ func expectedDeploymentVolumes(rateLimit *egv1a1.RateLimit, rateLimitDeployment }) } - return resource.ExpectedDeploymentVolumes(rateLimitDeployment.Pod, volumes) + return resource.ExpectedVolumes(rateLimitDeployment.Pod, volumes) } // expectedRateLimitContainerEnv returns expected rateLimit container envs. -func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec) []corev1.EnvVar { +func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeployment *egv1a1.KubernetesDeploymentSpec, + namespace string, +) []corev1.EnvVar { env := []corev1.EnvVar{ { Name: RuntimeRootEnvVar, @@ -384,6 +399,54 @@ func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeploym } } + if enableTracing(rateLimit) { + sampleRate := 1.0 + if rateLimit.Telemetry.Tracing.SamplingRate != nil { + sampleRate = float64(*rateLimit.Telemetry.Tracing.SamplingRate) / 100.0 + } + + traceEndpoint := checkTraceEndpointScheme(rateLimit.Telemetry.Tracing.Provider.URL) + tracingEnvs := []corev1.EnvVar{ + { + Name: TracingEnabledVar, + Value: "true", + }, + { + Name: TracingServiceNameVar, + Value: InfraName, + }, + { + Name: TracingServiceNamespaceVar, + Value: namespace, + }, + { + // By default, this is a random instanceID, + // we use the RateLimit pod name as the trace service instanceID. + Name: TracingServiceInstanceIDVar, + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }, + }, + }, + { + Name: TracingSamplingRateVar, + // The api is configured with [0,100], but sampling can only be [0,1]. + // doc: https://github.com/envoyproxy/ratelimit?tab=readme-ov-file#tracing + // You will lose precision during the conversion process, but don't worry, + // this follows the rounding rule and won't make the expected sampling rate too different + // from the actual sampling rate + Value: strconv.FormatFloat(sampleRate, 'f', 1, 64), + }, + { + Name: OTELExporterOTLPTraceEndpointVar, + Value: traceEndpoint, + }, + } + env = append(env, tracingEnvs...) + } + return resource.ExpectedContainerEnv(rateLimitDeployment.Container, env) } @@ -399,3 +462,31 @@ func Validate(ctx context.Context, client client.Client, gateway *egv1a1.EnvoyGa return nil } + +func enableTracing(rl *egv1a1.RateLimit) bool { + // Other fields can use the default values, + // but we have to make sure the user has the Provider.URL + if rl != nil && rl.Telemetry != nil && + rl.Telemetry.Tracing != nil && + rl.Telemetry.Tracing.Provider != nil && + len(rl.Telemetry.Tracing.Provider.URL) != 0 { + return true + } + + return false +} + +// checkTraceEndpointScheme Check the scheme prefix in the trace url +func checkTraceEndpointScheme(url string) string { + // Since the OTLP collector needs to configure the scheme prefix, + // we need to check if the user has configured this + // TODO: It is currently assumed to be a normal connection, + // and a TLS connection will be added later. + httpScheme := "http://" + exist := strings.HasPrefix(url, httpScheme) + if exist { + return url + } + + return fmt.Sprintf("%s%s", httpScheme, url) +} diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go index 90f646d014f..62d8e3df4ce 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go @@ -61,6 +61,7 @@ func (r *ResourceRender) Name() string { func enablePrometheus(rl *egv1a1.RateLimit) bool { if rl != nil && rl.Telemetry != nil && + rl.Telemetry.Metrics != nil && rl.Telemetry.Metrics.Prometheus != nil { return !rl.Telemetry.Metrics.Prometheus.Disable } @@ -183,7 +184,7 @@ func (r *ResourceRender) ServiceAccount() (*corev1.ServiceAccount, error) { // Deployment returns the expected rate limit Deployment based on the provided infra. func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { - containers := expectedRateLimitContainers(r.rateLimit, r.rateLimitDeployment) + containers := expectedRateLimitContainers(r.rateLimit, r.rateLimitDeployment, r.Namespace) labels := rateLimitLabels() selector := resource.GetSelector(labels) @@ -261,6 +262,11 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { return deployment, nil } +// TODO: implement this method +func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) { + return nil, nil +} + func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPodAutoscaler, error) { return nil, nil } diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go index 6c56631d9cc..6345aebdc55 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go @@ -27,9 +27,7 @@ import ( "github.com/envoyproxy/gateway/internal/envoygateway/config" ) -var ( - overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") -) +var overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") const ( // RedisAuthEnvVar is the redis auth. @@ -43,7 +41,6 @@ var ownerReferenceUID = map[string]types.UID{ } func TestRateLimitLabelSelector(t *testing.T) { - cases := []struct { name string expected []string @@ -65,7 +62,6 @@ func TestRateLimitLabelSelector(t *testing.T) { require.ElementsMatch(t, tc.expected, got) }) } - } func TestRateLimitLabels(t *testing.T) { @@ -126,7 +122,6 @@ func loadServiceAccount() (*corev1.ServiceAccount, error) { } func TestService(t *testing.T) { - cfg, err := config.New() require.NoError(t, err) @@ -209,7 +204,7 @@ func TestConfigmap(t *testing.T) { cmYAML, err := yaml.Marshal(cm) require.NoError(t, err) // nolint:gosec - err = os.WriteFile("testdata/envoy-ratelimit-configmap.yaml", cmYAML, 0644) + err = os.WriteFile("testdata/envoy-ratelimit-configmap.yaml", cmYAML, 0o644) require.NoError(t, err) return } @@ -648,6 +643,43 @@ func TestDeployment(t *testing.T) { }, }, }, + { + caseName: "enable-tracing", + rateLimit: &egv1a1.RateLimit{ + Backend: egv1a1.RateLimitDatabaseBackend{ + Type: egv1a1.RedisBackendType, + Redis: &egv1a1.RateLimitRedisSettings{ + URL: "redis.redis.svc:6379", + }, + }, + Telemetry: &egv1a1.RateLimitTelemetry{ + Tracing: &egv1a1.RateLimitTracing{ + Provider: &egv1a1.RateLimitTracingProvider{ + URL: "http://trace-collector.envoy-gateway-system.svc.cluster.local:4318", + }, + }, + }, + }, + }, + { + caseName: "enable-tracing-custom", + rateLimit: &egv1a1.RateLimit{ + Backend: egv1a1.RateLimitDatabaseBackend{ + Type: egv1a1.RedisBackendType, + Redis: &egv1a1.RateLimitRedisSettings{ + URL: "redis.redis.svc:6379", + }, + }, + Telemetry: &egv1a1.RateLimitTelemetry{ + Tracing: &egv1a1.RateLimitTracing{ + SamplingRate: ptr.To[uint32](55), + Provider: &egv1a1.RateLimitTracingProvider{ + URL: "trace-collector.envoy-gateway-system.svc.cluster.local:4317", + }, + }, + }, + }, + }, } for _, tc := range cases { t.Run(tc.caseName, func(t *testing.T) { @@ -657,7 +689,8 @@ func TestDeployment(t *testing.T) { Type: egv1a1.ProviderTypeKubernetes, Kubernetes: &egv1a1.EnvoyGatewayKubernetesProvider{ RateLimitDeployment: tc.deploy, - }} + }, + } r := NewResourceRender(cfg.Namespace, cfg.EnvoyGateway, ownerReferenceUID) dp, err := r.Deployment() require.NoError(t, err) @@ -666,7 +699,7 @@ func TestDeployment(t *testing.T) { deploymentYAML, err := yaml.Marshal(dp) require.NoError(t, err) // nolint:gosec - err = os.WriteFile(fmt.Sprintf("testdata/deployments/%s.yaml", tc.caseName), deploymentYAML, 0644) + err = os.WriteFile(fmt.Sprintf("testdata/deployments/%s.yaml", tc.caseName), deploymentYAML, 0o644) require.NoError(t, err) return } diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_test.go new file mode 100644 index 00000000000..61d24eac8da --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/resource_test.go @@ -0,0 +1,38 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package ratelimit + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCheckTraceEndpointScheme(t *testing.T) { + cases := []struct { + caseName string + actualURL string + expectedURL string + }{ + { + caseName: "normal url with http prefix", + actualURL: "http://collector.observability.svc.cluster.local:4318", + expectedURL: "http://collector.observability.svc.cluster.local:4318", + }, + { + caseName: "abnormal url without http prefix", + actualURL: "collector.observability.svc.cluster.local:4318", + expectedURL: "http://collector.observability.svc.cluster.local:4318", + }, + } + + for _, tc := range cases { + t.Run(tc.caseName, func(t *testing.T) { + actual := checkTraceEndpointScheme(tc.actualURL) + require.Equal(t, tc.expectedURL, actual) + }) + } +} diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml new file mode 100644 index 00000000000..b4c7d9472e9 --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml @@ -0,0 +1,160 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + name: envoy-ratelimit + namespace: envoy-gateway-system + ownerReferences: + - apiVersion: apps/v1 + kind: Deployment + name: envoy-gateway + uid: test-owner-reference-uid-for-deployment +spec: + progressDeadlineSeconds: 600 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + strategy: + type: RollingUpdate + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + spec: + automountServiceAccountToken: false + containers: + - command: + - /bin/ratelimit + env: + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + - name: CONFIG_TYPE + value: GRPC_XDS_SOTW + - name: CONFIG_GRPC_XDS_SERVER_URL + value: envoy-gateway:18001 + - name: CONFIG_GRPC_XDS_NODE_ID + value: envoy-ratelimit + - name: GRPC_SERVER_USE_TLS + value: "true" + - name: GRPC_SERVER_TLS_CERT + value: /certs/tls.crt + - name: GRPC_SERVER_TLS_KEY + value: /certs/tls.key + - name: GRPC_SERVER_TLS_CA_CERT + value: /certs/ca.crt + - name: CONFIG_GRPC_XDS_SERVER_USE_TLS + value: "true" + - name: CONFIG_GRPC_XDS_CLIENT_TLS_CERT + value: /certs/tls.crt + - name: CONFIG_GRPC_XDS_CLIENT_TLS_KEY + value: /certs/tls.key + - name: CONFIG_GRPC_XDS_SERVER_TLS_CACERT + value: /certs/ca.crt + - name: FORCE_START_WITHOUT_INITIAL_CONFIG + value: "true" + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: TRACING_ENABLED + value: "true" + - name: TRACING_SERVICE_NAME + value: envoy-ratelimit + - name: TRACING_SERVICE_NAMESPACE + value: envoy-gateway-system + - name: TRACING_SERVICE_INSTANCE_ID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: TRACING_SAMPLING_RATE + value: "0.6" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4317 + image: envoyproxy/ratelimit:master + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: grpc + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 8080 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - command: + - /bin/statsd_exporter + - --web.listen-address=:19001 + - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml + image: prom/statsd-exporter:v0.18.0 + imagePullPolicy: IfNotPresent + name: prom-statsd-exporter + ports: + - containerPort: 9125 + name: statsd + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/statsd-exporter + name: statsd-exporter-config + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-ratelimit + terminationGracePeriodSeconds: 300 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy-rate-limit + - configMap: + defaultMode: 420 + name: statsd-exporter-config + optional: true + name: statsd-exporter-config +status: {} diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml new file mode 100644 index 00000000000..e36ff5ef87d --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml @@ -0,0 +1,160 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + name: envoy-ratelimit + namespace: envoy-gateway-system + ownerReferences: + - apiVersion: apps/v1 + kind: Deployment + name: envoy-gateway + uid: test-owner-reference-uid-for-deployment +spec: + progressDeadlineSeconds: 600 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + strategy: + type: RollingUpdate + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "19001" + prometheus.io/scrape: "true" + creationTimestamp: null + labels: + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + app.kubernetes.io/name: envoy-ratelimit + spec: + automountServiceAccountToken: false + containers: + - command: + - /bin/ratelimit + env: + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + - name: CONFIG_TYPE + value: GRPC_XDS_SOTW + - name: CONFIG_GRPC_XDS_SERVER_URL + value: envoy-gateway:18001 + - name: CONFIG_GRPC_XDS_NODE_ID + value: envoy-ratelimit + - name: GRPC_SERVER_USE_TLS + value: "true" + - name: GRPC_SERVER_TLS_CERT + value: /certs/tls.crt + - name: GRPC_SERVER_TLS_KEY + value: /certs/tls.key + - name: GRPC_SERVER_TLS_CA_CERT + value: /certs/ca.crt + - name: CONFIG_GRPC_XDS_SERVER_USE_TLS + value: "true" + - name: CONFIG_GRPC_XDS_CLIENT_TLS_CERT + value: /certs/tls.crt + - name: CONFIG_GRPC_XDS_CLIENT_TLS_KEY + value: /certs/tls.key + - name: CONFIG_GRPC_XDS_SERVER_TLS_CACERT + value: /certs/ca.crt + - name: FORCE_START_WITHOUT_INITIAL_CONFIG + value: "true" + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: TRACING_ENABLED + value: "true" + - name: TRACING_SERVICE_NAME + value: envoy-ratelimit + - name: TRACING_SERVICE_NAMESPACE + value: envoy-gateway-system + - name: TRACING_SERVICE_INSTANCE_ID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: TRACING_SAMPLING_RATE + value: "1.0" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4318 + image: envoyproxy/ratelimit:master + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: grpc + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthcheck + port: 8080 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + - command: + - /bin/statsd_exporter + - --web.listen-address=:19001 + - --statsd.mapping-config=/etc/statsd-exporter/conf.yaml + image: prom/statsd-exporter:v0.18.0 + imagePullPolicy: IfNotPresent + name: prom-statsd-exporter + ports: + - containerPort: 9125 + name: statsd + protocol: TCP + - containerPort: 19001 + name: metrics + protocol: TCP + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/statsd-exporter + name: statsd-exporter-config + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-ratelimit + terminationGracePeriodSeconds: 300 + volumes: + - name: certs + secret: + defaultMode: 420 + secretName: envoy-rate-limit + - configMap: + defaultMode: 420 + name: statsd-exporter-config + optional: true + name: statsd-exporter-config +status: {} diff --git a/internal/infrastructure/kubernetes/resource/resource.go b/internal/infrastructure/kubernetes/resource/resource.go index bec8257071d..cff49336c71 100644 --- a/internal/infrastructure/kubernetes/resource/resource.go +++ b/internal/infrastructure/kubernetes/resource/resource.go @@ -37,6 +37,9 @@ func ExpectedServiceSpec(service *egv1a1.KubernetesServiceSpec) corev1.ServiceSp if service.AllocateLoadBalancerNodePorts != nil { serviceSpec.AllocateLoadBalancerNodePorts = service.AllocateLoadBalancerNodePorts } + if service.LoadBalancerSourceRanges != nil && len(service.LoadBalancerSourceRanges) > 0 { + serviceSpec.LoadBalancerSourceRanges = service.LoadBalancerSourceRanges + } if service.LoadBalancerIP != nil { serviceSpec.LoadBalancerIP = *service.LoadBalancerIP } @@ -73,8 +76,8 @@ func ExpectedContainerEnv(container *egv1a1.KubernetesContainerSpec, env []corev return env } -// ExpectedDeploymentVolumes returns expected deployment volumes. -func ExpectedDeploymentVolumes(pod *egv1a1.KubernetesPodSpec, volumes []corev1.Volume) []corev1.Volume { +// ExpectedVolumes returns expected deployment volumes. +func ExpectedVolumes(pod *egv1a1.KubernetesPodSpec, volumes []corev1.Volume) []corev1.Volume { amendFunc := func(volume corev1.Volume) { for index, e := range volumes { if e.Name == volume.Name { diff --git a/internal/infrastructure/kubernetes/resource/resource_test.go b/internal/infrastructure/kubernetes/resource/resource_test.go index 9eb71ce4ced..b65549911c7 100644 --- a/internal/infrastructure/kubernetes/resource/resource_test.go +++ b/internal/infrastructure/kubernetes/resource/resource_test.go @@ -77,6 +77,19 @@ func TestExpectedServiceSpec(t *testing.T) { ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal, }, }, + { + name: "LoadBalancerWithLoadBalancerSourceRanges", + args: args{service: &egv1a1.KubernetesServiceSpec{ + Type: egv1a1.GetKubernetesServiceType(egv1a1.ServiceTypeLoadBalancer), + LoadBalancerSourceRanges: []string{"1.1.1.1/32"}, + }}, + want: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + LoadBalancerSourceRanges: []string{"1.1.1.1/32"}, + SessionAffinity: corev1.ServiceAffinityNone, + ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal, + }, + }, { name: "LoadBalancerWithLoadBalancerIP", args: args{service: &egv1a1.KubernetesServiceSpec{ @@ -200,7 +213,8 @@ func TestCompareSvc(t *testing.T) { Type: "NodePort", }, }, - }, { + }, + { // Only Spec.Ports[*].Port is different ExpectRet: false, NewSvc: &corev1.Service{ @@ -285,7 +299,8 @@ func TestCompareSvc(t *testing.T) { Type: "ClusterIP", }, }, - }, { + }, + { // Finalizers field differs ExpectRet: true, NewSvc: &corev1.Service{ @@ -474,7 +489,7 @@ func TestExpectedDeploymentVolumes(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, ExpectedDeploymentVolumes(tt.args.pod, tt.args.volumes), "ExpectedDeploymentVolumes(%v, %v)", tt.args.pod, tt.args.volumes) + assert.Equalf(t, tt.want, ExpectedVolumes(tt.args.pod, tt.args.volumes), "ExpectedVolumes(%v, %v)", tt.args.pod, tt.args.volumes) }) } } diff --git a/internal/infrastructure/runner/runner.go b/internal/infrastructure/runner/runner.go index 8da18e46443..d9376eb8499 100644 --- a/internal/infrastructure/runner/runner.go +++ b/internal/infrastructure/runner/runner.go @@ -44,7 +44,7 @@ func (r *Runner) Start(ctx context.Context) (err error) { return err } - var initInfra = func() { + initInfra := func() { go r.subscribeToProxyInfraIR(ctx) // Enable global ratelimit if it has been configured. diff --git a/internal/ir/xds.go b/internal/ir/xds.go index abe5d59b6b9..337720f7fb0 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -180,12 +180,8 @@ func (x Xds) Printable() *Xds { for _, route := range listener.Routes { // Omit field - if route.OIDC != nil { - route.OIDC.ClientSecret = redacted - route.OIDC.HMACSecret = redacted - } - if route.BasicAuth != nil { - route.BasicAuth.Users = redacted + if route.Security != nil { + route.Security = route.Security.Printable() } } } @@ -221,14 +217,17 @@ type HTTPListener struct { EnableProxyProtocol bool `json:"enableProxyProtocol,omitempty" yaml:"enableProxyProtocol,omitempty"` // ClientIPDetection controls how the original client IP address is determined for requests. ClientIPDetection *ClientIPDetectionSettings `json:"clientIPDetection,omitempty" yaml:"clientIPDetection,omitempty"` - // HTTP3 provides HTTP/3 configuration on the listener. - // +optional - HTTP3 *HTTP3Settings `json:"http3,omitempty"` // Path contains settings for path URI manipulations Path PathSettings `json:"path,omitempty"` // HTTP1 provides HTTP/1 configuration on the listener // +optional HTTP1 *HTTP1Settings `json:"http1,omitempty" yaml:"http1,omitempty"` + // HTTP2 provides HTTP/2 configuration on the listener + // +optional + HTTP2 *HTTP2Settings `json:"http2,omitempty" yaml:"http2,omitempty"` + // HTTP3 provides HTTP/3 configuration on the listener. + // +optional + HTTP3 *HTTP3Settings `json:"http3,omitempty"` // ClientTimeout sets the timeout configuration for downstream connections Timeout *ClientTimeout `json:"timeout,omitempty" yaml:"clientTimeout,omitempty"` // Connection settings @@ -285,6 +284,8 @@ type TLSConfig struct { Certificates []TLSCertificate `json:"certificates,omitempty" yaml:"certificates,omitempty"` // CACertificate to verify the client CACertificate *TLSCACertificate `json:"caCertificate,omitempty" yaml:"caCertificate,omitempty"` + // RequireClientCertificate to enforce client certificate + RequireClientCertificate bool `json:"requireClientCertificate,omitempty" yaml:"requireClientCertificate,omitempty"` // MinVersion defines the minimal version of the TLS protocol supported by this listener. MinVersion *TLSVersion `json:"minVersion,omitempty" yaml:"version,omitempty"` // MaxVersion defines the maximal version of the TLS protocol supported by this listener. @@ -396,6 +397,17 @@ type HTTP10Settings struct { DefaultHost *string `json:"defaultHost,omitempty" yaml:"defaultHost,omitempty"` } +// HTTP2Settings provides HTTP/2 configuration on the listener. +// +k8s:deepcopy-gen=true +type HTTP2Settings struct { + // InitialStreamWindowSize is the initial window size for a stream. + InitialStreamWindowSize *uint32 `json:"initialConnectionWindowSize,omitempty" yaml:"initialConnectionWindowSize,omitempty"` + // InitialConnectionWindowSize is the initial window size for a connection. + InitialConnectionWindowSize *uint32 `json:"initialStreamWindowSize,omitempty" yaml:"initialStreamWindowSize,omitempty"` + // MaxConcurrentStreams is the maximum number of concurrent streams that can be opened on a connection. + MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty" yaml:"maxConcurrentStreams,omitempty"` +} + // HeaderSettings provides configuration related to header processing on the listener. // +k8s:deepcopy-gen=true type HeaderSettings struct { @@ -467,18 +479,8 @@ type HTTPRoute struct { RateLimit *RateLimit `json:"rateLimit,omitempty" yaml:"rateLimit,omitempty"` // load balancer policy to use when routing to the backend endpoints. LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` - // CORS policy for the route. - CORS *CORS `json:"cors,omitempty" yaml:"cors,omitempty"` - // JWT defines the schema for authenticating HTTP requests using JSON Web Tokens (JWT). - JWT *JWT `json:"jwt,omitempty" yaml:"jwt,omitempty"` - // OIDC defines the schema for authenticating HTTP requests using OpenID Connect (OIDC). - OIDC *OIDC `json:"oidc,omitempty" yaml:"oidc,omitempty"` // Proxy Protocol Settings ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty"` - // BasicAuth defines the schema for the HTTP Basic Authentication. - BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` - // ExtAuth defines the schema for the external authorization. - ExtAuth *ExtAuth `json:"extAuth,omitempty" yaml:"extAuth,omitempty"` // HealthCheck defines the configuration for health checking on the upstream. HealthCheck *HealthCheck `json:"healthCheck,omitempty" yaml:"healthCheck,omitempty"` // FaultInjection defines the schema for injecting faults into HTTP requests. @@ -495,6 +497,65 @@ type HTTPRoute struct { Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` // External Processing extensions ExtProcs []ExtProc `json:"extProc,omitempty" yaml:"extProc,omitempty"` + // Wasm extensions + Wasms []Wasm `json:"wasm,omitempty" yaml:"wasm,omitempty"` + + // Security holds the features associated with SecurityPolicy + Security *SecurityFeatures `json:"security,omitempty" yaml:"security,omitempty"` + // UseClientProtocol enables using the same protocol upstream that was used downstream + UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"` +} + +// SecurityFeatures holds the information associated with the Security Policy. +// +k8s:deepcopy-gen=true +type SecurityFeatures struct { + // CORS policy for the route. + CORS *CORS `json:"cors,omitempty" yaml:"cors,omitempty"` + // JWT defines the schema for authenticating HTTP requests using JSON Web Tokens (JWT). + JWT *JWT `json:"jwt,omitempty" yaml:"jwt,omitempty"` + // OIDC defines the schema for authenticating HTTP requests using OpenID Connect (OIDC). + OIDC *OIDC `json:"oidc,omitempty" yaml:"oidc,omitempty"` + // BasicAuth defines the schema for the HTTP Basic Authentication. + BasicAuth *BasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth,omitempty"` + // ExtAuth defines the schema for the external authorization. + ExtAuth *ExtAuth `json:"extAuth,omitempty" yaml:"extAuth,omitempty"` +} + +// Empty returns true if all the features are not set. +func (s *SecurityFeatures) Empty() bool { + if s == nil { + return true + } + + return s.CORS == nil && + s.JWT == nil && + s.OIDC == nil && + s.BasicAuth == nil && + s.ExtAuth == nil +} + +func (s *SecurityFeatures) Printable() *SecurityFeatures { + out := s.DeepCopy() + if out.OIDC != nil { + out.OIDC.ClientSecret = redacted + out.OIDC.HMACSecret = redacted + } + if out.BasicAuth != nil { + out.BasicAuth.Users = redacted + } + return out +} + +func (s *SecurityFeatures) Validate() error { + var errs error + + if s.JWT != nil { + if err := s.JWT.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + + return errs } // UnstructuredRef holds unstructured data for an arbitrary k8s resource introduced by an extension @@ -529,6 +590,10 @@ type CORS struct { // // +k8s:deepcopy-gen=true type JWT struct { + // AllowMissing determines whether a missing JWT is acceptable. + // + AllowMissing bool `json:"allowMissing,omitempty" yaml:"allowMissing,omitempty"` + // Providers defines a list of JSON Web Token (JWT) authentication providers. Providers []egv1a1.JWTProvider `json:"providers,omitempty" yaml:"providers,omitempty"` } @@ -810,8 +875,8 @@ func (h HTTPRoute) Validate() error { errs = errors.Join(errs, err) } } - if h.JWT != nil { - if err := h.JWT.validate(); err != nil { + if h.Security != nil { + if err := h.Security.Validate(); err != nil { errs = errors.Join(errs, err) } } @@ -824,7 +889,7 @@ func (h HTTPRoute) Validate() error { return errs } -func (j *JWT) validate() error { +func (j *JWT) Validate() error { var errs error if err := egv1a1validation.ValidateJWTProvider(j.Providers); err != nil { @@ -1380,15 +1445,18 @@ type JSONPatchOperation struct { // Tracing defines the configuration for tracing a Envoy xDS Resource // +k8s:deepcopy-gen=true type Tracing struct { - ServiceName string `json:"serviceName"` - - egv1a1.ProxyTracing + ServiceName string `json:"serviceName"` + Host string `json:"host"` + Port uint32 `json:"port"` + SamplingRate float64 `json:"samplingRate,omitempty"` + CustomTags map[string]egv1a1.CustomTag `json:"customTags,omitempty"` } // Metrics defines the configuration for metrics generated by Envoy // +k8s:deepcopy-gen=true type Metrics struct { EnableVirtualHostStats bool `json:"enableVirtualHostStats" yaml:"enableVirtualHostStats"` + EnablePerEndpointStats bool `json:"enablePerEndpointStats" yaml:"enablePerEndpointStats"` } // TCPKeepalive define the TCP Keepalive configuration. @@ -1817,12 +1885,12 @@ type TLSUpstreamConfig struct { SNI string `json:"sni,omitempty" yaml:"sni,omitempty"` UseSystemTrustStore bool `json:"useSystemTrustStore,omitempty" yaml:"useSystemTrustStore,omitempty"` CACertificate *TLSCACertificate `json:"caCertificate,omitempty" yaml:"caCertificate,omitempty"` + TLSConfig `json:",inline"` } // Connection settings for downstream connections // +k8s:deepcopy-gen=true type Connection struct { - // // ConnectionLimit is the limit of number of connections ConnectionLimit *ConnectionLimit `json:"limit,omitempty" yaml:"limit,omitempty"` // BufferLimitBytes is the maximum number of bytes that can be buffered for a connection. @@ -1841,6 +1909,17 @@ type ConnectionLimit struct { CloseDelay *metav1.Duration `json:"closeDelay,omitempty" yaml:"closeDelay,omitempty"` } +type ExtProcBodyProcessingMode egv1a1.ExtProcBodyProcessingMode + +const ( + // ExtProcBodyStreamed sets the streamed body processing mode + ExtProcBodyStreamed = ExtProcBodyProcessingMode(egv1a1.StreamedExtProcBodyProcessingMode) + // ExtProcBodyBuffered sets the buffered body processing mode + ExtProcBodyBuffered = ExtProcBodyProcessingMode(egv1a1.BufferedExtProcBodyProcessingMode) + // ExtProcBodyBufferedPartial sets the partial buffered body processing mode + ExtProcBodyBufferedPartial = ExtProcBodyProcessingMode(egv1a1.BufferedPartialExtBodyHeaderProcessingMode) +) + // ExtProc holds the information associated with the ExtProc extensions. // +k8s:deepcopy-gen=true type ExtProc struct { @@ -1849,8 +1928,65 @@ type ExtProc struct { Name string `json:"name" yaml:"name"` // Destination defines the destination for the gRPC External Processing service. - Destination RouteDestination `json:"destination"` + Destination RouteDestination `json:"destination" yaml:"destination"` // Authority is the hostname:port of the HTTP External Processing service. - Authority string `json:"authority"` + Authority string `json:"authority" yaml:"authority"` + + // MessageTimeout is the timeout for a response to be returned from the external processor + MessageTimeout *metav1.Duration `json:"messageTimeout,omitempty" yaml:"messageTimeout,omitempty"` + + // FailOpen defines if requests or responses that cannot be processed due to connectivity to the + // external processor are terminated or passed-through. + FailOpen *bool `json:"failOpen,omitempty" yaml:"failOpen,omitempty"` + + // RequestHeaderProcessing Defines if request headers are processed + RequestHeaderProcessing bool `json:"requestHeaderProcessing,omitempty" yaml:"requestHeaderProcessing,omitempty"` + + // RequestBodyProcessingMode Defines request body processing + RequestBodyProcessingMode *ExtProcBodyProcessingMode `json:"requestBodyProcessingMode,omitempty" yaml:"requestBodyProcessingMode,omitempty"` + + // ResponseHeaderProcessingMode Defines if response headers are processed + ResponseHeaderProcessing bool `json:"responseHeaderProcessing,omitempty" yaml:"responseHeaderProcessing,omitempty"` + + // ResponseBodyProcessingMode Defines response body processing + ResponseBodyProcessingMode *ExtProcBodyProcessingMode `json:"responseBodyProcessingMode,omitempty" yaml:"responseBodyProcessingMode,omitempty"` +} + +// Wasm holds the information associated with the Wasm extensions. +// +k8s:deepcopy-gen=true +type Wasm struct { + // Name is a unique name for an Wasm configuration. + // The xds translator only generates one ExtProc filter for each unique name. + Name string `json:"name"` + + // RootID is a unique ID for a set of extensions in a VM which will share a + // RootContext and Contexts if applicable (e.g., an Wasm HttpFilter and an Wasm AccessLog). + // If left blank, all extensions with a blank root_id with the same vm_id will share Context(s). + RootID *string `json:"rootID,omitempty"` + + // WasmName is used to identify the Wasm extension if multiple extensions are + // handled by the same vm_id and root_id. + // It's also used for logging/debugging. + WasmName string `json:"wasmName"` + + // Config is the configuration for the Wasm extension. + // This configuration will be passed as a JSON string to the Wasm extension. + Config *apiextensionsv1.JSON `json:"config"` + + // FailOpen is a switch used to control the behavior when a fatal error occurs + // during the initialization or the execution of the Wasm extension. + FailOpen bool `json:"failOpen"` + + // HTTPWasmCode is the HTTP Wasm code source. + HTTPWasmCode *HTTPWasmCode `json:"httpWasmCode,omitempty"` +} + +// HTTPWasmCode holds the information associated with the HTTP Wasm code source. +type HTTPWasmCode struct { + // URL is the URL of the Wasm code. + URL string `json:"url"` + + // SHA256 checksum that will be used to verify the wasm code. + SHA256 string `json:"sha256"` } diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go index 2f4d9a46a33..30c07a70001 100644 --- a/internal/ir/xds_test.go +++ b/internal/ir/xds_test.go @@ -35,11 +35,11 @@ var ( Hostnames: []string{"example.com"}, TLS: &TLSConfig{ Certificates: []TLSCertificate{{ - Name: "happy", ServerCertificate: []byte{1, 2, 3}, PrivateKey: []byte{1, 2, 3}, - }}}, + }}, + }, Routes: []*HTTPRoute{&happyHTTPRoute}, } redactedHappyHTTPSListener = HTTPListener{ @@ -49,11 +49,11 @@ var ( Hostnames: []string{"example.com"}, TLS: &TLSConfig{ Certificates: []TLSCertificate{{ - Name: "happy", ServerCertificate: []byte{1, 2, 3}, PrivateKey: redacted, - }}}, + }}, + }, Routes: []*HTTPRoute{&happyHTTPRoute}, } invalidAddrHTTPListener = HTTPListener{ @@ -96,7 +96,8 @@ var ( Name: "happy", ServerCertificate: []byte("server-cert"), PrivateKey: []byte("priv-key"), - }}}}, + }}, + }}, Destination: &happyRouteDestination, } @@ -446,12 +447,14 @@ var ( PathMatch: &StringMatch{ Exact: ptr.To("jwtauthen"), }, - JWT: &JWT{ - Providers: []egv1a1.JWTProvider{ - { - Name: "test1", - RemoteJWKS: egv1a1.RemoteJWKS{ - URI: "https://test1.local", + Security: &SecurityFeatures{ + JWT: &JWT{ + Providers: []egv1a1.JWTProvider{ + { + Name: "test1", + RemoteJWKS: egv1a1.RemoteJWKS{ + URI: "https://test1.local", + }, }, }, }, @@ -656,7 +659,8 @@ func TestValidateTLSListenerConfig(t *testing.T) { Certificates: []TLSCertificate{{ ServerCertificate: []byte("server-cert"), PrivateKey: []byte("priv-key"), - }}}, + }}, + }, want: nil, }, { @@ -664,7 +668,8 @@ func TestValidateTLSListenerConfig(t *testing.T) { input: TLSConfig{ Certificates: []TLSCertificate{{ PrivateKey: []byte("priv-key"), - }}}, + }}, + }, want: ErrTLSServerCertEmpty, }, { @@ -672,7 +677,8 @@ func TestValidateTLSListenerConfig(t *testing.T) { input: TLSConfig{ Certificates: []TLSCertificate{{ ServerCertificate: []byte("server-cert"), - }}}, + }}, + }, want: ErrTLSPrivateKey, }, } @@ -1153,9 +1159,9 @@ func TestValidateJWT(t *testing.T) { test := tests[i] t.Run(test.name, func(t *testing.T) { if test.want == nil { - require.NoError(t, test.input.validate()) + require.NoError(t, test.input.Validate()) } else { - require.EqualError(t, test.input.validate(), test.want.Error()) + require.EqualError(t, test.input.Validate(), test.want.Error()) } }) } @@ -1251,231 +1257,244 @@ func TestValidateHealthCheck(t *testing.T) { }{ { name: "invalid timeout", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Duration(0)}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To[uint32](3), - HealthyThreshold: ptr.To[uint32](3), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - ExpectedStatuses: []HTTPStatus{200, 400}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Duration(0)}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To[uint32](3), + HealthyThreshold: ptr.To[uint32](3), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + ExpectedStatuses: []HTTPStatus{200, 400}, + }, }, - }, &OutlierDetection{}, }, want: ErrHealthCheckTimeoutInvalid, }, { name: "invalid interval", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Duration(0)}, - UnhealthyThreshold: ptr.To[uint32](3), - HealthyThreshold: ptr.To[uint32](3), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - Method: ptr.To(http.MethodGet), - ExpectedStatuses: []HTTPStatus{200, 400}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Duration(0)}, + UnhealthyThreshold: ptr.To[uint32](3), + HealthyThreshold: ptr.To[uint32](3), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + Method: ptr.To(http.MethodGet), + ExpectedStatuses: []HTTPStatus{200, 400}, + }, }, - }, &OutlierDetection{}, }, want: ErrHealthCheckIntervalInvalid, }, { name: "invalid unhealthy threshold", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To[uint32](0), - HealthyThreshold: ptr.To[uint32](3), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - Method: ptr.To(http.MethodPatch), - ExpectedStatuses: []HTTPStatus{200, 400}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To[uint32](0), + HealthyThreshold: ptr.To[uint32](3), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + Method: ptr.To(http.MethodPatch), + ExpectedStatuses: []HTTPStatus{200, 400}, + }, }, - }, &OutlierDetection{}, }, want: ErrHealthCheckUnhealthyThresholdInvalid, }, { name: "invalid healthy threshold", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To[uint32](3), - HealthyThreshold: ptr.To[uint32](0), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - Method: ptr.To(http.MethodPost), - ExpectedStatuses: []HTTPStatus{200, 400}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To[uint32](3), + HealthyThreshold: ptr.To[uint32](0), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + Method: ptr.To(http.MethodPost), + ExpectedStatuses: []HTTPStatus{200, 400}, + }, }, - }, &OutlierDetection{}, }, want: ErrHealthCheckHealthyThresholdInvalid, }, { name: "http-health-check: invalid host", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To[uint32](3), - HealthyThreshold: ptr.To[uint32](3), - HTTP: &HTTPHealthChecker{ - Path: "/healthz", - Method: ptr.To(http.MethodPut), - ExpectedStatuses: []HTTPStatus{200, 400}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To[uint32](3), + HealthyThreshold: ptr.To[uint32](3), + HTTP: &HTTPHealthChecker{ + Path: "/healthz", + Method: ptr.To(http.MethodPut), + ExpectedStatuses: []HTTPStatus{200, 400}, + }, }, - }, &OutlierDetection{}, }, want: ErrHCHTTPHostInvalid, }, { name: "http-health-check: invalid path", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To[uint32](3), - HealthyThreshold: ptr.To[uint32](3), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "", - Method: ptr.To(http.MethodPut), - ExpectedStatuses: []HTTPStatus{200, 400}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To[uint32](3), + HealthyThreshold: ptr.To[uint32](3), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "", + Method: ptr.To(http.MethodPut), + ExpectedStatuses: []HTTPStatus{200, 400}, + }, }, - }, &OutlierDetection{}, }, want: ErrHCHTTPPathInvalid, }, { name: "http-health-check: invalid method", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To(uint32(3)), - HealthyThreshold: ptr.To(uint32(3)), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - Method: ptr.To(http.MethodConnect), - ExpectedStatuses: []HTTPStatus{200, 400}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To(uint32(3)), + HealthyThreshold: ptr.To(uint32(3)), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + Method: ptr.To(http.MethodConnect), + ExpectedStatuses: []HTTPStatus{200, 400}, + }, }, - }, &OutlierDetection{}, }, want: ErrHCHTTPMethodInvalid, }, { name: "http-health-check: invalid expected-statuses", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To(uint32(3)), - HealthyThreshold: ptr.To(uint32(3)), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - Method: ptr.To(http.MethodDelete), - ExpectedStatuses: []HTTPStatus{}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To(uint32(3)), + HealthyThreshold: ptr.To(uint32(3)), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + Method: ptr.To(http.MethodDelete), + ExpectedStatuses: []HTTPStatus{}, + }, }, - }, &OutlierDetection{}, }, want: ErrHCHTTPExpectedStatusesInvalid, }, { name: "http-health-check: invalid range", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To(uint32(3)), - HealthyThreshold: ptr.To(uint32(3)), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - Method: ptr.To(http.MethodHead), - ExpectedStatuses: []HTTPStatus{100, 600}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To(uint32(3)), + HealthyThreshold: ptr.To(uint32(3)), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + Method: ptr.To(http.MethodHead), + ExpectedStatuses: []HTTPStatus{100, 600}, + }, }, - }, &OutlierDetection{}, }, want: ErrHTTPStatusInvalid, }, { name: "http-health-check: invalid expected-responses", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To(uint32(3)), - HealthyThreshold: ptr.To(uint32(3)), - HTTP: &HTTPHealthChecker{ - Host: "*", - Path: "/healthz", - Method: ptr.To(http.MethodOptions), - ExpectedStatuses: []HTTPStatus{200, 300}, - ExpectedResponse: &HealthCheckPayload{ - Text: ptr.To("foo"), - Binary: []byte{'f', 'o', 'o'}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To(uint32(3)), + HealthyThreshold: ptr.To(uint32(3)), + HTTP: &HTTPHealthChecker{ + Host: "*", + Path: "/healthz", + Method: ptr.To(http.MethodOptions), + ExpectedStatuses: []HTTPStatus{200, 300}, + ExpectedResponse: &HealthCheckPayload{ + Text: ptr.To("foo"), + Binary: []byte{'f', 'o', 'o'}, + }, }, }, - }, &OutlierDetection{}, }, want: ErrHealthCheckPayloadInvalid, }, { name: "tcp-health-check: invalid send payload", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To(uint32(3)), - HealthyThreshold: ptr.To(uint32(3)), - TCP: &TCPHealthChecker{ - Send: &HealthCheckPayload{ - Text: ptr.To("foo"), - Binary: []byte{'f', 'o', 'o'}, - }, - Receive: &HealthCheckPayload{ - Text: ptr.To("foo"), + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To(uint32(3)), + HealthyThreshold: ptr.To(uint32(3)), + TCP: &TCPHealthChecker{ + Send: &HealthCheckPayload{ + Text: ptr.To("foo"), + Binary: []byte{'f', 'o', 'o'}, + }, + Receive: &HealthCheckPayload{ + Text: ptr.To("foo"), + }, }, }, - }, &OutlierDetection{}, }, want: ErrHealthCheckPayloadInvalid, }, { name: "tcp-health-check: invalid receive payload", - input: HealthCheck{&ActiveHealthCheck{ - Timeout: &metav1.Duration{Duration: time.Second}, - Interval: &metav1.Duration{Duration: time.Second}, - UnhealthyThreshold: ptr.To(uint32(3)), - HealthyThreshold: ptr.To(uint32(3)), - TCP: &TCPHealthChecker{ - Send: &HealthCheckPayload{ - Text: ptr.To("foo"), - }, - Receive: &HealthCheckPayload{ - Text: ptr.To("foo"), - Binary: []byte{'f', 'o', 'o'}, + input: HealthCheck{ + &ActiveHealthCheck{ + Timeout: &metav1.Duration{Duration: time.Second}, + Interval: &metav1.Duration{Duration: time.Second}, + UnhealthyThreshold: ptr.To(uint32(3)), + HealthyThreshold: ptr.To(uint32(3)), + TCP: &TCPHealthChecker{ + Send: &HealthCheckPayload{ + Text: ptr.To("foo"), + }, + Receive: &HealthCheckPayload{ + Text: ptr.To("foo"), + Binary: []byte{'f', 'o', 'o'}, + }, }, }, - }, &OutlierDetection{}, }, want: ErrHealthCheckPayloadInvalid, }, { name: "OutlierDetection invalid interval", - input: HealthCheck{&ActiveHealthCheck{}, + input: HealthCheck{ + &ActiveHealthCheck{}, &OutlierDetection{ Interval: &metav1.Duration{Duration: time.Duration(0)}, BaseEjectionTime: &metav1.Duration{Duration: time.Second}, @@ -1485,7 +1504,8 @@ func TestValidateHealthCheck(t *testing.T) { }, { name: "OutlierDetection invalid BaseEjectionTime", - input: HealthCheck{&ActiveHealthCheck{}, + input: HealthCheck{ + &ActiveHealthCheck{}, &OutlierDetection{ Interval: &metav1.Duration{Duration: time.Second}, BaseEjectionTime: &metav1.Duration{Duration: time.Duration(0)}, diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 34d00d3eb48..5430ef9ce6b 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -532,6 +532,26 @@ func (in *ExtAuth) DeepCopy() *ExtAuth { func (in *ExtProc) DeepCopyInto(out *ExtProc) { *out = *in in.Destination.DeepCopyInto(&out.Destination) + if in.MessageTimeout != nil { + in, out := &in.MessageTimeout, &out.MessageTimeout + *out = new(v1.Duration) + **out = **in + } + if in.FailOpen != nil { + in, out := &in.FailOpen, &out.FailOpen + *out = new(bool) + **out = **in + } + if in.RequestBodyProcessingMode != nil { + in, out := &in.RequestBodyProcessingMode, &out.RequestBodyProcessingMode + *out = new(ExtProcBodyProcessingMode) + **out = **in + } + if in.ResponseBodyProcessingMode != nil { + in, out := &in.ResponseBodyProcessingMode, &out.ResponseBodyProcessingMode + *out = new(ExtProcBodyProcessingMode) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProc. @@ -706,6 +726,36 @@ func (in *HTTP1Settings) DeepCopy() *HTTP1Settings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { + *out = *in + if in.InitialStreamWindowSize != nil { + in, out := &in.InitialStreamWindowSize, &out.InitialStreamWindowSize + *out = new(uint32) + **out = **in + } + if in.InitialConnectionWindowSize != nil { + in, out := &in.InitialConnectionWindowSize, &out.InitialConnectionWindowSize + *out = new(uint32) + **out = **in + } + if in.MaxConcurrentStreams != nil { + in, out := &in.MaxConcurrentStreams, &out.MaxConcurrentStreams + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. +func (in *HTTP2Settings) DeepCopy() *HTTP2Settings { + if in == nil { + return nil + } + out := new(HTTP2Settings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPClientTimeout) DeepCopyInto(out *HTTPClientTimeout) { *out = *in @@ -821,17 +871,22 @@ func (in *HTTPListener) DeepCopyInto(out *HTTPListener) { *out = new(ClientIPDetectionSettings) (*in).DeepCopyInto(*out) } - if in.HTTP3 != nil { - in, out := &in.HTTP3, &out.HTTP3 - *out = new(HTTP3Settings) - **out = **in - } out.Path = in.Path if in.HTTP1 != nil { in, out := &in.HTTP1, &out.HTTP1 *out = new(HTTP1Settings) (*in).DeepCopyInto(*out) } + if in.HTTP2 != nil { + in, out := &in.HTTP2, &out.HTTP2 + *out = new(HTTP2Settings) + (*in).DeepCopyInto(*out) + } + if in.HTTP3 != nil { + in, out := &in.HTTP3, &out.HTTP3 + *out = new(HTTP3Settings) + **out = **in + } if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout *out = new(ClientTimeout) @@ -971,36 +1026,11 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { *out = new(LoadBalancer) (*in).DeepCopyInto(*out) } - if in.CORS != nil { - in, out := &in.CORS, &out.CORS - *out = new(CORS) - (*in).DeepCopyInto(*out) - } - if in.JWT != nil { - in, out := &in.JWT, &out.JWT - *out = new(JWT) - (*in).DeepCopyInto(*out) - } - if in.OIDC != nil { - in, out := &in.OIDC, &out.OIDC - *out = new(OIDC) - (*in).DeepCopyInto(*out) - } if in.ProxyProtocol != nil { in, out := &in.ProxyProtocol, &out.ProxyProtocol *out = new(ProxyProtocol) **out = **in } - if in.BasicAuth != nil { - in, out := &in.BasicAuth, &out.BasicAuth - *out = new(BasicAuth) - (*in).DeepCopyInto(*out) - } - if in.ExtAuth != nil { - in, out := &in.ExtAuth, &out.ExtAuth - *out = new(ExtAuth) - (*in).DeepCopyInto(*out) - } if in.HealthCheck != nil { in, out := &in.HealthCheck, &out.HealthCheck *out = new(HealthCheck) @@ -1049,6 +1079,23 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Wasms != nil { + in, out := &in.Wasms, &out.Wasms + *out = make([]Wasm, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Security != nil { + in, out := &in.Security, &out.Security + *out = new(SecurityFeatures) + (*in).DeepCopyInto(*out) + } + if in.UseClientProtocol != nil { + in, out := &in.UseClientProtocol, &out.UseClientProtocol + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRoute. @@ -1876,6 +1923,46 @@ func (in *RouteDestination) DeepCopy() *RouteDestination { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityFeatures) DeepCopyInto(out *SecurityFeatures) { + *out = *in + if in.CORS != nil { + in, out := &in.CORS, &out.CORS + *out = new(CORS) + (*in).DeepCopyInto(*out) + } + if in.JWT != nil { + in, out := &in.JWT, &out.JWT + *out = new(JWT) + (*in).DeepCopyInto(*out) + } + if in.OIDC != nil { + in, out := &in.OIDC, &out.OIDC + *out = new(OIDC) + (*in).DeepCopyInto(*out) + } + if in.BasicAuth != nil { + in, out := &in.BasicAuth, &out.BasicAuth + *out = new(BasicAuth) + (*in).DeepCopyInto(*out) + } + if in.ExtAuth != nil { + in, out := &in.ExtAuth, &out.ExtAuth + *out = new(ExtAuth) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityFeatures. +func (in *SecurityFeatures) DeepCopy() *SecurityFeatures { + if in == nil { + return nil + } + out := new(SecurityFeatures) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SlowStart) DeepCopyInto(out *SlowStart) { *out = *in @@ -2221,6 +2308,7 @@ func (in *TLSUpstreamConfig) DeepCopyInto(out *TLSUpstreamConfig) { *out = new(TLSCACertificate) (*in).DeepCopyInto(*out) } + in.TLSConfig.DeepCopyInto(&out.TLSConfig) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSUpstreamConfig. @@ -2281,7 +2369,13 @@ func (in *Timeout) DeepCopy() *Timeout { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Tracing) DeepCopyInto(out *Tracing) { *out = *in - in.ProxyTracing.DeepCopyInto(&out.ProxyTracing) + if in.CustomTags != nil { + in, out := &in.CustomTags, &out.CustomTags + *out = make(map[string]v1alpha1.CustomTag, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tracing. @@ -2368,6 +2462,36 @@ func (in *UnstructuredRef) DeepCopy() *UnstructuredRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Wasm) DeepCopyInto(out *Wasm) { + *out = *in + if in.RootID != nil { + in, out := &in.RootID, &out.RootID + *out = new(string) + **out = **in + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } + if in.HTTPWasmCode != nil { + in, out := &in.HTTPWasmCode, &out.HTTPWasmCode + *out = new(HTTPWasmCode) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Wasm. +func (in *Wasm) DeepCopy() *Wasm { + if in == nil { + return nil + } + out := new(Wasm) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Xds) DeepCopyInto(out *Xds) { *out = *in diff --git a/internal/kubernetes/port_forwarder.go b/internal/kubernetes/port_forwarder.go index ceb439d7721..176610dab3e 100644 --- a/internal/kubernetes/port_forwarder.go +++ b/internal/kubernetes/port_forwarder.go @@ -86,7 +86,6 @@ func (f *localForwarder) Start() error { readyCh = nil } - }() select { diff --git a/internal/logging/log.go b/internal/logging/log.go index 0d6d36f8f95..8f90a9c8e0a 100644 --- a/internal/logging/log.go +++ b/internal/logging/log.go @@ -34,7 +34,7 @@ func NewLogger(logging *v1alpha1.EnvoyGatewayLogging) Logger { } func FileLogger(file string, name string, level v1alpha1.LogLevel) Logger { - writer, err := os.OpenFile(file, os.O_WRONLY, 0666) + writer, err := os.OpenFile(file, os.O_WRONLY, 0o666) if err != nil { panic(err) } diff --git a/internal/message/watchutil.go b/internal/message/watchutil.go index b938f276b7d..bd7829f3cbd 100644 --- a/internal/message/watchutil.go +++ b/internal/message/watchutil.go @@ -49,7 +49,7 @@ func HandleSubscription[K comparable, V any]( subscription <-chan watchable.Snapshot[K, V], handle func(updateFunc Update[K, V], errChans chan error), ) { - //TODO: find a suitable value + // TODO: find a suitable value errChans := make(chan error, 10) go func() { for err := range errChans { diff --git a/internal/metrics/metadata.go b/internal/metrics/metadata.go index f2ab8498407..255619bbd11 100644 --- a/internal/metrics/metadata.go +++ b/internal/metrics/metadata.go @@ -94,7 +94,8 @@ func (d *store) preAddOptions() []metric.Option { metric.Stream{ Aggregation: metric.AggregationExplicitBucketHistogram{ Boundaries: store.Bounds, - }}, + }, + }, )) opts = append(opts, v) } diff --git a/internal/metrics/metrics_test.go b/internal/metrics/metrics_test.go index 560141c6266..9b1aafcd5e2 100644 --- a/internal/metrics/metrics_test.go +++ b/internal/metrics/metrics_test.go @@ -29,12 +29,9 @@ import ( semconv "go.opentelemetry.io/otel/semconv/v1.17.0" ) -var ( - overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") -) +var overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") func TestCounter(t *testing.T) { - name := "counter_metric" var writer io.ReadWriter = bytes.NewBuffer(nil) @@ -87,7 +84,6 @@ func TestCounter(t *testing.T) { } func TestGauge(t *testing.T) { - name := "gauge_metric" var writer io.ReadWriter = bytes.NewBuffer(nil) @@ -130,7 +126,6 @@ func TestGauge(t *testing.T) { } func TestHistogram(t *testing.T) { - name := "histogram_metric" var writer io.ReadWriter = bytes.NewBuffer(nil) @@ -219,7 +214,7 @@ func exporterWriter(name string, origin io.ReadWriter) (io.ReadWriter, error) { fname := fmt.Sprintf("testdata/%s.json", name) // nolint:gosec - f, err := os.OpenFile(fname, os.O_CREATE|os.O_RDWR, 0644) + f, err := os.OpenFile(fname, os.O_CREATE|os.O_RDWR, 0o644) if err != nil { return nil, err } diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 11a177c9ab8..ca3d2c1602b 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -379,7 +379,8 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour // - Secrets for OIDC and BasicAuth // - BackendRefs for ExAuth func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( - ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) { + ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, +) { // we don't return errors from this method, because we want to continue reconciling // the rest of the SecurityPolicies despite that one reference is invalid. This // allows Envoy Gateway to continue serving traffic even if some SecurityPolicies @@ -482,7 +483,6 @@ func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resour types.NamespacedName{Namespace: r.namespace, Name: oidcHMACSecretName}, &secret, ) - // We don't return an error here, because we want to continue reconciling // despite that the OIDC HMAC secret can't be found. // If the OIDC HMAC Secret is missing, the SecurityPolicy with OIDC will be @@ -555,7 +555,8 @@ func (r *gatewayAPIReconciler) processSecretRef( // processCtpConfigMapRefs adds the referenced ConfigMaps in ClientTrafficPolicies // to the resourceTree func (r *gatewayAPIReconciler) processCtpConfigMapRefs( - ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) { + ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, +) { for _, policy := range resourceTree.ClientTrafficPolicies { tls := policy.Spec.TLS @@ -739,7 +740,6 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g gtw.Namespace, gtw.Name, certRef); err != nil { - r.log.Error(err, "failed to process TLS SecretRef for gateway", "gateway", gtw, "secretRef", certRef) @@ -804,7 +804,8 @@ func (r *gatewayAPIReconciler) processEnvoyPatchPolicies(ctx context.Context, re // processClientTrafficPolicies adds ClientTrafficPolicies to the resourceTree func (r *gatewayAPIReconciler) processClientTrafficPolicies( - ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) error { + ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, +) error { clientTrafficPolicies := egv1a1.ClientTrafficPolicyList{} if err := r.client.List(ctx, &clientTrafficPolicies); err != nil { return fmt.Errorf("error listing ClientTrafficPolicies: %w", err) @@ -842,7 +843,8 @@ func (r *gatewayAPIReconciler) processBackendTrafficPolicies(ctx context.Context // processSecurityPolicies adds SecurityPolicies and their referenced resources to the resourceTree func (r *gatewayAPIReconciler) processSecurityPolicies( - ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) error { + ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, +) error { securityPolicies := egv1a1.SecurityPolicyList{} if err := r.client.List(ctx, &securityPolicies); err != nil { return fmt.Errorf("error listing SecurityPolicies: %w", err) @@ -866,7 +868,8 @@ func (r *gatewayAPIReconciler) processSecurityPolicies( // processBackendTLSPolicies adds BackendTLSPolicies and their referenced resources to the resourceTree func (r *gatewayAPIReconciler) processBackendTLSPolicies( - ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) error { + ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, +) error { backendTLSPolicies := gwapiv1a2.BackendTLSPolicyList{} if err := r.client.List(ctx, &backendTLSPolicies); err != nil { return fmt.Errorf("error listing BackendTLSPolicies: %w", err) @@ -914,9 +917,7 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M // Upon leader election, we retrigger the reconciliation process to allow the elected leader to // process status updates and infrastructure changes. This step is crucial for synchronizing resources // that may have been altered or introduced while there was no elected leader. - if err := c.Watch( - NewWatchAndReconcileSource(mgr.Elected(), &gwapiv1.GatewayClass{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass)); err != nil { + if err := c.Watch(NewWatchAndReconcileSource(mgr.Elected(), &gwapiv1.GatewayClass{}, handler.EnqueueRequestsFromMapFunc(r.enqueueClass))); err != nil { return err } @@ -934,39 +935,52 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M predicate.GenerationChangedPredicate{}, predicate.NewPredicateFuncs(r.hasMatchingController), ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1.GatewayClass{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, gc *gwapiv1.GatewayClass) []reconcile.Request { + return r.enqueueClass(ctx, gc) + }), + &predicate.TypedGenerationChangedPredicate[*gwapiv1.GatewayClass]{}, + predicate.NewTypedPredicateFuncs[*gwapiv1.GatewayClass](r.hasMatchingController))); err != nil { return err } // Only enqueue EnvoyProxy objects that match this Envoy Gateway's GatewayClass. - epPredicates := []predicate.Predicate{ - predicate.GenerationChangedPredicate{}, - predicate.ResourceVersionChangedPredicate{}, - predicate.NewPredicateFuncs(r.hasManagedClass), + epPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyProxy]{ + &predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyProxy]{}, + predicate.NewTypedPredicateFuncs[*egv1a1.EnvoyProxy](r.hasManagedClass), } if r.namespaceLabel != nil { - epPredicates = append(epPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + epPredicates = append(epPredicates, predicate.NewTypedPredicateFuncs(func(ep *egv1a1.EnvoyProxy) bool { + return r.hasMatchingNamespaceLabels(ep) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &egv1a1.EnvoyProxy{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - epPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &egv1a1.EnvoyProxy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, t *egv1a1.EnvoyProxy) []reconcile.Request { + return r.enqueueClass(ctx, t) + }), + epPredicates...)); err != nil { return err } // Watch Gateway CRUDs and reconcile affected GatewayClass. - gPredicates := []predicate.Predicate{ - predicate.GenerationChangedPredicate{}, - predicate.NewPredicateFuncs(r.validateGatewayForReconcile), + gPredicates := []predicate.TypedPredicate[*gwapiv1.Gateway]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1.Gateway]{}, + predicate.NewTypedPredicateFuncs(func(gtw *gwapiv1.Gateway) bool { + return r.validateGatewayForReconcile(gtw) + }), } if r.namespaceLabel != nil { - gPredicates = append(gPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + gPredicates = append(gPredicates, predicate.NewTypedPredicateFuncs(func(gtw *gwapiv1.Gateway) bool { + return r.hasMatchingNamespaceLabels(gtw) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1.Gateway{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - gPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1.Gateway{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, gtw *gwapiv1.Gateway) []reconcile.Request { + return r.enqueueClass(ctx, gtw) + }), + gPredicates...)); err != nil { return err } if err := addGatewayIndexers(ctx, mgr); err != nil { @@ -974,15 +988,20 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch HTTPRoute CRUDs and process affected Gateways. - httprPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + httprPredicates := []predicate.TypedPredicate[*gwapiv1.HTTPRoute]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1.HTTPRoute]{}, + } if r.namespaceLabel != nil { - httprPredicates = append(httprPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + httprPredicates = append(httprPredicates, predicate.NewTypedPredicateFuncs(func(hr *gwapiv1.HTTPRoute) bool { + return r.hasMatchingNamespaceLabels(hr) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1.HTTPRoute{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - httprPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1.HTTPRoute{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, t *gwapiv1.HTTPRoute) []reconcile.Request { + return r.enqueueClass(ctx, t) + }), + httprPredicates...)); err != nil { return err } if err := addHTTPRouteIndexers(ctx, mgr); err != nil { @@ -990,15 +1009,20 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch GRPCRoute CRUDs and process affected Gateways. - grpcrPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + grpcrPredicates := []predicate.TypedPredicate[*gwapiv1a2.GRPCRoute]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1a2.GRPCRoute]{}, + } if r.namespaceLabel != nil { - grpcrPredicates = append(grpcrPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + grpcrPredicates = append(grpcrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.GRPCRoute](func(grpc *gwapiv1a2.GRPCRoute) bool { + return r.hasMatchingNamespaceLabels(grpc) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1a2.GRPCRoute{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - grpcrPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1a2.GRPCRoute{}, + handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.GRPCRoute](func(ctx context.Context, route *gwapiv1a2.GRPCRoute) []reconcile.Request { + return r.enqueueClass(ctx, route) + }), + grpcrPredicates...)); err != nil { return err } if err := addGRPCRouteIndexers(ctx, mgr); err != nil { @@ -1006,15 +1030,20 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch TLSRoute CRUDs and process affected Gateways. - tlsrPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + tlsrPredicates := []predicate.TypedPredicate[*gwapiv1a2.TLSRoute]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TLSRoute]{}, + } if r.namespaceLabel != nil { - tlsrPredicates = append(tlsrPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + tlsrPredicates = append(tlsrPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TLSRoute](func(route *gwapiv1a2.TLSRoute) bool { + return r.hasMatchingNamespaceLabels(route) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1a2.TLSRoute{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - tlsrPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1a2.TLSRoute{}, + handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.TLSRoute](func(ctx context.Context, route *gwapiv1a2.TLSRoute) []reconcile.Request { + return r.enqueueClass(ctx, route) + }), + tlsrPredicates...)); err != nil { return err } if err := addTLSRouteIndexers(ctx, mgr); err != nil { @@ -1022,15 +1051,20 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch UDPRoute CRUDs and process affected Gateways. - udprPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + udprPredicates := []predicate.TypedPredicate[*gwapiv1a2.UDPRoute]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1a2.UDPRoute]{}, + } if r.namespaceLabel != nil { - udprPredicates = append(udprPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + udprPredicates = append(udprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.UDPRoute](func(route *gwapiv1a2.UDPRoute) bool { + return r.hasMatchingNamespaceLabels(route) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1a2.UDPRoute{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - udprPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1a2.UDPRoute{}, + handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.UDPRoute](func(ctx context.Context, route *gwapiv1a2.UDPRoute) []reconcile.Request { + return r.enqueueClass(ctx, route) + }), + udprPredicates...)); err != nil { return err } if err := addUDPRouteIndexers(ctx, mgr); err != nil { @@ -1038,15 +1072,20 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch TCPRoute CRUDs and process affected Gateways. - tcprPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + tcprPredicates := []predicate.TypedPredicate[*gwapiv1a2.TCPRoute]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1a2.TCPRoute]{}, + } if r.namespaceLabel != nil { - tcprPredicates = append(tcprPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + tcprPredicates = append(tcprPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.TCPRoute](func(route *gwapiv1a2.TCPRoute) bool { + return r.hasMatchingNamespaceLabels(route) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1a2.TCPRoute{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - tcprPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1a2.TCPRoute{}, + handler.TypedEnqueueRequestsFromMapFunc[*gwapiv1a2.TCPRoute](func(ctx context.Context, route *gwapiv1a2.TCPRoute) []reconcile.Request { + return r.enqueueClass(ctx, route) + }), + tcprPredicates...)); err != nil { return err } if err := addTCPRouteIndexers(ctx, mgr); err != nil { @@ -1054,15 +1093,22 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch Service CRUDs and process affected *Route objects. - servicePredicates := []predicate.Predicate{predicate.NewPredicateFuncs(r.validateServiceForReconcile)} + servicePredicates := []predicate.TypedPredicate[*corev1.Service]{ + predicate.NewTypedPredicateFuncs[*corev1.Service](func(svc *corev1.Service) bool { + return r.validateServiceForReconcile(svc) + }), + } if r.namespaceLabel != nil { - servicePredicates = append(servicePredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + servicePredicates = append(servicePredicates, predicate.NewTypedPredicateFuncs[*corev1.Service](func(svc *corev1.Service) bool { + return r.hasMatchingNamespaceLabels(svc) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &corev1.Service{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - servicePredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &corev1.Service{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, svc *corev1.Service) []reconcile.Request { + return r.enqueueClass(ctx, svc) + }), + servicePredicates...)); err != nil { return err } @@ -1074,91 +1120,120 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M // Watch ServiceImport CRUDs and process affected *Route objects. if serviceImportCRDExists { if err := c.Watch( - source.Kind(mgr.GetCache(), &mcsapi.ServiceImport{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - predicate.GenerationChangedPredicate{}, - predicate.NewPredicateFuncs(r.validateServiceImportForReconcile)); err != nil { + source.Kind(mgr.GetCache(), &mcsapi.ServiceImport{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, si *mcsapi.ServiceImport) []reconcile.Request { + return r.enqueueClass(ctx, si) + }), + predicate.TypedGenerationChangedPredicate[*mcsapi.ServiceImport]{}, + predicate.NewTypedPredicateFuncs[*mcsapi.ServiceImport](func(si *mcsapi.ServiceImport) bool { + return r.validateServiceImportForReconcile(si) + }))); err != nil { // ServiceImport is not available in the cluster, skip the watch and not throw error. r.log.Info("unable to watch ServiceImport: %s", err.Error()) } } // Watch EndpointSlice CRUDs and process affected *Route objects. - esPredicates := []predicate.Predicate{ - predicate.GenerationChangedPredicate{}, - predicate.NewPredicateFuncs(r.validateEndpointSliceForReconcile), + esPredicates := []predicate.TypedPredicate[*discoveryv1.EndpointSlice]{ + predicate.TypedGenerationChangedPredicate[*discoveryv1.EndpointSlice]{}, + predicate.NewTypedPredicateFuncs[*discoveryv1.EndpointSlice](func(eps *discoveryv1.EndpointSlice) bool { + return r.validateEndpointSliceForReconcile(eps) + }), } if r.namespaceLabel != nil { - esPredicates = append(esPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + esPredicates = append(esPredicates, predicate.NewTypedPredicateFuncs[*discoveryv1.EndpointSlice](func(eps *discoveryv1.EndpointSlice) bool { + return r.hasMatchingNamespaceLabels(eps) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &discoveryv1.EndpointSlice{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - esPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &discoveryv1.EndpointSlice{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, si *discoveryv1.EndpointSlice) []reconcile.Request { + return r.enqueueClass(ctx, si) + }), + esPredicates...)); err != nil { return err } // Watch Node CRUDs to update Gateway Address exposed by Service of type NodePort. // Node creation/deletion and ExternalIP updates would require update in the Gateway - nPredicates := []predicate.Predicate{ - predicate.GenerationChangedPredicate{}, - predicate.NewPredicateFuncs(r.handleNode), + nPredicates := []predicate.TypedPredicate[*corev1.Node]{ + predicate.TypedGenerationChangedPredicate[*corev1.Node]{}, + predicate.NewTypedPredicateFuncs[*corev1.Node](func(node *corev1.Node) bool { + return r.handleNode(node) + }), } if r.namespaceLabel != nil { - nPredicates = append(nPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + nPredicates = append(nPredicates, predicate.NewTypedPredicateFuncs[*corev1.Node](func(node *corev1.Node) bool { + return r.hasMatchingNamespaceLabels(node) + })) } // resource address. if err := c.Watch( - source.Kind(mgr.GetCache(), &corev1.Node{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - nPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &corev1.Node{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, si *corev1.Node) []reconcile.Request { + return r.enqueueClass(ctx, si) + }), + nPredicates...)); err != nil { return err } // Watch Secret CRUDs and process affected EG CRs (Gateway, SecurityPolicy, more in the future). - secretPredicates := []predicate.Predicate{ - predicate.GenerationChangedPredicate{}, - predicate.NewPredicateFuncs(r.validateSecretForReconcile), + secretPredicates := []predicate.TypedPredicate[*corev1.Secret]{ + predicate.TypedGenerationChangedPredicate[*corev1.Secret]{}, + predicate.NewTypedPredicateFuncs(func(s *corev1.Secret) bool { + return r.validateSecretForReconcile(s) + }), } if r.namespaceLabel != nil { - secretPredicates = append(secretPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + secretPredicates = append(secretPredicates, predicate.NewTypedPredicateFuncs(func(s *corev1.Secret) bool { + return r.hasMatchingNamespaceLabels(s) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &corev1.Secret{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - secretPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &corev1.Secret{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, s *corev1.Secret) []reconcile.Request { + return r.enqueueClass(ctx, s) + }), + secretPredicates...)); err != nil { return err } // Watch ConfigMap CRUDs and process affected ClienTraffiPolicies and BackendTLSPolicies. - configMapPredicates := []predicate.Predicate{ - predicate.GenerationChangedPredicate{}, - predicate.NewPredicateFuncs(r.validateConfigMapForReconcile), + configMapPredicates := []predicate.TypedPredicate[*corev1.ConfigMap]{ + predicate.TypedGenerationChangedPredicate[*corev1.ConfigMap]{}, + predicate.NewTypedPredicateFuncs[*corev1.ConfigMap](func(cm *corev1.ConfigMap) bool { + return r.validateConfigMapForReconcile(cm) + }), } if r.namespaceLabel != nil { - configMapPredicates = append(configMapPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + configMapPredicates = append(configMapPredicates, predicate.NewTypedPredicateFuncs[*corev1.ConfigMap](func(cm *corev1.ConfigMap) bool { + return r.hasMatchingNamespaceLabels(cm) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &corev1.ConfigMap{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - configMapPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &corev1.ConfigMap{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, cm *corev1.ConfigMap) []reconcile.Request { + return r.enqueueClass(ctx, cm) + }), + configMapPredicates...)); err != nil { return err } // Watch ReferenceGrant CRUDs and process affected Gateways. - rgPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + rgPredicates := []predicate.TypedPredicate[*gwapiv1b1.ReferenceGrant]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1b1.ReferenceGrant]{}, + } if r.namespaceLabel != nil { - rgPredicates = append(rgPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + rgPredicates = append(rgPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1b1.ReferenceGrant](func(rg *gwapiv1b1.ReferenceGrant) bool { + return r.hasMatchingNamespaceLabels(rg) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1b1.ReferenceGrant{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - rgPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1b1.ReferenceGrant{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, rg *gwapiv1b1.ReferenceGrant) []reconcile.Request { + return r.enqueueClass(ctx, rg) + }), + rgPredicates...)); err != nil { return err } if err := addReferenceGrantIndexers(ctx, mgr); err != nil { @@ -1166,45 +1241,62 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch Deployment CRUDs and process affected Gateways. - dPredicates := []predicate.Predicate{predicate.NewPredicateFuncs(r.validateDeploymentForReconcile)} + dPredicates := []predicate.TypedPredicate[*appsv1.Deployment]{ + predicate.NewTypedPredicateFuncs[*appsv1.Deployment](func(deploy *appsv1.Deployment) bool { + return r.validateDeploymentForReconcile(deploy) + }), + } if r.namespaceLabel != nil { - dPredicates = append(dPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + dPredicates = append(dPredicates, predicate.NewTypedPredicateFuncs[*appsv1.Deployment](func(deploy *appsv1.Deployment) bool { + return r.hasMatchingNamespaceLabels(deploy) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &appsv1.Deployment{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - dPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &appsv1.Deployment{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, deploy *appsv1.Deployment) []reconcile.Request { + return r.enqueueClass(ctx, deploy) + }), + dPredicates...)); err != nil { return err } - // Watch EnvoyPatchPolicy if enabled in config - eppPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} - if r.namespaceLabel != nil { - eppPredicates = append(eppPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) - } if r.envoyGateway.ExtensionAPIs != nil && r.envoyGateway.ExtensionAPIs.EnableEnvoyPatchPolicy { + // Watch EnvoyPatchPolicy if enabled in config + eppPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyPatchPolicy]{ + predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyPatchPolicy]{}, + } + if r.namespaceLabel != nil { + eppPredicates = append(eppPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.EnvoyPatchPolicy](func(epp *egv1a1.EnvoyPatchPolicy) bool { + return r.hasMatchingNamespaceLabels(epp) + })) + } // Watch EnvoyPatchPolicy CRUDs if err := c.Watch( - source.Kind(mgr.GetCache(), &egv1a1.EnvoyPatchPolicy{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - eppPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &egv1a1.EnvoyPatchPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, epp *egv1a1.EnvoyPatchPolicy) []reconcile.Request { + return r.enqueueClass(ctx, epp) + }), + eppPredicates...)); err != nil { return err } } // Watch ClientTrafficPolicy - ctpPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + ctpPredicates := []predicate.TypedPredicate[*egv1a1.ClientTrafficPolicy]{ + predicate.TypedGenerationChangedPredicate[*egv1a1.ClientTrafficPolicy]{}, + } if r.namespaceLabel != nil { - ctpPredicates = append(ctpPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + ctpPredicates = append(ctpPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.ClientTrafficPolicy](func(ctp *egv1a1.ClientTrafficPolicy) bool { + return r.hasMatchingNamespaceLabels(ctp) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &egv1a1.ClientTrafficPolicy{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - ctpPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &egv1a1.ClientTrafficPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, ctp *egv1a1.ClientTrafficPolicy) []reconcile.Request { + return r.enqueueClass(ctx, ctp) + }), + ctpPredicates...)); err != nil { return err } @@ -1213,30 +1305,40 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch BackendTrafficPolicy - btpPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + btpPredicates := []predicate.TypedPredicate[*egv1a1.BackendTrafficPolicy]{ + predicate.TypedGenerationChangedPredicate[*egv1a1.BackendTrafficPolicy]{}, + } if r.namespaceLabel != nil { - btpPredicates = append(btpPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + btpPredicates = append(btpPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.BackendTrafficPolicy](func(btp *egv1a1.BackendTrafficPolicy) bool { + return r.hasMatchingNamespaceLabels(btp) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &egv1a1.BackendTrafficPolicy{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - btpPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &egv1a1.BackendTrafficPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *egv1a1.BackendTrafficPolicy) []reconcile.Request { + return r.enqueueClass(ctx, btp) + }), + btpPredicates...)); err != nil { return err } // Watch SecurityPolicy - spPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + spPredicates := []predicate.TypedPredicate[*egv1a1.SecurityPolicy]{ + predicate.TypedGenerationChangedPredicate[*egv1a1.SecurityPolicy]{}, + } if r.namespaceLabel != nil { - spPredicates = append(spPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + spPredicates = append(spPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.SecurityPolicy](func(sp *egv1a1.SecurityPolicy) bool { + return r.hasMatchingNamespaceLabels(sp) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &egv1a1.SecurityPolicy{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - spPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &egv1a1.SecurityPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, sp *egv1a1.SecurityPolicy) []reconcile.Request { + return r.enqueueClass(ctx, sp) + }), + spPredicates...)); err != nil { return err } if err := addSecurityPolicyIndexers(ctx, mgr); err != nil { @@ -1244,16 +1346,21 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch BackendTLSPolicy - btlsPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + btlsPredicates := []predicate.TypedPredicate[*gwapiv1a2.BackendTLSPolicy]{ + predicate.TypedGenerationChangedPredicate[*gwapiv1a2.BackendTLSPolicy]{}, + } if r.namespaceLabel != nil { - btlsPredicates = append(btlsPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + btlsPredicates = append(btlsPredicates, predicate.NewTypedPredicateFuncs[*gwapiv1a2.BackendTLSPolicy](func(btp *gwapiv1a2.BackendTLSPolicy) bool { + return r.hasMatchingNamespaceLabels(btp) + })) } if err := c.Watch( - source.Kind(mgr.GetCache(), &gwapiv1a2.BackendTLSPolicy{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - btlsPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &gwapiv1a2.BackendTLSPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, btp *gwapiv1a2.BackendTLSPolicy) []reconcile.Request { + return r.enqueueClass(ctx, btp) + }), + btlsPredicates...)); err != nil { return err } @@ -1262,17 +1369,22 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M } // Watch EnvoyExtensionPolicy - eepPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + eepPredicates := []predicate.TypedPredicate[*egv1a1.EnvoyExtensionPolicy]{ + predicate.TypedGenerationChangedPredicate[*egv1a1.EnvoyExtensionPolicy]{}, + } if r.namespaceLabel != nil { - eepPredicates = append(eepPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + eepPredicates = append(eepPredicates, predicate.NewTypedPredicateFuncs[*egv1a1.EnvoyExtensionPolicy](func(eep *egv1a1.EnvoyExtensionPolicy) bool { + return r.hasMatchingNamespaceLabels(eep) + })) } // Watch EnvoyExtensionPolicy CRUDs if err := c.Watch( - source.Kind(mgr.GetCache(), &egv1a1.EnvoyExtensionPolicy{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - eepPredicates..., - ); err != nil { + source.Kind(mgr.GetCache(), &egv1a1.EnvoyExtensionPolicy{}, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, eep *egv1a1.EnvoyExtensionPolicy) []reconcile.Request { + return r.enqueueClass(ctx, eep) + }), + eepPredicates...)); err != nil { return err } if err := addEnvoyExtensionPolicyIndexers(ctx, mgr); err != nil { @@ -1282,17 +1394,22 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M r.log.Info("Watching gatewayAPI related objects") // Watch any additional GVKs from the registered extension. - uPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} + uPredicates := []predicate.TypedPredicate[*unstructured.Unstructured]{ + predicate.TypedGenerationChangedPredicate[*unstructured.Unstructured]{}, + } if r.namespaceLabel != nil { - uPredicates = append(uPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) + uPredicates = append(uPredicates, predicate.NewTypedPredicateFuncs[*unstructured.Unstructured](func(obj *unstructured.Unstructured) bool { + return r.hasMatchingNamespaceLabels(obj) + })) } for _, gvk := range r.extGVKs { u := &unstructured.Unstructured{} u.SetGroupVersionKind(gvk) - if err := c.Watch(source.Kind(mgr.GetCache(), u), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - uPredicates..., - ); err != nil { + if err := c.Watch(source.Kind(mgr.GetCache(), u, + handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, si *unstructured.Unstructured) []reconcile.Request { + return r.enqueueClass(ctx, si) + }), + uPredicates...)); err != nil { return err } r.log.Info("Watching additional resource", "resource", gvk.String()) @@ -1306,12 +1423,7 @@ func (r *gatewayAPIReconciler) enqueueClass(_ context.Context, _ client.Object) }}} } -func (r *gatewayAPIReconciler) hasManagedClass(obj client.Object) bool { - ep, ok := obj.(*egv1a1.EnvoyProxy) - if !ok { - panic(fmt.Sprintf("unsupported object type %T", obj)) - } - +func (r *gatewayAPIReconciler) hasManagedClass(ep *egv1a1.EnvoyProxy) bool { // The EnvoyProxy must be in the same namespace as EG. if ep.Namespace != r.namespace { r.log.Info("envoyproxy namespace does not match Envoy Gateway's namespace", @@ -1448,7 +1560,8 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicyConfigMapRefs(ctx context. // processEnvoyExtensionPolicies adds EnvoyExtensionPolicies and their referenced resources to the resourceTree func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies( - ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) error { + ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, +) error { envoyExtensionPolicies := egv1a1.EnvoyExtensionPolicyList{} if err := r.client.List(ctx, &envoyExtensionPolicies); err != nil { return fmt.Errorf("error listing EnvoyExtensionPolicies: %w", err) @@ -1472,7 +1585,8 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies( // to the resourceTree // - BackendRefs for ExtProcs func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( - ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings) { + ctx context.Context, resourceTree *gatewayapi.Resources, resourceMap *resourceMappings, +) { // we don't return errors from this method, because we want to continue reconciling // the rest of the EnvoyExtensionPolicies despite that one reference is invalid. This // allows Envoy Gateway to continue serving traffic even if some EnvoyExtensionPolicies @@ -1483,38 +1597,40 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( for _, policy := range resourceTree.EnvoyExtensionPolicies { // Add the referenced BackendRefs and ReferenceGrants in ExtAuth to Maps for later processing for _, ep := range policy.Spec.ExtProc { - backendRef := ep.BackendRef.BackendObjectReference - - backendNamespace := gatewayapi.NamespaceDerefOr(backendRef.Namespace, policy.Namespace) - resourceMap.allAssociatedBackendRefs[gwapiv1.BackendObjectReference{ - Group: backendRef.Group, - Kind: backendRef.Kind, - Namespace: gatewayapi.NamespacePtrV1Alpha2(backendNamespace), - Name: backendRef.Name, - }] = struct{}{} - - if backendNamespace != policy.Namespace { - from := ObjectKindNamespacedName{ - kind: gatewayapi.KindHTTPRoute, - namespace: policy.Namespace, - name: policy.Name, - } - to := ObjectKindNamespacedName{ - kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService), - namespace: backendNamespace, - name: string(backendRef.Name), - } - refGrant, err := r.findReferenceGrant(ctx, from, to) - switch { - case err != nil: - r.log.Error(err, "failed to find ReferenceGrant") - case refGrant == nil: - r.log.Info("no matching ReferenceGrants found", "from", from.kind, - "from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace) - default: - resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant) - r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace, - "name", refGrant.Name) + for _, br := range ep.BackendRefs { + backendRef := br.BackendObjectReference + + backendNamespace := gatewayapi.NamespaceDerefOr(backendRef.Namespace, policy.Namespace) + resourceMap.allAssociatedBackendRefs[gwapiv1.BackendObjectReference{ + Group: backendRef.Group, + Kind: backendRef.Kind, + Namespace: gatewayapi.NamespacePtrV1Alpha2(backendNamespace), + Name: backendRef.Name, + }] = struct{}{} + + if backendNamespace != policy.Namespace { + from := ObjectKindNamespacedName{ + kind: gatewayapi.KindHTTPRoute, + namespace: policy.Namespace, + name: policy.Name, + } + to := ObjectKindNamespacedName{ + kind: gatewayapi.KindDerefOr(backendRef.Kind, gatewayapi.KindService), + namespace: backendNamespace, + name: string(backendRef.Name), + } + refGrant, err := r.findReferenceGrant(ctx, from, to) + switch { + case err != nil: + r.log.Error(err, "failed to find ReferenceGrant") + case refGrant == nil: + r.log.Info("no matching ReferenceGrants found", "from", from.kind, + "from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace) + default: + resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant) + r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace, + "name", refGrant.Name) + } } } } diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go index 1aa58a1d533..8e3a5f9b56f 100644 --- a/internal/provider/kubernetes/controller_test.go +++ b/internal/provider/kubernetes/controller_test.go @@ -156,7 +156,7 @@ func TestHasManagedClass(t *testing.T) { testCases := []struct { name string - ep client.Object + ep *egv1a1.EnvoyProxy classes []*gwapiv1.GatewayClass expected bool }{ diff --git a/internal/provider/kubernetes/helpers.go b/internal/provider/kubernetes/helpers.go index 00029f1cb92..d3a1d972a42 100644 --- a/internal/provider/kubernetes/helpers.go +++ b/internal/provider/kubernetes/helpers.go @@ -36,8 +36,8 @@ type ObjectKindNamespacedName struct { // is a Gateway. func validateParentRefs(ctx context.Context, client client.Client, namespace string, gatewayClassController gwapiv1.GatewayController, - routeParentReferences []gwapiv1.ParentReference) ([]gwapiv1.Gateway, error) { - + routeParentReferences []gwapiv1.ParentReference, +) ([]gwapiv1.Gateway, error) { var gateways []gwapiv1.Gateway for i := range routeParentReferences { ref := routeParentReferences[i] diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go index ac1132b31d5..511802e2e38 100644 --- a/internal/provider/kubernetes/indexers.go +++ b/internal/provider/kubernetes/indexers.go @@ -38,7 +38,7 @@ const ( configMapCtpIndex = "configMapCtpIndex" secretCtpIndex = "secretCtpIndex" configMapBtlsIndex = "configMapBtlsIndex" - backendEnvoyExtensionPolicyIndex = "backendSecurityPolicyIndex" + backendEnvoyExtensionPolicyIndex = "backendEnvoyExtensionPolicyIndex" ) func addReferenceGrantIndexers(ctx context.Context, mgr manager.Manager) error { @@ -535,12 +535,14 @@ func backendEnvoyExtensionPolicyIndexFunc(rawObj client.Object) []string { var ret []string for _, ep := range envoyExtensionPolicy.Spec.ExtProc { - backendRef := ep.BackendRef.BackendObjectReference - ret = append(ret, - types.NamespacedName{ - Namespace: gatewayapi.NamespaceDerefOr(backendRef.Namespace, envoyExtensionPolicy.Namespace), - Name: string(backendRef.Name), - }.String()) + for _, br := range ep.BackendRefs { + backendRef := br.BackendObjectReference + ret = append(ret, + types.NamespacedName{ + Namespace: gatewayapi.NamespaceDerefOr(backendRef.Namespace, envoyExtensionPolicy.Namespace), + Name: string(backendRef.Name), + }.String()) + } } return ret diff --git a/internal/provider/kubernetes/kubernetes_test.go b/internal/provider/kubernetes/kubernetes_test.go index 9f19e1d0797..a877e1e4b48 100644 --- a/internal/provider/kubernetes/kubernetes_test.go +++ b/internal/provider/kubernetes/kubernetes_test.go @@ -443,7 +443,7 @@ func testHTTPRoute(ctx context.Context, t *testing.T, provider *Provider, resour rewriteHostname := gwapiv1.PreciseHostname("rewrite.hostname.local") - var testCases = []struct { + testCases := []struct { name string route gwapiv1.HTTPRoute }{ @@ -987,7 +987,7 @@ func testTLSRoute(ctx context.Context, t *testing.T, provider *Provider, resourc require.NoError(t, cli.Delete(ctx, svc)) }() - var testCases = []struct { + testCases := []struct { name string route gwapiv1a2.TLSRoute }{ @@ -1150,13 +1150,17 @@ func testServiceCleanupForMultipleRoutes(ctx context.Context, t *testing.T, prov }}, }, Hostnames: []gwapiv1a2.Hostname{"test-tls.hostname.local"}, - Rules: []gwapiv1a2.TLSRouteRule{{ - BackendRefs: []gwapiv1a2.BackendRef{{ - BackendObjectReference: gwapiv1a2.BackendObjectReference{ - Name: "test-common-svc", - Port: ptr.To(gwapiv1.PortNumber(90)), - }}, - }}, + Rules: []gwapiv1a2.TLSRouteRule{ + { + BackendRefs: []gwapiv1a2.BackendRef{ + { + BackendObjectReference: gwapiv1a2.BackendObjectReference{ + Name: "test-common-svc", + Port: ptr.To(gwapiv1.PortNumber(90)), + }, + }, + }, + }, }, }, } @@ -1586,7 +1590,6 @@ func TestNamespaceSelectorProvider(t *testing.T) { } return res != nil && len(res.GRPCRoutes) == 1 }, defaultWait, defaultTick) - } func waitUntilGatewayClassResourcesAreReady(resources *message.ProviderResources, gatewayClassName string) (*gatewayapi.Resources, bool) { diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index f25c0092326..1c0668f1a9b 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -33,13 +33,7 @@ const oidcHMACSecretName = "envoy-oidc-hmac" // hasMatchingController returns true if the provided object is a GatewayClass // with a Spec.Controller string matching this Envoy Gateway's controller string, // or false otherwise. -func (r *gatewayAPIReconciler) hasMatchingController(obj client.Object) bool { - gc, ok := obj.(*gwapiv1.GatewayClass) - if !ok { - r.log.Info("bypassing reconciliation due to unexpected object type", "type", obj) - return false - } - +func (r *gatewayAPIReconciler) hasMatchingController(gc *gwapiv1.GatewayClass) bool { if gc.Spec.ControllerName == r.classController { r.log.Info("gatewayclass has matching controller name, processing", "name", gc.Name) return true @@ -69,7 +63,6 @@ type NamespaceGetter interface { // checkObjectNamespaceLabels checks if labels of namespace of the object is a subset of namespaceLabels func (r *gatewayAPIReconciler) checkObjectNamespaceLabels(obj metav1.Object) (bool, error) { - var nsString string // TODO: it requires extra condition validate cluster resources or resources without namespace? if nsString = obj.GetNamespace(); len(nsString) == 0 { diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go index e9f24d6e51f..6f327b0c23a 100644 --- a/internal/provider/kubernetes/predicates_test.go +++ b/internal/provider/kubernetes/predicates_test.go @@ -33,18 +33,18 @@ import ( func TestGatewayClassHasMatchingController(t *testing.T) { testCases := []struct { name string - obj client.Object + gc *gwapiv1.GatewayClass client client.Client expect bool }{ { name: "matching controller name", - obj: test.GetGatewayClass("test-gc", v1alpha1.GatewayControllerName, nil), + gc: test.GetGatewayClass("test-gc", v1alpha1.GatewayControllerName, nil), expect: true, }, { name: "non-matching controller name", - obj: test.GetGatewayClass("test-gc", "not.configured/controller", nil), + gc: test.GetGatewayClass("test-gc", "not.configured/controller", nil), expect: false, }, } @@ -60,7 +60,7 @@ func TestGatewayClassHasMatchingController(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - res := r.hasMatchingController(tc.obj) + res := r.hasMatchingController(tc.gc) require.Equal(t, tc.expect, res) }) } @@ -530,9 +530,11 @@ func TestValidateServiceForReconcile(t *testing.T) { }, ExtProc: []v1alpha1.ExtProc{ { - BackendRef: v1alpha1.ExtProcBackendRef{ - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "ext-proc-service", + BackendRefs: []v1alpha1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "ext-proc-service", + }, }, }, }, @@ -559,9 +561,11 @@ func TestValidateServiceForReconcile(t *testing.T) { }, ExtProc: []v1alpha1.ExtProc{ { - BackendRef: v1alpha1.ExtProcBackendRef{ - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "ext-proc-service", + BackendRefs: []v1alpha1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "ext-proc-service", + }, }, }, }, diff --git a/internal/provider/kubernetes/routes.go b/internal/provider/kubernetes/routes.go index 20d690f574a..b1b2524e25a 100644 --- a/internal/provider/kubernetes/routes.go +++ b/internal/provider/kubernetes/routes.go @@ -23,7 +23,8 @@ import ( // processTLSRoutes finds TLSRoutes corresponding to a gatewayNamespaceName, further checks for // the backend references and pushes the TLSRoutes to the resourceTree. func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayNamespaceName string, - resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error { + resourceMap *resourceMappings, resourceTree *gatewayapi.Resources, +) error { tlsRouteList := &gwapiv1a2.TLSRouteList{} if err := r.client.List(ctx, tlsRouteList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(gatewayTLSRouteIndex, gatewayNamespaceName), @@ -93,7 +94,8 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName // processGRPCRoutes finds GRPCRoutes corresponding to a gatewayNamespaceName, further checks for // the backend references and pushes the GRPCRoutes to the resourceTree. func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNamespaceName string, - resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error { + resourceMap *resourceMappings, resourceTree *gatewayapi.Resources, +) error { grpcRouteList := &gwapiv1a2.GRPCRouteList{} if err := r.client.List(ctx, grpcRouteList, &client.ListOptions{ @@ -203,7 +205,8 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam // processHTTPRoutes finds HTTPRoutes corresponding to a gatewayNamespaceName, further checks for // the backend references and pushes the HTTPRoutes to the resourceTree. func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNamespaceName string, - resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error { + resourceMap *resourceMappings, resourceTree *gatewayapi.Resources, +) error { httpRouteList := &gwapiv1.HTTPRouteList{} extensionRefFilters, err := r.getExtensionRefFilters(ctx) @@ -376,7 +379,8 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam // processTCPRoutes finds TCPRoutes corresponding to a gatewayNamespaceName, further checks for // the backend references and pushes the TCPRoutes to the resourceTree. func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayNamespaceName string, - resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error { + resourceMap *resourceMappings, resourceTree *gatewayapi.Resources, +) error { tcpRouteList := &gwapiv1a2.TCPRouteList{} if err := r.client.List(ctx, tcpRouteList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(gatewayTCPRouteIndex, gatewayNamespaceName), @@ -446,7 +450,8 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName // processUDPRoutes finds UDPRoutes corresponding to a gatewayNamespaceName, further checks for // the backend references and pushes the UDPRoutes to the resourceTree. func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayNamespaceName string, - resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error { + resourceMap *resourceMappings, resourceTree *gatewayapi.Resources, +) error { udpRouteList := &gwapiv1a2.UDPRouteList{} if err := r.client.List(ctx, udpRouteList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(gatewayUDPRouteIndex, gatewayNamespaceName), diff --git a/internal/provider/kubernetes/secrets.go b/internal/provider/kubernetes/secrets.go index ab67f6e1608..953127e781b 100644 --- a/internal/provider/kubernetes/secrets.go +++ b/internal/provider/kubernetes/secrets.go @@ -20,9 +20,7 @@ import ( "github.com/envoyproxy/gateway/internal/utils" ) -var ( - ErrSecretExists = errors.New("skipped creating secret since it already exists") -) +var ErrSecretExists = errors.New("skipped creating secret since it already exists") // caCertificateKey is the key name for accessing TLS CA certificate bundles // in Kubernetes Secrets. diff --git a/internal/provider/kubernetes/sources.go b/internal/provider/kubernetes/sources.go index 66d93acb0d5..e19259f77ca 100644 --- a/internal/provider/kubernetes/sources.go +++ b/internal/provider/kubernetes/sources.go @@ -13,22 +13,22 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/source" ) // watchAndReconcileSource is a concrete implementation of the Source interface. type watchAndReconcileSource struct { - condition <-chan struct{} - object client.Object + condition <-chan struct{} + object client.Object + eventHandler handler.EventHandler } -func NewWatchAndReconcileSource(cond <-chan struct{}, obj client.Object) source.Source { - return &watchAndReconcileSource{condition: cond, object: obj} +func NewWatchAndReconcileSource(cond <-chan struct{}, obj client.Object, eh handler.EventHandler) source.Source { + return &watchAndReconcileSource{condition: cond, object: obj, eventHandler: eh} } // Start implements the Source interface. It registers the EventHandler with the Informer. -func (s *watchAndReconcileSource) Start(ctx context.Context, eh handler.EventHandler, queue workqueue.RateLimitingInterface, _ ...predicate.Predicate) error { +func (s *watchAndReconcileSource) Start(ctx context.Context, queue workqueue.RateLimitingInterface) error { if s.object == nil { return errors.New("object to queue is required") } @@ -39,7 +39,7 @@ func (s *watchAndReconcileSource) Start(ctx context.Context, eh handler.EventHan return case <-s.condition: // Triggers a reconcile - eh.Generic(ctx, event.GenericEvent{Object: s.object}, queue) + s.eventHandler.Generic(ctx, event.GenericEvent{Object: s.object}, queue) } }() return nil diff --git a/internal/provider/kubernetes/sources_test.go b/internal/provider/kubernetes/sources_test.go index adae9f8f854..aafc74bd2b6 100644 --- a/internal/provider/kubernetes/sources_test.go +++ b/internal/provider/kubernetes/sources_test.go @@ -59,8 +59,8 @@ func TestSources(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { cond := make(chan struct{}) - store := NewWatchAndReconcileSource(cond, tc.obj) - err := store.Start(tc.ctx, tc.handler, tc.queue) + store := NewWatchAndReconcileSource(cond, tc.obj, tc.handler) + err := store.Start(tc.ctx, tc.queue) if !tc.expected { require.Error(t, err) } else { diff --git a/internal/provider/kubernetes/status.go b/internal/provider/kubernetes/status.go index 5aa8af4fa57..33988675073 100644 --- a/internal/provider/kubernetes/status.go +++ b/internal/provider/kubernetes/status.go @@ -447,7 +447,8 @@ func (r *gatewayAPIReconciler) updateStatusForGatewayClass( gc *gwapiv1.GatewayClass, accepted bool, reason, - msg string) error { + msg string, +) error { if r.statusUpdater != nil { r.statusUpdater.Send(status.Update{ NamespacedName: types.NamespacedName{Name: gc.Name}, diff --git a/internal/status/conditions.go b/internal/status/conditions.go index 092513184bb..955dc26a7ab 100644 --- a/internal/status/conditions.go +++ b/internal/status/conditions.go @@ -34,7 +34,8 @@ const ( // computeGatewayClassAcceptedCondition computes the GatewayClass Accepted status condition. func computeGatewayClassAcceptedCondition(gatewayClass *gwapiv1.GatewayClass, accepted bool, - reason, msg string) metav1.Condition { + reason, msg string, +) metav1.Condition { switch accepted { case true: return metav1.Condition{ diff --git a/internal/status/policy.go b/internal/status/policy.go index e60b52d40db..a5c7a21a92f 100644 --- a/internal/status/policy.go +++ b/internal/status/policy.go @@ -59,15 +59,16 @@ func setAcceptedForPolicyAncestor(policyStatus *gwv1a2.PolicyStatus, ancestorRef } func SetConditionForPolicyAncestors(policyStatus *gwv1a2.PolicyStatus, ancestorRefs []gwv1a2.ParentReference, controllerName string, - conditionType gwv1a2.PolicyConditionType, status metav1.ConditionStatus, reason gwv1a2.PolicyConditionReason, message string, generation int64) { + conditionType gwv1a2.PolicyConditionType, status metav1.ConditionStatus, reason gwv1a2.PolicyConditionReason, message string, generation int64, +) { for _, ancestorRef := range ancestorRefs { SetConditionForPolicyAncestor(policyStatus, ancestorRef, controllerName, conditionType, status, reason, message, generation) } } func SetConditionForPolicyAncestor(policyStatus *gwv1a2.PolicyStatus, ancestorRef gwv1a2.ParentReference, controllerName string, - conditionType gwv1a2.PolicyConditionType, status metav1.ConditionStatus, reason gwv1a2.PolicyConditionReason, message string, generation int64) { - + conditionType gwv1a2.PolicyConditionType, status metav1.ConditionStatus, reason gwv1a2.PolicyConditionReason, message string, generation int64, +) { if policyStatus.Ancestors == nil { policyStatus.Ancestors = []gwv1a2.PolicyAncestorStatus{} } diff --git a/internal/utils/field/field_test.go b/internal/utils/field/field_test.go index fe8460973b3..8e8322d9ad3 100644 --- a/internal/utils/field/field_test.go +++ b/internal/utils/field/field_test.go @@ -19,22 +19,25 @@ func TestSetValue(t *testing.T) { fieldValue any expect any expectedErr bool - }{{ - name: "field name cannot be empty", - input: "", - expectedErr: true, - }, + }{ + { + name: "field name cannot be empty", + input: "", + expectedErr: true, + }, { name: "input cannot be a string", input: "", fieldName: "K", expectedErr: true, - }, { + }, + { name: "input cannot be a struct", input: struct{}{}, fieldName: "K", expectedErr: true, - }, { + }, + { name: "field cannot be unexported", input: &struct { name string @@ -45,7 +48,8 @@ func TestSetValue(t *testing.T) { expectedErr: true, fieldName: "name", fieldValue: "test1", - }, { + }, + { name: "simple struct set value", input: &struct { Name string @@ -56,7 +60,8 @@ func TestSetValue(t *testing.T) { expectedErr: false, fieldName: "Name", fieldValue: "test1", - }, { + }, + { name: "simple recursive struct set value", input: &struct { Name string @@ -77,7 +82,8 @@ func TestSetValue(t *testing.T) { expectedErr: false, fieldName: "Name", fieldValue: "test1", - }, { + }, + { name: "simple recursive child struct in slice set value", input: &struct { Name string @@ -100,7 +106,8 @@ func TestSetValue(t *testing.T) { expectedErr: false, fieldName: "Name", fieldValue: "test1", - }, { + }, + { name: "simple recursive child struct in map set value", input: &struct { Name string diff --git a/internal/utils/file/file.go b/internal/utils/file/file.go index fc4ce527e17..51a02571493 100644 --- a/internal/utils/file/file.go +++ b/internal/utils/file/file.go @@ -11,7 +11,7 @@ import ( ) func Write(data string, filepath string) error { - file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755) + file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644) if err != nil { return err } diff --git a/internal/utils/helm/package.go b/internal/utils/helm/package.go index 87ba6d5e444..4cbf81eff4c 100644 --- a/internal/utils/helm/package.go +++ b/internal/utils/helm/package.go @@ -50,6 +50,7 @@ type PackageOptions struct { ReleaseNamespace string OnlyCRD bool WithCRD bool + Output string } type PackageTool struct { @@ -76,7 +77,6 @@ func NewPackageTool() *PackageTool { // Setup Configuration required to initialize helm action. func (pt *PackageTool) Setup() error { - // Since envoy-gateway uses docker's oci to store charts, // we need to create a registry client to make sure we can retrieve envoy-gateway chart registryCli, err := registry.NewClient() @@ -111,7 +111,6 @@ func (pt *PackageTool) Setup() error { // SetInstallEnvSettings set the installation flags we are interested in func (pt *PackageTool) SetInstallEnvSettings(installCmd *cobra.Command, opts *PackageOptions) { - // add helm flags // we use a temporary flag to be set by helm env flags, // from which we can retrieve the flags we are interested @@ -128,7 +127,8 @@ func (pt *PackageTool) SetInstallEnvSettings(installCmd *cobra.Command, opts *Pa installCmd.Flags().DurationVar(&opts.Timeout, "timeout", helmOperateTimeout, "time to wait for any individual Kubernetes operation") installCmd.Flags().StringVar(&opts.Version, "version", egChartVersion, "specify a version constraint for the envoy gateway version to use") - installCmd.Flags().StringVar(&opts.ReleaseName, "release-name", egReleaseName, "name of the envoy-gateway release to install") + installCmd.Flags().StringVar(&opts.ReleaseName, "name", egReleaseName, "name of the envoy-gateway release to install") + installCmd.Flags().StringVarP(&opts.Output, "output", "o", "", "if set, the manifest will be output to the specified file.") installCmd.Flags().StringVarP(&opts.ReleaseNamespace, "namespace", "n", egReleaseNamespace, "if set, specify the namespace where envoy gateway is installed") installCmd.Flags().BoolVar(&opts.DryRun, "dry-run", false, "console output only, make no changes") installCmd.Flags().BoolVar(&opts.SkipCRD, "skip-crds", false, "if set, no CRDs will be installed. By default, CRDs are installed if not already present") @@ -137,25 +137,21 @@ func (pt *PackageTool) SetInstallEnvSettings(installCmd *cobra.Command, opts *Pa installCmd.Flags().StringSliceVarP(&pt.valuesOpts.ValueFiles, "values", "f", []string{}, "Specify values in a YAML file or a URL (can specify multiple)") installCmd.Flags().StringArrayVar(&pt.valuesOpts.Values, "set", []string{}, "Set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") - } // SetUninstallEnvSetting set the uninstallation flags we are interested in func (pt *PackageTool) SetUninstallEnvSetting(uninstallCmd *cobra.Command, opts *PackageOptions) { - uninstallCmd.Flags().DurationVar(&opts.Timeout, "timeout", helmOperateTimeout, "time to wait for any individual Kubernetes operation") - uninstallCmd.Flags().StringVar(&opts.ReleaseName, "release-name", egReleaseName, "name of the envoy-gateway release to uninstall") + uninstallCmd.Flags().StringVar(&opts.ReleaseName, "name", egReleaseName, "name of the envoy-gateway release to uninstall") uninstallCmd.Flags().StringVarP(&opts.ReleaseNamespace, "namespace", "n", "", "if set, specify the namespace where envoy gateway is uninstalled") uninstallCmd.Flags().BoolVar(&opts.Wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout") uninstallCmd.Flags().BoolVar(&opts.DryRun, "dry-run", false, "console output only, make no changes") uninstallCmd.Flags().BoolVar(&opts.WithCRD, "with-crds", false, "if set, the CRDs will also be removed") uninstallCmd.Flags().Bool("debug", false, "if set, the will output detailed execution logs") - } // loadChart Load the chart instance according to the chart name and version func (pt *PackageTool) loadChart(opts *PackageOptions) (*chart.Chart, error) { - pt.actionInstall.Version = opts.Version chartName, err := pt.actionInstall.LocateChart(pt.chartName, pt.envSettings) if err != nil { @@ -180,7 +176,6 @@ func (pt *PackageTool) loadChart(opts *PackageOptions) (*chart.Chart, error) { // extractCRDs Extract the CRDs part of the chart func (pt *PackageTool) extractCRDs(ch *chart.Chart) ([]*resource.Info, error) { - crdResInfo := make([]*resource.Info, 0, len(ch.CRDObjects())) for _, crd := range ch.CRDObjects() { @@ -202,7 +197,6 @@ func (pt *PackageTool) extractCRDs(ch *chart.Chart) ([]*resource.Info, error) { // This is done to avoid garbage collection on CRs in the cluster during uninstallation, // preventing the potential loss of crucial CR instances. func (pt *PackageTool) RunInstall(opts *PackageOptions) error { - if opts.Version == "v0.0.0-latest" { warningMarker := color.New(color.FgYellow).Add(color.Bold).Sprintf("WARNING") pt.logger.Println(fmt.Sprintf("%s: Currently using the latest version of envoy gateway chart, it is recommended to use the fixed version", @@ -222,7 +216,7 @@ func (pt *PackageTool) RunInstall(opts *PackageOptions) error { // Before we install CRDs, we need to ensure that CRDs do not exist in the cluster // After we install CRDs, we need to ensure that the CRDs are successfully installed into the cluster - if !opts.SkipCRD { + if !opts.SkipCRD && !opts.DryRun { if len(crdInfo) == 0 { return fmt.Errorf("CRDs not found in the envoy gateway chart") @@ -264,6 +258,18 @@ func (pt *PackageTool) RunInstall(opts *PackageOptions) error { return fmt.Errorf("failed to install envoy gateway resource: %w", err) } + if len(opts.Output) != 0 { + var outputErr error + var outputFile *os.File + + if outputFile, outputErr = os.OpenFile(opts.Output, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0o666); outputErr == nil { + _, outputErr = fmt.Fprint(outputFile, release.Manifest) + } + if outputErr != nil { + pt.logger.Println(fmt.Errorf("failed to output manifests to specified file: %w", outputErr).Error()) + } + } + if opts.DryRun { pt.logger.Println(release.Manifest) return nil @@ -276,7 +282,6 @@ func (pt *PackageTool) RunInstall(opts *PackageOptions) error { // RunUninstall By default, we only uninstall instances of the Envoy Gateway resources. func (pt *PackageTool) RunUninstall(opts *PackageOptions) error { - pt.setUninstallOptions(opts) resp, err := pt.actionUninstall.Run(opts.ReleaseName) @@ -290,7 +295,6 @@ func (pt *PackageTool) RunUninstall(opts *PackageOptions) error { } if opts.WithCRD { - if crdInfo, err := pt.extractCRDs(resp.Release.Chart); err != nil { return err } else if len(crdInfo) == 0 { @@ -298,7 +302,6 @@ func (pt *PackageTool) RunUninstall(opts *PackageOptions) error { } else if _, errors := pt.actionConfig.KubeClient.Delete(crdInfo); len(errors) != 0 { return fmt.Errorf("failed to delete CRDs error: %s", util.MultipleErrors("", errors)) } - } successMarker := color.New(color.FgGreen).Add(color.Bold).Sprintf("SUCCESS") @@ -316,7 +319,6 @@ func (pt *PackageTool) setCommonValue() { // setInstallOptions Sets the options required before install func (pt *PackageTool) setInstallOptions(opts *PackageOptions) { - if opts.DryRun { // When dry-run is set up, we do not need to connect to k8s-api server. // Since the kubernetes version needs to be higher than the value in the Helm library @@ -361,7 +363,6 @@ func (pt *PackageTool) setUninstallOptions(opts *PackageOptions) { func (pt *PackageTool) SetPreRun(cmd *cobra.Command) { existPreRunE := cmd.PreRunE cmd.PreRunE = func(cmd *cobra.Command, args []string) error { - pt.setPrinter(cmd) pt.setNamespace(cmd) @@ -412,7 +413,6 @@ func createDummyK8sVersion() *chartutil.KubeVersion { // detectExistCRDs Check if envoy-gateway and gateway-api CRDs already exist in the cluster func detectExistCRDs(crdResInfo []*resource.Info) (*bool, error) { - exist := false existObj := make([]runtime.Object, 0, len(crdResInfo)) @@ -441,7 +441,6 @@ func detectExistCRDs(crdResInfo []*resource.Info) (*bool, error) { // installCRDs Install CRDs to the cluster func installCRDs(crds []*resource.Info, actionConfig *action.Configuration) error { - // Create all CRDs in the envoy gateway chart result, err := actionConfig.KubeClient.Create(crds) if err != nil { diff --git a/internal/utils/net/backendref.go b/internal/utils/net/backendref.go new file mode 100644 index 00000000000..d5cb27ecaab --- /dev/null +++ b/internal/utils/net/backendref.go @@ -0,0 +1,25 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package net + +import ( + "fmt" + + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +func BackendHostAndPort(backendRef gwapiv1.BackendObjectReference, defaultNamespace string) (string, uint32) { + ns := defaultNamespace + if backendRef.Namespace != nil { + ns = string(*backendRef.Namespace) + } + + if ns == "" { + return string(backendRef.Name), uint32(*backendRef.Port) + } + + return fmt.Sprintf("%s.%s.svc", backendRef.Name, ns), uint32(*backendRef.Port) +} diff --git a/internal/utils/protocov/protocov.go b/internal/utils/protocov/protocov.go index 52bb952269e..6533f84c543 100644 --- a/internal/utils/protocov/protocov.go +++ b/internal/utils/protocov/protocov.go @@ -16,9 +16,7 @@ const ( APIPrefix = "type.googleapis.com/" ) -var ( - marshalOpts = proto.MarshalOptions{} -) +var marshalOpts = proto.MarshalOptions{} func ToAnyWithError(msg proto.Message) (*anypb.Any, error) { if msg == nil { diff --git a/internal/xds/bootstrap/bootstrap.go b/internal/xds/bootstrap/bootstrap.go index 4794c7374cc..68146e2ddaf 100644 --- a/internal/xds/bootstrap/bootstrap.go +++ b/internal/xds/bootstrap/bootstrap.go @@ -15,6 +15,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/utils/net" "github.com/envoyproxy/gateway/internal/utils/regex" ) @@ -62,6 +63,11 @@ type bootstrapParameters struct { ReadyServer readyServerParameters // EnablePrometheus defines whether to enable metrics endpoint for prometheus. EnablePrometheus bool + // EnablePrometheusCompression defines whether to enable HTTP compression on metrics endpoint for prometheus. + EnablePrometheusCompression bool + // PrometheusCompressionLibrary defines the HTTP compression library for metrics endpoint for prometheus. + PrometheusCompressionLibrary string + // OtelMetricSinks defines the configuration of the OpenTelemetry sinks. OtelMetricSinks []metricSink // EnableStatConfig defines whether to to customize the Envoy proxy stats. @@ -84,7 +90,7 @@ type metricSink struct { // Address is the address of the XDS Server that Envoy is managed by. Address string // Port is the port of the XDS Server that Envoy is managed by. - Port int32 + Port uint32 } type adminServerParameters struct { @@ -135,9 +141,11 @@ func (b *bootstrapConfig) render() error { // GetRenderedBootstrapConfig renders the bootstrap YAML string func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, error) { var ( - enablePrometheus = true - metricSinks []metricSink - StatsMatcher StatsMatcherParameters + enablePrometheus = true + enablePrometheusCompression = false + PrometheusCompressionLibrary = "gzip" + metricSinks []metricSink + StatsMatcher StatsMatcherParameters ) if opts != nil && opts.ProxyMetrics != nil { @@ -145,6 +153,11 @@ func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, erro if proxyMetrics.Prometheus != nil { enablePrometheus = !proxyMetrics.Prometheus.Disable + + if proxyMetrics.Prometheus.Compression != nil { + enablePrometheusCompression = true + PrometheusCompressionLibrary = string(proxyMetrics.Prometheus.Compression.Type) + } } addresses := sets.NewString() @@ -154,15 +167,23 @@ func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, erro } // skip duplicate sinks - addr := fmt.Sprintf("%s:%d", sink.OpenTelemetry.Host, sink.OpenTelemetry.Port) + var host string + var port uint32 + if sink.OpenTelemetry.Host != nil { + host, port = *sink.OpenTelemetry.Host, uint32(sink.OpenTelemetry.Port) + } + if len(sink.OpenTelemetry.BackendRefs) > 0 { + host, port = net.BackendHostAndPort(sink.OpenTelemetry.BackendRefs[0].BackendObjectReference, "") + } + addr := fmt.Sprintf("%s:%d", host, port) if addresses.Has(addr) { continue } addresses.Insert(addr) metricSinks = append(metricSinks, metricSink{ - Address: sink.OpenTelemetry.Host, - Port: sink.OpenTelemetry.Port, + Address: host, + Port: port, }) } @@ -207,8 +228,10 @@ func GetRenderedBootstrapConfig(opts *RenderBootsrapConfigOptions) (string, erro Port: EnvoyReadinessPort, ReadinessPath: EnvoyReadinessPath, }, - EnablePrometheus: enablePrometheus, - OtelMetricSinks: metricSinks, + EnablePrometheus: enablePrometheus, + EnablePrometheusCompression: enablePrometheusCompression, + PrometheusCompressionLibrary: PrometheusCompressionLibrary, + OtelMetricSinks: metricSinks, }, } if opts != nil && opts.ProxyMetrics != nil && opts.ProxyMetrics.Matches != nil { diff --git a/internal/xds/bootstrap/bootstrap.yaml.tpl b/internal/xds/bootstrap/bootstrap.yaml.tpl index 1c2a2f12edf..cc59b913862 100644 --- a/internal/xds/bootstrap/bootstrap.yaml.tpl +++ b/internal/xds/bootstrap/bootstrap.yaml.tpl @@ -86,6 +86,29 @@ static_resources: prefix: /stats/prometheus route: cluster: prometheus_stats + {{- if .EnablePrometheusCompression }} + typed_per_filter_config: + envoy.filters.http.compression: + "@type": type.googleapis.com/envoy.extensions.filters.http.compressor.v3.CompressorPerRoute + {{- if eq .PrometheusCompressionLibrary "gzip"}} + compressor_library: + name: text_optimized + typed_config: + "@type": type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip + {{- end }} + {{- if eq .PrometheusCompressionLibrary "brotli"}} + compressor_library: + name: text_optimized + typed_config: + "@type": type.googleapis.com/envoy.extensions.compression.brotli.compressor.v3.Brotli + {{- end }} + {{- if eq .PrometheusCompressionLibrary "zstd"}} + compressor_library: + name: text_optimized + typed_config: + "@type": type.googleapis.com/envoy.extensions.compression.zstd.compressor.v3.Zstd + {{- end }} + {{- end }} {{- end }} http_filters: - name: envoy.filters.http.health_check diff --git a/internal/xds/bootstrap/bootstrap_test.go b/internal/xds/bootstrap/bootstrap_test.go index 2bfa874d653..54ee52f3d4e 100644 --- a/internal/xds/bootstrap/bootstrap_test.go +++ b/internal/xds/bootstrap/bootstrap_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/utils/ptr" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" ) @@ -41,6 +42,18 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { }, }, }, + { + name: "enable-prometheus-gzip-compression", + opts: &RenderBootsrapConfigOptions{ + ProxyMetrics: &egv1a1.ProxyMetrics{ + Prometheus: &egv1a1.ProxyPrometheusProvider{ + Compression: &egv1a1.Compression{ + Type: "gzip", + }, + }, + }, + }, + }, { name: "otel-metrics", opts: &RenderBootsrapConfigOptions{ @@ -52,8 +65,36 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - Host: "otel-collector.monitoring.svc", + Host: ptr.To("otel-collector.monitoring.svc"), + Port: 4317, + }, + }, + }, + }, + }, + }, + { + name: "otel-metrics-backendref", + opts: &RenderBootsrapConfigOptions{ + ProxyMetrics: &egv1a1.ProxyMetrics{ + Prometheus: &egv1a1.ProxyPrometheusProvider{ + Disable: true, + }, + Sinks: []egv1a1.ProxyMetricSink{ + { + Type: egv1a1.MetricSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ + Host: ptr.To("otel-collector.monitoring.svc"), Port: 4317, + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "otel-collector", + Namespace: ptr.To(gwapiv1.Namespace("monitoring")), + Port: ptr.To(gwapiv1.PortNumber(4317)), + }, + }, + }, }, }, }, @@ -104,7 +145,7 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { if *overrideTestData { // nolint:gosec - err = os.WriteFile(path.Join("testdata", "render", fmt.Sprintf("%s.yaml", tc.name)), []byte(got), 0644) + err = os.WriteFile(path.Join("testdata", "render", fmt.Sprintf("%s.yaml", tc.name)), []byte(got), 0o644) require.NoError(t, err) return } diff --git a/internal/xds/bootstrap/testdata/render/enable-prometheus-gzip-compression.yaml b/internal/xds/bootstrap/testdata/render/enable-prometheus-gzip-compression.yaml new file mode 100644 index 00000000000..ca82e1996b4 --- /dev/null +++ b/internal/xds/bootstrap/testdata/render/enable-prometheus-gzip-compression.yaml @@ -0,0 +1,137 @@ +admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 +layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 +dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 +static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + virtual_hosts: + - name: prometheus_stats + domains: + - "*" + routes: + - match: + prefix: /stats/prometheus + route: + cluster: prometheus_stats + typed_per_filter_config: + envoy.filters.http.compression: + "@type": type.googleapis.com/envoy.extensions.filters.http.compressor.v3.CompressorPerRoute + compressor_library: + name: text_optimized + typed_config: + "@type": type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: prometheus_stats + connect_timeout: 0.250s + type: STATIC + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: prometheus_stats + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 +overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 diff --git a/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml b/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml new file mode 100644 index 00000000000..db865b4cb8b --- /dev/null +++ b/internal/xds/bootstrap/testdata/render/otel-metrics-backendref.yaml @@ -0,0 +1,133 @@ +admin: + access_log: + - name: envoy.access_loggers.file + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/null + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 +layered_runtime: + layers: + - name: global_config + static_layer: + envoy.restart_features.use_eds_cache_for_ads: true + re2.max_program_size.error_level: 4294967295 + re2.max_program_size.warn_level: 1000 +dynamic_resources: + ads_config: + api_type: DELTA_GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + lds_config: + ads: {} + resource_api_version: V3 + cds_config: + ads: {} + resource_api_version: V3 +stats_sinks: +- name: "envoy.stat_sinks.open_telemetry" + typed_config: + "@type": type.googleapis.com/envoy.extensions.stat_sinks.open_telemetry.v3.SinkConfig + grpc_service: + envoy_grpc: + cluster_name: otel_metric_sink_0 +static_resources: + listeners: + - name: envoy-gateway-proxy-ready-0.0.0.0-19001 + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + protocol: TCP + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: eg-ready-http + route_config: + name: local_route + http_filters: + - name: envoy.filters.http.health_check + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck + pass_through_mode: false + headers: + - name: ":path" + string_match: + exact: /ready + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: otel_metric_sink_0 + connect_timeout: 0.250s + type: STRICT_DNS + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: {} + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: otel_metric_sink_0 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: otel-collector.monitoring.svc + port_value: 4317 + - connect_timeout: 10s + load_assignment: + cluster_name: xds_cluster + endpoints: + - load_balancing_weight: 1 + lb_endpoints: + - load_balancing_weight: 1 + endpoint: + address: + socket_address: + address: envoy-gateway + port_value: 18000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions" + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 30s + timeout: 5s + name: xds_cluster + type: STRICT_DNS + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_maximum_protocol_version: TLSv1_3 + tls_certificate_sds_secret_configs: + - name: xds_certificate + sds_config: + path_config_source: + path: "/sds/xds-certificate.json" + resource_api_version: V3 + validation_context_sds_secret_config: + name: xds_trusted_ca + sds_config: + path_config_source: + path: "/sds/xds-trusted-ca.json" + resource_api_version: V3 +overload_manager: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 diff --git a/internal/xds/bootstrap/util_test.go b/internal/xds/bootstrap/util_test.go index b0d27460093..5591d0e4f53 100644 --- a/internal/xds/bootstrap/util_test.go +++ b/internal/xds/bootstrap/util_test.go @@ -18,9 +18,7 @@ import ( egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" ) -var ( - overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") -) +var overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") func TestApplyBootstrapConfig(t *testing.T) { str, _ := readTestData("enable-prometheus") @@ -56,7 +54,7 @@ func TestApplyBootstrapConfig(t *testing.T) { if *overrideTestData { // nolint:gosec - err = os.WriteFile(path.Join("testdata", "merge", fmt.Sprintf("%s.out.yaml", tc.name)), []byte(data), 0644) + err = os.WriteFile(path.Join("testdata", "merge", fmt.Sprintf("%s.out.yaml", tc.name)), []byte(data), 0o644) require.NoError(t, err) return } diff --git a/internal/xds/extensions/extensions.gen.go b/internal/xds/extensions/extensions.gen.go index 49a38500a6a..adf155d9bc9 100644 --- a/internal/xds/extensions/extensions.gen.go +++ b/internal/xds/extensions/extensions.gen.go @@ -196,12 +196,12 @@ import ( _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/early_header_mutation/header_mutation/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/header_formatters/preserve_case/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/header_validators/envoy_default/v3" + _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/injected_credentials/generic/v3" + _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/injected_credentials/oauth2/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/original_ip_detection/custom_header/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/original_ip_detection/xff/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/cookie/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/header/v3" - _ "github.com/envoyproxy/go-control-plane/envoy/extensions/injected_credentials/generic/v3" - _ "github.com/envoyproxy/go-control-plane/envoy/extensions/injected_credentials/oauth2/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/internal_redirect/allow_listed_routes/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/internal_redirect/previous_routes/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/internal_redirect/safe_cross_scheme/v3" diff --git a/internal/xds/translator/accesslog.go b/internal/xds/translator/accesslog.go index a74315a255e..9f1f17a09d9 100644 --- a/internal/xds/translator/accesslog.go +++ b/internal/xds/translator/accesslog.go @@ -48,14 +48,12 @@ const ( otelAccessLog = "envoy.access_loggers.open_telemetry" ) -var ( - // for the case when a route does not exist to upstream, hcm logs will not be present - listenerAccessLogFilter = &accesslog.AccessLogFilter{ - FilterSpecifier: &accesslog.AccessLogFilter_ResponseFlagFilter{ - ResponseFlagFilter: &accesslog.ResponseFlagFilter{Flags: []string{"NR"}}, - }, - } -) +// for the case when a route does not exist to upstream, hcm logs will not be present +var listenerAccessLogFilter = &accesslog.AccessLogFilter{ + FilterSpecifier: &accesslog.AccessLogFilter_ResponseFlagFilter{ + ResponseFlagFilter: &accesslog.ResponseFlagFilter{Flags: []string{"NR"}}, + }, +} func buildXdsAccessLog(al *ir.AccessLog, forListener bool) []*accesslog.AccessLog { if al == nil { @@ -233,7 +231,7 @@ func convertToKeyValueList(attributes map[string]string, additionalLabels bool) return keyValueList } -func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessLog) error { +func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessLog, metrics *ir.Metrics) error { if al == nil { return nil } @@ -251,6 +249,7 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL settings: []*ir.DestinationSetting{ds}, tSocket: nil, endpointType: EndpointTypeDNS, + metrics: metrics, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go index f9c88d58175..e22febfca4b 100644 --- a/internal/xds/translator/basicauth.go +++ b/internal/xds/translator/basicauth.go @@ -7,6 +7,7 @@ package translator import ( "errors" + "fmt" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" @@ -26,100 +27,85 @@ func init() { registerHTTPFilter(&basicAuth{}) } -type basicAuth struct { -} +type basicAuth struct{} var _ httpFilter = &basicAuth{} -// patchHCM builds and appends the basic_auth Filters to the HTTP Connection Manager +// patchHCM builds and appends the basic_auth Filter to the HTTP Connection Manager // if applicable, and it does not already exist. -// Note: this method creates an basic_auth filter for each route that contains an BasicAuth config. -// The filter is disabled by default. It is enabled on the route level. func (*basicAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { - var errs error - if mgr == nil { return errors.New("hcm is nil") } - if irListener == nil { return errors.New("ir listener is nil") } + if hcmContainsFilter(mgr, basicAuthFilter) { + return nil + } - for _, route := range irListener.Routes { - if !routeContainsBasicAuth(route) { - continue - } - - // Only generates one BasicAuth Envoy filter for each unique name. - // For example, if there are two routes under the same gateway with the - // same BasicAuth config, only one BasicAuth filter will be generated. - if hcmContainsFilter(mgr, basicAuthFilterName(route.BasicAuth)) { - continue - } + var ( + irBasicAuth *ir.BasicAuth + filter *hcmv3.HttpFilter + err error + ) - filter, err := buildHCMBasicAuthFilter(route.BasicAuth) - if err != nil { - errs = errors.Join(errs, err) - continue + for _, route := range irListener.Routes { + if route.Security != nil && route.Security.BasicAuth != nil { + irBasicAuth = route.Security.BasicAuth + break } - - mgr.HttpFilters = append(mgr.HttpFilters, filter) + } + if irBasicAuth == nil { + return nil } - return errs + // We use the first route that contains the basicAuth config to build the filter. + // The HCM-level filter config doesn't matter since it is overridden at the route level. + if filter, err = buildHCMBasicAuthFilter(irBasicAuth); err != nil { + return err + } + mgr.HttpFilters = append(mgr.HttpFilters, filter) + return err } // buildHCMBasicAuthFilter returns a basic_auth HTTP filter from the provided IR HTTPRoute. func buildHCMBasicAuthFilter(basicAuth *ir.BasicAuth) (*hcmv3.HttpFilter, error) { - basicAuthProto := basicAuthConfig(basicAuth) + var ( + basicAuthProto *basicauthv3.BasicAuth + basicAuthAny *anypb.Any + err error + ) - if err := basicAuthProto.ValidateAll(); err != nil { + basicAuthProto = &basicauthv3.BasicAuth{ + Users: &corev3.DataSource{ + Specifier: &corev3.DataSource_InlineBytes{ + InlineBytes: basicAuth.Users, + }, + }, + } + if err = basicAuthProto.ValidateAll(); err != nil { return nil, err } - - basicAuthAny, err := anypb.New(basicAuthProto) - if err != nil { + if basicAuthAny, err = anypb.New(basicAuthProto); err != nil { return nil, err } return &hcmv3.HttpFilter{ - Name: basicAuthFilterName(basicAuth), - Disabled: true, + Name: basicAuthFilter, ConfigType: &hcmv3.HttpFilter_TypedConfig{ TypedConfig: basicAuthAny, }, + Disabled: true, }, nil } -func basicAuthFilterName(basicAuth *ir.BasicAuth) string { - return perRouteFilterName(basicAuthFilter, basicAuth.Name) -} - -func basicAuthConfig(basicAuth *ir.BasicAuth) *basicauthv3.BasicAuth { - return &basicauthv3.BasicAuth{ - Users: &corev3.DataSource{ - Specifier: &corev3.DataSource_InlineBytes{ - InlineBytes: basicAuth.Users, - }, - }, - } -} - -// routeContainsBasicAuth returns true if BasicAuth exists for the provided route. -func routeContainsBasicAuth(irRoute *ir.HTTPRoute) bool { - if irRoute != nil && irRoute.BasicAuth != nil { - return true - } - return false -} - func (*basicAuth) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { return nil } // patchRoute patches the provided route with the basicAuth config if applicable. -// Note: this method enables the corresponding basicAuth filter for the provided route. +// Note: this method overwrites the HCM level filter config with the per route filter config. func (*basicAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if route == nil { return errors.New("xds route is nil") @@ -127,12 +113,48 @@ func (*basicAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.BasicAuth == nil { + if irRoute.Security == nil || irRoute.Security.BasicAuth == nil { return nil } - filterName := basicAuthFilterName(irRoute.BasicAuth) - if err := enableFilterOnRoute(route, filterName); err != nil { + + var ( + perFilterCfg map[string]*anypb.Any + basicAuthAny *anypb.Any + err error + ) + + perFilterCfg = route.GetTypedPerFilterConfig() + if _, ok := perFilterCfg[basicAuthFilter]; ok { + // This should not happen since this is the only place where the filter + // config is added in a route. + return fmt.Errorf("route already contains filter config: %s, %+v", + basicAuthFilter, route) + } + + // Overwrite the HCM level filter config with the per route filter config. + basicAuthProto := basicAuthPerRouteConfig(irRoute.Security.BasicAuth) + if err = basicAuthProto.ValidateAll(); err != nil { return err } + + if basicAuthAny, err = anypb.New(basicAuthProto); err != nil { + return err + } + + if perFilterCfg == nil { + route.TypedPerFilterConfig = make(map[string]*anypb.Any) + } + route.TypedPerFilterConfig[basicAuthFilter] = basicAuthAny + return nil } + +func basicAuthPerRouteConfig(basicAuth *ir.BasicAuth) *basicauthv3.BasicAuthPerRoute { + return &basicauthv3.BasicAuthPerRoute{ + Users: &corev3.DataSource{ + Specifier: &corev3.DataSource_InlineBytes{ + InlineBytes: basicAuth.Users, + }, + }, + } +} diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index 0d2593f9cc6..bb18a7e0286 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -38,17 +38,19 @@ const ( ) type xdsClusterArgs struct { - name string - settings []*ir.DestinationSetting - tSocket *corev3.TransportSocket - endpointType EndpointType - loadBalancer *ir.LoadBalancer - proxyProtocol *ir.ProxyProtocol - circuitBreaker *ir.CircuitBreaker - healthCheck *ir.HealthCheck - http1Settings *ir.HTTP1Settings - timeout *ir.Timeout - tcpkeepalive *ir.TCPKeepalive + name string + settings []*ir.DestinationSetting + tSocket *corev3.TransportSocket + endpointType EndpointType + loadBalancer *ir.LoadBalancer + proxyProtocol *ir.ProxyProtocol + circuitBreaker *ir.CircuitBreaker + healthCheck *ir.HealthCheck + http1Settings *ir.HTTP1Settings + timeout *ir.Timeout + tcpkeepalive *ir.TCPKeepalive + metrics *ir.Metrics + useClientProtocol bool } type EndpointType int @@ -80,13 +82,22 @@ func buildXdsCluster(args *xdsClusterArgs) *clusterv3.Cluster { DnsLookupFamily: clusterv3.Cluster_V4_ONLY, CommonLbConfig: &clusterv3.Cluster_CommonLbConfig{ LocalityConfigSpecifier: &clusterv3.Cluster_CommonLbConfig_LocalityWeightedLbConfig_{ - LocalityWeightedLbConfig: &clusterv3.Cluster_CommonLbConfig_LocalityWeightedLbConfig{}}}, + LocalityWeightedLbConfig: &clusterv3.Cluster_CommonLbConfig_LocalityWeightedLbConfig{}, + }, + }, OutlierDetection: &clusterv3.OutlierDetection{}, PerConnectionBufferLimitBytes: wrapperspb.UInt32(tcpClusterPerConnectionBufferLimitBytes), } cluster.ConnectTimeout = buildConnectTimeout(args.timeout) + // set peer endpoint stats + if args.metrics != nil && args.metrics.EnablePerEndpointStats { + cluster.TrackClusterStats = &clusterv3.TrackClusterStats{ + PerEndpointStats: args.metrics.EnablePerEndpointStats, + } + } + // Set Proxy Protocol if args.proxyProtocol != nil { cluster.TransportSocket = buildProxyProtocolSocket(args.proxyProtocol, args.tSocket) @@ -182,7 +193,6 @@ func buildXdsCluster(args *xdsClusterArgs) *clusterv3.Cluster { if args.healthCheck != nil && args.healthCheck.Passive != nil { cluster.OutlierDetection = buildXdsOutlierDetection(args.healthCheck.Passive) - } cluster.CircuitBreakers = buildXdsClusterCircuitBreaker(args.circuitBreaker) @@ -439,7 +449,7 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. requiresHTTP1Options := args.http1Settings != nil && (args.http1Settings.EnableTrailers || args.http1Settings.PreserveHeaderCase || args.http1Settings.HTTP10 != nil) - if !(requiresCommonHTTPOptions || requiresHTTP1Options || requiresHTTP2Options) { + if !(requiresCommonHTTPOptions || requiresHTTP1Options || requiresHTTP2Options || args.useClientProtocol) { return nil } @@ -450,13 +460,11 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. if args.timeout != nil && args.timeout.HTTP != nil { if args.timeout.HTTP.ConnectionIdleTimeout != nil { - protocolOptions.CommonHttpProtocolOptions.IdleTimeout = - durationpb.New(args.timeout.HTTP.ConnectionIdleTimeout.Duration) + protocolOptions.CommonHttpProtocolOptions.IdleTimeout = durationpb.New(args.timeout.HTTP.ConnectionIdleTimeout.Duration) } if args.timeout.HTTP.MaxConnectionDuration != nil { - protocolOptions.CommonHttpProtocolOptions.MaxConnectionDuration = - durationpb.New(args.timeout.HTTP.MaxConnectionDuration.Duration) + protocolOptions.CommonHttpProtocolOptions.MaxConnectionDuration = durationpb.New(args.timeout.HTTP.MaxConnectionDuration.Duration) } } @@ -465,25 +473,11 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. Value: *args.circuitBreaker.MaxRequestsPerConnection, } } - } - // When setting any Typed Extension Protocol Options, UpstreamProtocolOptions are mandatory - // If translation requires HTTP2 enablement or HTTP1 trailers, set appropriate setting - // Default to http1 otherwise - // TODO: If the cluster is TLS enabled, use AutoHTTPConfig instead of ExplicitHttpConfig - // so that when ALPN is supported then enabling http1 options doesn't force HTTP/1.1 - switch { - case requiresHTTP2Options: - protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{ - ExplicitHttpConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig{ - ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{}, - }, - } - case requiresHTTP1Options: - http1opts := &corev3.Http1ProtocolOptions{ - EnableTrailers: args.http1Settings.EnableTrailers, - } + http1opts := &corev3.Http1ProtocolOptions{} + if args.http1Settings != nil { + http1opts.EnableTrailers = args.http1Settings.EnableTrailers if args.http1Settings.PreserveHeaderCase { preservecaseAny, _ := anypb.New(&preservecasev3.PreserveCaseFormatterConfig{}) http1opts.HeaderKeyFormat = &corev3.Http1ProtocolOptions_HeaderKeyFormat{ @@ -499,6 +493,28 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. http1opts.AcceptHttp_10 = true http1opts.DefaultHostForHttp_10 = ptr.Deref(args.http1Settings.HTTP10.DefaultHost, "") } + } + + // When setting any Typed Extension Protocol Options, UpstreamProtocolOptions are mandatory + // If translation requires HTTP2 enablement or HTTP1 trailers, set appropriate setting + // Default to http1 otherwise + // TODO: If the cluster is TLS enabled, use AutoHTTPConfig instead of ExplicitHttpConfig + // so that when ALPN is supported then enabling http1 options doesn't force HTTP/1.1 + switch { + case args.useClientProtocol: + protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_UseDownstreamProtocolConfig{ + UseDownstreamProtocolConfig: &httpv3.HttpProtocolOptions_UseDownstreamHttpConfig{ + HttpProtocolOptions: http1opts, + Http2ProtocolOptions: &corev3.Http2ProtocolOptions{}, + }, + } + case requiresHTTP2Options: + protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{ + ExplicitHttpConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig{ + ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{}, + }, + } + case requiresHTTP1Options: protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{ ExplicitHttpConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig{ ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_HttpProtocolOptions{ @@ -609,5 +625,4 @@ func buildXdsClusterUpstreamOptions(tcpkeepalive *ir.TCPKeepalive) *clusterv3.Up } return ka - } diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go index 94c3855f86e..6090bc21689 100644 --- a/internal/xds/translator/cors.go +++ b/internal/xds/translator/cors.go @@ -27,8 +27,7 @@ func init() { registerHTTPFilter(&cors{}) } -type cors struct { -} +type cors struct{} var _ httpFilter = &cors{} @@ -36,7 +35,8 @@ var _ httpFilter = &cors{} // applicable. func (*cors) patchHCM( mgr *hcmv3.HttpConnectionManager, - irListener *ir.HTTPListener) error { + irListener *ir.HTTPListener, +) error { if mgr == nil { return errors.New("hcm is nil") } @@ -92,7 +92,7 @@ func listenerContainsCORS(irListener *ir.HTTPListener) bool { } for _, route := range irListener.Routes { - if route.CORS != nil { + if route.Security != nil && route.Security.CORS != nil { return true } } @@ -108,7 +108,7 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.CORS == nil { + if irRoute.Security == nil || irRoute.Security.CORS == nil { return nil } @@ -126,21 +126,22 @@ func (*cors) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { exposeHeaders string maxAge string allowCredentials *wrappers.BoolValue + c = irRoute.Security.CORS ) //nolint:gocritic - for _, origin := range irRoute.CORS.AllowOrigins { + for _, origin := range c.AllowOrigins { allowOrigins = append(allowOrigins, buildXdsStringMatcher(origin)) } - allowMethods = strings.Join(irRoute.CORS.AllowMethods, ", ") - allowHeaders = strings.Join(irRoute.CORS.AllowHeaders, ", ") - exposeHeaders = strings.Join(irRoute.CORS.ExposeHeaders, ", ") - if irRoute.CORS.MaxAge != nil { - maxAge = strconv.Itoa(int(irRoute.CORS.MaxAge.Seconds())) + allowMethods = strings.Join(c.AllowMethods, ", ") + allowHeaders = strings.Join(c.AllowHeaders, ", ") + exposeHeaders = strings.Join(c.ExposeHeaders, ", ") + if c.MaxAge != nil { + maxAge = strconv.Itoa(int(c.MaxAge.Seconds())) } - allowCredentials = &wrappers.BoolValue{Value: irRoute.CORS.AllowCredentials} + allowCredentials = &wrappers.BoolValue{Value: c.AllowCredentials} routeCfgProto := &corsv3.CorsPolicy{ AllowOriginStringMatch: allowOrigins, diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index eb79779f8e9..ead7ceccdf9 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -29,8 +29,7 @@ func init() { registerHTTPFilter(&extAuth{}) } -type extAuth struct { -} +type extAuth struct{} var _ httpFilter = &extAuth{} @@ -58,11 +57,11 @@ func (*extAuth) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPLi // Only generates one OAuth2 Envoy filter for each unique name. // For example, if there are two routes under the same gateway with the // same OIDC config, only one OAuth2 filter will be generated. - if hcmContainsFilter(mgr, extAuthFilterName(route.ExtAuth)) { + if hcmContainsFilter(mgr, extAuthFilterName(route.Security.ExtAuth)) { continue } - filter, err := buildHCMExtAuthFilter(route.ExtAuth) + filter, err := buildHCMExtAuthFilter(route.Security.ExtAuth) if err != nil { errs = errors.Join(errs, err) continue @@ -202,7 +201,9 @@ func grpcService(grpc *ir.GRPCExtAuthService) *corev3.GrpcService_EnvoyGrpc { // routeContainsExtAuth returns true if ExtAuth exists for the provided route. func routeContainsExtAuth(irRoute *ir.HTTPRoute) bool { - if irRoute != nil && irRoute.ExtAuth != nil { + if irRoute != nil && + irRoute.Security != nil && + irRoute.Security.ExtAuth != nil { return true } return false @@ -210,7 +211,8 @@ func routeContainsExtAuth(irRoute *ir.HTTPRoute) bool { // patchResources patches the cluster resources for the external auth services. func (*extAuth) patchResources(tCtx *types.ResourceVersionTable, - routes []*ir.HTTPRoute) error { + routes []*ir.HTTPRoute, +) error { if tCtx == nil || tCtx.XdsResources == nil { return errors.New("xds resource table is nil") } @@ -220,15 +222,15 @@ func (*extAuth) patchResources(tCtx *types.ResourceVersionTable, if !routeContainsExtAuth(route) { continue } - if route.ExtAuth.HTTP != nil { + if route.Security.ExtAuth.HTTP != nil { if err := createExtServiceXDSCluster( - &route.ExtAuth.HTTP.Destination, tCtx); err != nil && !errors.Is( + &route.Security.ExtAuth.HTTP.Destination, tCtx); err != nil && !errors.Is( err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } } else { if err := createExtServiceXDSCluster( - &route.ExtAuth.GRPC.Destination, tCtx); err != nil && !errors.Is( + &route.Security.ExtAuth.GRPC.Destination, tCtx); err != nil && !errors.Is( err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } @@ -247,10 +249,10 @@ func (*extAuth) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.ExtAuth == nil { + if irRoute.Security == nil || irRoute.Security.ExtAuth == nil { return nil } - filterName := extAuthFilterName(irRoute.ExtAuth) + filterName := extAuthFilterName(irRoute.Security.ExtAuth) if err := enableFilterOnRoute(route, filterName); err != nil { return err } diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go index 19dd8480753..c31185211d4 100644 --- a/internal/xds/translator/extproc.go +++ b/internal/xds/translator/extproc.go @@ -12,11 +12,13 @@ import ( routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" extprocv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_proc/v3" hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" - "github.com/golang/protobuf/ptypes/duration" - "google.golang.org/protobuf/types/known/anypb" "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/xds/types" + + "github.com/golang/protobuf/ptypes/duration" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/durationpb" ) const ( @@ -27,14 +29,13 @@ func init() { registerHTTPFilter(&extProc{}) } -type extProc struct { -} +type extProc struct{} var _ httpFilter = &extProc{} -// patchHCM builds and appends the ext_authz Filters to the HTTP Connection Manager +// patchHCM builds and appends the ext_proc Filters to the HTTP Connection Manager // if applicable, and it does not already exist. -// Note: this method creates an ext_authz filter for each route that contains an ExtAuthz config. +// Note: this method creates an ext_proc filter for each route that contains an ExtAuthz config. // The filter is disabled by default. It is enabled on the route level. func (*extProc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { var errs error @@ -70,7 +71,7 @@ func (*extProc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPLi return errs } -// buildHCMExtProcFilter returns an ext_authp HTTP filter from the provided IR HTTPRoute. +// buildHCMExtProcFilter returns an ext_proc HTTP filter from the provided IR HTTPRoute. func buildHCMExtProcFilter(extProc ir.ExtProc) (*hcmv3.HttpFilter, error) { extAuthProto := extProcConfig(extProc) if err := extAuthProto.ValidateAll(); err != nil { @@ -107,6 +108,38 @@ func extProcConfig(extProc ir.ExtProc) *extprocv3.ExternalProcessor { Seconds: defaultExtServiceRequestTimeout, }, }, + ProcessingMode: &extprocv3.ProcessingMode{ + RequestHeaderMode: extprocv3.ProcessingMode_SKIP, + ResponseHeaderMode: extprocv3.ProcessingMode_SKIP, + RequestBodyMode: extprocv3.ProcessingMode_NONE, + ResponseBodyMode: extprocv3.ProcessingMode_NONE, + RequestTrailerMode: extprocv3.ProcessingMode_SKIP, + ResponseTrailerMode: extprocv3.ProcessingMode_SKIP, + }, + } + + if extProc.FailOpen != nil { + config.FailureModeAllow = *extProc.FailOpen + } + + if extProc.MessageTimeout != nil { + config.MessageTimeout = durationpb.New(extProc.MessageTimeout.Duration) + } + + if extProc.RequestBodyProcessingMode != nil { + config.ProcessingMode.RequestBodyMode = buildExtProcBodyProcessingMode(extProc.RequestBodyProcessingMode) + } + + if extProc.RequestHeaderProcessing { + config.ProcessingMode.RequestHeaderMode = extprocv3.ProcessingMode_SEND + } + + if extProc.ResponseBodyProcessingMode != nil { + config.ProcessingMode.ResponseBodyMode = buildExtProcBodyProcessingMode(extProc.ResponseBodyProcessingMode) + } + + if extProc.ResponseHeaderProcessing { + config.ProcessingMode.ResponseHeaderMode = extprocv3.ProcessingMode_SEND } return config @@ -128,9 +161,10 @@ func routeContainsExtProc(irRoute *ir.HTTPRoute) bool { return len(irRoute.ExtProcs) > 0 } -// patchResources patches the cluster resources for the external auth services. +// patchResources patches the cluster resources for the external services. func (*extProc) patchResources(tCtx *types.ResourceVersionTable, - routes []*ir.HTTPRoute) error { + routes []*ir.HTTPRoute, +) error { if tCtx == nil || tCtx.XdsResources == nil { return errors.New("xds resource table is nil") } @@ -173,3 +207,15 @@ func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { } return nil } + +func buildExtProcBodyProcessingMode(mode *ir.ExtProcBodyProcessingMode) extprocv3.ProcessingMode_BodySendMode { + lookup := map[ir.ExtProcBodyProcessingMode]extprocv3.ProcessingMode_BodySendMode{ + ir.ExtProcBodyBuffered: extprocv3.ProcessingMode_BUFFERED, + ir.ExtProcBodyBufferedPartial: extprocv3.ProcessingMode_BUFFERED_PARTIAL, + ir.ExtProcBodyStreamed: extprocv3.ProcessingMode_STREAMED, + } + if r, found := lookup[*mode]; found { + return r + } + return extprocv3.ProcessingMode_NONE +} diff --git a/internal/xds/translator/fault.go b/internal/xds/translator/fault.go index ae01b566c84..46642934ce1 100644 --- a/internal/xds/translator/fault.go +++ b/internal/xds/translator/fault.go @@ -30,8 +30,7 @@ func init() { registerHTTPFilter(&fault{}) } -type fault struct { -} +type fault struct{} var _ httpFilter = &fault{} @@ -39,7 +38,6 @@ var _ httpFilter = &fault{} // if applicable, and it does not already exist. // Note: this method creates an fault filter for each route that contains an Fault config. func (*fault) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { - if mgr == nil { return errors.New("hcm is nil") } @@ -179,7 +177,6 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { route.TypedPerFilterConfig[wellknown.Fault] = routeCfgAny return nil - } // translatePercentToFractionalPercent translates an v1alpha3 Percent instance diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index ca4e6bb64c3..0b8f6dbeff9 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -44,7 +44,7 @@ func registerHTTPFilter(filter httpFilter) { // - PatchRouteWithPerRouteConfig: EG enables the corresponding filter for each // route in the typedFilterConfig of that route. // -// The filter types that haven't native per-route support: oauth2, basic authn, ext_authz. +// The filter types that haven't native per-route support: oauth2, ext_authz. // Note: The filter types that have native per-route configuration support should // always se their own native per-route configuration. type httpFilter interface { @@ -97,18 +97,20 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { order = 2 case isFilterType(filter, extAuthFilter): order = 3 - case isFilterType(filter, basicAuthFilter): + case filter.Name == basicAuthFilter: order = 4 case isFilterType(filter, oauth2Filter): order = 5 case filter.Name == jwtAuthn: order = 6 - case filter.Name == extProcFilter: + case isFilterType(filter, extProcFilter): order = 7 - case filter.Name == localRateLimitFilter: + case isFilterType(filter, wasmFilter): order = 8 - case filter.Name == wellknown.HTTPRateLimit: + case filter.Name == localRateLimitFilter: order = 9 + case filter.Name == wellknown.HTTPRateLimit: + order = 10 case filter.Name == wellknown.Router: order = 100 } @@ -157,7 +159,8 @@ func sortHTTPFilters(filters []*hcmv3.HttpFilter) []*hcmv3.HttpFilter { // newOrderedHTTPFilter method. func (t *Translator) patchHCMWithFilters( mgr *hcmv3.HttpConnectionManager, - irListener *ir.HTTPListener) error { + irListener *ir.HTTPListener, +) error { // The order of filter patching is not relevant here. // All the filters will be sorted in correct order after the patching is done. // @@ -195,8 +198,8 @@ func (t *Translator) patchHCMWithFilters( // provided route. func patchRouteWithPerRouteConfig( route *routev3.Route, - irRoute *ir.HTTPRoute) error { - + irRoute *ir.HTTPRoute, +) error { for _, filter := range httpFilters { if err := filter.patchRoute(route, irRoute); err != nil { return err @@ -205,8 +208,7 @@ func patchRouteWithPerRouteConfig( // RateLimit filter is handled separately because it relies on the global // rate limit server configuration. - if err := - patchRouteWithRateLimit(route.GetRoute(), irRoute); err != nil { + if err := patchRouteWithRateLimit(route.GetRoute(), irRoute); err != nil { return nil } diff --git a/internal/xds/translator/httpfilters_test.go b/internal/xds/translator/httpfilters_test.go index 47cd118da58..90773ce6a36 100644 --- a/internal/xds/translator/httpfilters_test.go +++ b/internal/xds/translator/httpfilters_test.go @@ -26,18 +26,24 @@ func Test_sortHTTPFilters(t *testing.T) { httpFilterForTest(wellknown.CORS), httpFilterForTest(jwtAuthn), httpFilterForTest(oauth2Filter + "-route1"), - httpFilterForTest(basicAuthFilter + "-route1"), + httpFilterForTest(basicAuthFilter), httpFilterForTest(wellknown.HTTPRateLimit), httpFilterForTest(wellknown.Fault), httpFilterForTest(extAuthFilter + "-route1"), + httpFilterForTest(wasmFilter + "-route1"), + httpFilterForTest(extProcFilter + "-route1"), + httpFilterForTest(localRateLimitFilter), }, want: []*hcmv3.HttpFilter{ httpFilterForTest(wellknown.Fault), httpFilterForTest(wellknown.CORS), httpFilterForTest(extAuthFilter + "-route1"), - httpFilterForTest(basicAuthFilter + "-route1"), + httpFilterForTest(basicAuthFilter), httpFilterForTest(oauth2Filter + "-route1"), httpFilterForTest(jwtAuthn), + httpFilterForTest(extProcFilter + "-route1"), + httpFilterForTest(wasmFilter + "-route1"), + httpFilterForTest(localRateLimitFilter), httpFilterForTest(wellknown.HTTPRateLimit), httpFilterForTest(wellknown.Router), }, diff --git a/internal/xds/translator/jwt.go b/internal/xds/translator/jwt.go index 72e8029f1c4..27697043a46 100644 --- a/internal/xds/translator/jwt.go +++ b/internal/xds/translator/jwt.go @@ -17,6 +17,7 @@ import ( "github.com/envoyproxy/go-control-plane/pkg/wellknown" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/emptypb" "k8s.io/utils/ptr" "github.com/envoyproxy/gateway/api/v1alpha1" @@ -33,8 +34,7 @@ func init() { registerHTTPFilter(&jwt{}) } -type jwt struct { -} +type jwt struct{} var _ httpFilter = &jwt{} @@ -106,8 +106,8 @@ func buildJWTAuthn(irListener *ir.HTTPListener) (*jwtauthnv3.JwtAuthentication, } var reqs []*jwtauthnv3.JwtRequirement - for i := range route.JWT.Providers { - irProvider := route.JWT.Providers[i] + for i := range route.Security.JWT.Providers { + irProvider := route.Security.JWT.Providers[i] // Create the cluster for the remote jwks, if it doesn't exist. jwksCluster, err := url2Cluster(irProvider.RemoteJWKS.URI) if err != nil { @@ -133,7 +133,8 @@ func buildJWTAuthn(irListener *ir.HTTPListener) (*jwtauthnv3.JwtAuthentication, for _, claimToHeader := range irProvider.ClaimToHeaders { claimToHeader := &jwtauthnv3.JwtClaimToHeader{ HeaderName: claimToHeader.Header, - ClaimName: claimToHeader.Claim} + ClaimName: claimToHeader.Claim, + } claimToHeaders = append(claimToHeaders, claimToHeader) } jwtProvider := &jwtauthnv3.JwtProvider{ @@ -163,6 +164,15 @@ func buildJWTAuthn(irListener *ir.HTTPListener) (*jwtauthnv3.JwtAuthentication, }, }) } + + if route.Security.JWT.AllowMissing { + reqs = append(reqs, &jwtauthnv3.JwtRequirement{ + RequiresType: &jwtauthnv3.JwtRequirement_AllowMissing{ + AllowMissing: &emptypb.Empty{}, + }, + }) + } + if len(reqs) == 1 { reqMap[route.Name] = reqs[0] } else { @@ -232,7 +242,8 @@ func (*jwt) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { } routeCfgProto := &jwtauthnv3.PerRouteConfig{ - RequirementSpecifier: &jwtauthnv3.PerRouteConfig_RequirementName{RequirementName: irRoute.Name}} + RequirementSpecifier: &jwtauthnv3.PerRouteConfig_RequirementName{RequirementName: irRoute.Name}, + } routeCfgAny, err := anypb.New(routeCfgProto) if err != nil { @@ -255,47 +266,16 @@ func (*jwt) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRo return errors.New("xds resource table is nil") } - var errs error + var err, errs error for _, route := range routes { if !routeContainsJWTAuthn(route) { continue } - for i := range route.JWT.Providers { - var ( - jwks *urlCluster - ds *ir.DestinationSetting - tSocket *corev3.TransportSocket - err error - ) - - provider := route.JWT.Providers[i] - jwks, err = url2Cluster(provider.RemoteJWKS.URI) - if err != nil { - errs = errors.Join(errs, err) - continue - } - - ds = &ir.DestinationSetting{ - Weight: ptr.To[uint32](1), - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(jwks.hostname, jwks.port)}, - } - - clusterArgs := &xdsClusterArgs{ - name: jwks.name, - settings: []*ir.DestinationSetting{ds}, - endpointType: jwks.endpointType, - } - if jwks.tls { - tSocket, err = buildXdsUpstreamTLSSocket(jwks.hostname) - if err != nil { - errs = errors.Join(errs, err) - continue - } - clusterArgs.tSocket = tSocket - } + for i := range route.Security.JWT.Providers { + provider := route.Security.JWT.Providers[i] - if err = addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) { + if err = addClusterFromURL(provider.RemoteJWKS.URI, tCtx); err != nil { errs = errors.Join(errs, err) } } @@ -324,9 +304,10 @@ func listenerContainsJWTAuthn(irListener *ir.HTTPListener) bool { // provided route. func routeContainsJWTAuthn(irRoute *ir.HTTPRoute) bool { if irRoute != nil && - irRoute.JWT != nil && - irRoute.JWT.Providers != nil && - len(irRoute.JWT.Providers) > 0 { + irRoute.Security != nil && + irRoute.Security.JWT != nil && + irRoute.Security.JWT.Providers != nil && + len(irRoute.Security.JWT.Providers) > 0 { return true } return false diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 9d470edbe35..af81f20aa89 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -79,16 +79,20 @@ func http1ProtocolOptions(opts *ir.HTTP1Settings) *corev3.Http1ProtocolOptions { return r } -func http2ProtocolOptions() *corev3.Http2ProtocolOptions { +func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { + if opts == nil { + opts = &ir.HTTP2Settings{} + } + return &corev3.Http2ProtocolOptions{ MaxConcurrentStreams: &wrappers.UInt32Value{ - Value: http2MaxConcurrentStreamsLimit, + Value: ptr.Deref(opts.MaxConcurrentStreams, http2MaxConcurrentStreamsLimit), }, InitialStreamWindowSize: &wrappers.UInt32Value{ - Value: http2InitialStreamWindowSize, + Value: ptr.Deref(opts.InitialStreamWindowSize, http2InitialStreamWindowSize), }, InitialConnectionWindowSize: &wrappers.UInt32Value{ - Value: http2InitialConnectionWindowSize, + Value: ptr.Deref(opts.InitialConnectionWindowSize, http2InitialConnectionWindowSize), }, } } @@ -194,8 +198,19 @@ func buildXdsQuicListener(name, address string, port uint32, accesslog *ir.Acces return xdsListener } -func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irListener *ir.HTTPListener, - accesslog *ir.AccessLog, tracing *ir.Tracing, http3Listener bool, connection *ir.Connection) error { +// addHCMToXDSListener adds a HCM filter to the listener's filter chain, and adds +// all the necessary HTTP filters to that HCM. +// +// - If tls is not enabled, a HCM filter is added to the Listener's default TCP filter chain. +// All the ir HTTP Listeners on the same address + port combination share the +// same HCM + HTTP filters. +// - If tls is enabled, a new TCP filter chain is created and added to the listener. +// A HCM filter is added to the new TCP filter chain. +// The newly created TCP filter chain is configured with a filter chain match to +// match the server names(SNI) based on the listener's hostnames. +func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irListener *ir.HTTPListener, + accesslog *ir.AccessLog, tracing *ir.Tracing, http3Listener bool, connection *ir.Connection, +) error { al := buildXdsAccessLog(accesslog, false) hcmTracing, err := buildHCMTracing(tracing) @@ -212,8 +227,8 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL } // Client IP detection - var useRemoteAddress = true - var originalIPDetectionExtensions = originalIPDetectionExtensions(irListener.ClientIPDetection) + useRemoteAddress := true + originalIPDetectionExtensions := originalIPDetectionExtensions(irListener.ClientIPDetection) if originalIPDetectionExtensions != nil { useRemoteAddress = false } @@ -234,7 +249,7 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL ServerHeaderTransformation: hcmv3.HttpConnectionManager_PASS_THROUGH, // Add HTTP2 protocol options // Set it by default to also support HTTP1.1 to HTTP2 Upgrades - Http2ProtocolOptions: http2ProtocolOptions(), + Http2ProtocolOptions: http2ProtocolOptions(irListener.HTTP2), // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for UseRemoteAddress: &wrappers.BoolValue{Value: useRemoteAddress}, XffNumTrustedHops: xffNumTrustedHops(irListener.ClientIPDetection), @@ -533,7 +548,7 @@ func buildXdsDownstreamTLSSocket(tlsConfig *ir.TLSConfig) (*corev3.TransportSock } if tlsConfig.CACertificate != nil { - tlsCtx.RequireClientCertificate = &wrappers.BoolValue{Value: true} + tlsCtx.RequireClientCertificate = &wrappers.BoolValue{Value: tlsConfig.RequireClientCertificate} tlsCtx.CommonTlsContext.ValidationContextType = &tlsv3.CommonTlsContext_ValidationContextSdsSecretConfig{ ValidationContextSdsSecretConfig: &tlsv3.SdsSecretConfig{ Name: tlsConfig.CACertificate.Name, @@ -706,7 +721,6 @@ func makeConfigSource() *corev3.ConfigSource { } func translateEscapePath(in ir.PathEscapedSlashAction) hcmv3.HttpConnectionManager_PathWithEscapedSlashesAction { - lookup := map[ir.PathEscapedSlashAction]hcmv3.HttpConnectionManager_PathWithEscapedSlashesAction{ ir.KeepUnchangedAction: hcmv3.HttpConnectionManager_KEEP_UNCHANGED, ir.RejectRequestAction: hcmv3.HttpConnectionManager_REJECT_REQUEST, diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go index a3110cbf98e..adbcca6e749 100644 --- a/internal/xds/translator/local_ratelimit.go +++ b/internal/xds/translator/local_ratelimit.go @@ -35,8 +35,7 @@ func init() { registerHTTPFilter(&localRateLimit{}) } -type localRateLimit struct { -} +type localRateLimit struct{} var _ httpFilter = &localRateLimit{} @@ -106,7 +105,8 @@ func routeContainsLocalRateLimit(irRoute *ir.HTTPRoute) bool { } func (*localRateLimit) patchResources(*types.ResourceVersionTable, - []*ir.HTTPRoute) error { + []*ir.HTTPRoute, +) error { return nil } @@ -188,7 +188,8 @@ func (*localRateLimit) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) e } func buildRouteLocalRateLimits(local *ir.LocalRateLimit) ( - []*routev3.RateLimit, []*rlv3.LocalRateLimitDescriptor, error) { + []*routev3.RateLimit, []*rlv3.LocalRateLimitDescriptor, error, +) { var rateLimits []*routev3.RateLimit var descriptors []*rlv3.LocalRateLimitDescriptor diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 5b14a00f871..d005f4b4914 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -31,8 +31,7 @@ func init() { registerHTTPFilter(&oidc{}) } -type oidc struct { -} +type oidc struct{} var _ httpFilter = &oidc{} @@ -59,11 +58,11 @@ func (*oidc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe // Only generates one BasicAuth Envoy filter for each unique name. // For example, if there are two routes under the same gateway with the // same BasicAuth config, only one BasicAuth filter will be generated. - if hcmContainsFilter(mgr, oauth2FilterName(route.OIDC)) { + if hcmContainsFilter(mgr, oauth2FilterName(route.Security.OIDC)) { continue } - filter, err := buildHCMOAuth2Filter(route.OIDC) + filter, err := buildHCMOAuth2Filter(route.Security.OIDC) if err != nil { errs = errors.Join(errs, err) continue @@ -178,14 +177,17 @@ func oauth2Config(oidc *ir.OIDC) (*oauth2v3.OAuth2, error) { // routeContainsOIDC returns true if OIDC exists for the provided route. func routeContainsOIDC(irRoute *ir.HTTPRoute) bool { - if irRoute != nil && irRoute.OIDC != nil { + if irRoute != nil && + irRoute.Security != nil && + irRoute.Security.OIDC != nil { return true } return false } func (*oidc) patchResources(tCtx *types.ResourceVersionTable, - routes []*ir.HTTPRoute) error { + routes []*ir.HTTPRoute, +) error { if err := createOAuth2TokenEndpointClusters(tCtx, routes); err != nil { return err } @@ -198,7 +200,8 @@ func (*oidc) patchResources(tCtx *types.ResourceVersionTable, // createOAuth2TokenEndpointClusters creates token endpoint clusters from the // provided routes, if needed. func createOAuth2TokenEndpointClusters(tCtx *types.ResourceVersionTable, - routes []*ir.HTTPRoute) error { + routes []*ir.HTTPRoute, +) error { if tCtx == nil || tCtx.XdsResources == nil { return errors.New("xds resource table is nil") } @@ -216,7 +219,7 @@ func createOAuth2TokenEndpointClusters(tCtx *types.ResourceVersionTable, err error ) - cluster, err = url2Cluster(route.OIDC.Provider.TokenEndpoint) + cluster, err = url2Cluster(route.Security.OIDC.Provider.TokenEndpoint) if err != nil { errs = errors.Join(errs, err) continue @@ -228,15 +231,16 @@ func createOAuth2TokenEndpointClusters(tCtx *types.ResourceVersionTable, if cluster.endpointType == EndpointTypeStatic { errs = errors.Join(errs, fmt.Errorf( "static IP cluster is not allowed: %s", - route.OIDC.Provider.TokenEndpoint)) + route.Security.OIDC.Provider.TokenEndpoint)) continue } ds = &ir.DestinationSetting{ Weight: ptr.To[uint32](1), - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint( - cluster.hostname, - cluster.port), + Endpoints: []*ir.DestinationEndpoint{ + ir.NewDestEndpoint( + cluster.hostname, + cluster.port), }, } @@ -275,12 +279,12 @@ func createOAuth2Secrets(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRout // a separate secret is created for each route, even they share the same // oauth2 client ID and secret. - clientSecret := buildOAuth2ClientSecret(route.OIDC) + clientSecret := buildOAuth2ClientSecret(route.Security.OIDC) if err := addXdsSecret(tCtx, clientSecret); err != nil { errs = errors.Join(errs, err) } - if err := addXdsSecret(tCtx, buildOAuth2HMACSecret(route.OIDC)); err != nil { + if err := addXdsSecret(tCtx, buildOAuth2HMACSecret(route.Security.OIDC)); err != nil { errs = errors.Join(errs, err) } } @@ -339,10 +343,10 @@ func (*oidc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { if irRoute == nil { return errors.New("ir route is nil") } - if irRoute.OIDC == nil { + if irRoute.Security == nil || irRoute.Security.OIDC == nil { return nil } - filterName := oauth2FilterName(irRoute.OIDC) + filterName := oauth2FilterName(irRoute.Security.OIDC) if err := enableFilterOnRoute(route, filterName); err != nil { return err } diff --git a/internal/xds/translator/ratelimit.go b/internal/xds/translator/ratelimit.go index 6fb3e2d86db..02b1c3d6048 100644 --- a/internal/xds/translator/ratelimit.go +++ b/internal/xds/translator/ratelimit.go @@ -462,7 +462,7 @@ func buildRateLimitTLSocket() (*corev3.TransportSocket, error) { }, nil } -func (t *Translator) createRateLimitServiceCluster(tCtx *types.ResourceVersionTable, irListener *ir.HTTPListener) error { +func (t *Translator) createRateLimitServiceCluster(tCtx *types.ResourceVersionTable, irListener *ir.HTTPListener, metrics *ir.Metrics) error { // Return early if rate limits don't exist. if !t.isRateLimitPresent(irListener) { return nil @@ -486,6 +486,7 @@ func (t *Translator) createRateLimitServiceCluster(tCtx *types.ResourceVersionTa settings: []*ir.DestinationSetting{ds}, tSocket: tSocket, endpointType: EndpointTypeDNS, + metrics: metrics, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } diff --git a/internal/xds/translator/runner/runner_test.go b/internal/xds/translator/runner/runner_test.go index 9f3d7035bd6..a7be53236c8 100644 --- a/internal/xds/translator/runner/runner_test.go +++ b/internal/xds/translator/runner/runner_test.go @@ -98,7 +98,6 @@ func TestRunner(t *testing.T) { // Ensure that xds has no key, value pairs return len(out) == 0 }, time.Second*5, time.Millisecond*50) - } func TestRunner_withExtensionManager(t *testing.T) { diff --git a/internal/xds/translator/tcpkeepalive.go b/internal/xds/translator/tcpkeepalive.go index 9d4c71d6d30..fcdd2a46992 100644 --- a/internal/xds/translator/tcpkeepalive.go +++ b/internal/xds/translator/tcpkeepalive.go @@ -62,5 +62,4 @@ func buildTCPSocketOptions(keepAlive *ir.TCPKeepalive) []*corev3.SocketOption { } return socketOptions - } diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml new file mode 100644 index 00000000000..ca71bbad491 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml @@ -0,0 +1,46 @@ +name: "accesslog" +metrics: + enablePerEndpointStats: true +accesslog: + text: + - path: "/dev/stdout" + format: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + json: + - path: "/dev/stdout" + json: + start_time: "%START_TIME%" + method: "%REQ(:METHOD)%" + path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" + protocol: "%PROTOCOL%" + response_code: "%RESPONSE_CODE%" + openTelemetry: + - text: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + attributes: + "response_code": "%RESPONSE_CODE%" + resources: + "cluster_name": "cluster1" + host: otel-collector.default.svc.cluster.local + port: 4317 +http: + - name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + directResponse: + body: "Unknown custom filter type: UnsupportedType" + statusCode: 500 diff --git a/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml b/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml index 36df412f728..48bbbebadc2 100644 --- a/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/basic-auth.yaml @@ -28,9 +28,10 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com backendWeights: hostname: www.foo.com @@ -50,9 +51,10 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com hostname: www.bar.com isHTTP2: false @@ -72,6 +74,7 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-gateway-1 - users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= + security: + basicAuth: + name: securitypolicy/default/policy-for-gateway-1 + users: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= diff --git a/internal/xds/translator/testdata/in/xds-ir/cors.yaml b/internal/xds/translator/testdata/in/xds-ir/cors.yaml index c5a07bee840..dd9eff3418f 100644 --- a/internal/xds/translator/testdata/in/xds-ir/cors.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/cors.yaml @@ -18,22 +18,23 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - cors: - allowOrigins: - - name: example.com - stringMatch: - safeRegex: "*.example.com" - - name: foo.bar.com - stringMatch: - exact: foo.bar.com - allowMethods: - - GET - - POST - allowHeaders: - - "x-header-1" - - "x-header-2" - exposeHeaders: - - "x-header-3" - - "x-header-4" - allowCredentials: true - maxAge: 1000s + security: + cors: + allowOrigins: + - name: example.com + stringMatch: + safeRegex: "*.example.com" + - name: foo.bar.com + stringMatch: + exact: foo.bar.com + allowMethods: + - GET + - POST + allowHeaders: + - "x-header-1" + - "x-header-2" + exposeHeaders: + - "x-header-3" + - "x-header-4" + allowCredentials: true + maxAge: 1000s diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml index 32d5522e6df..bedbbae996c 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml @@ -28,23 +28,24 @@ http: port: 8080 protocol: HTTP weight: 1 - extAuth: - name: securitypolicy/default/policy-for-http-route-1 - failOpen: false - grpc: - authority: grpc-backend.default:9000 - destination: - name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend - settings: - - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - protocol: GRPC - weight: 1 - headersToExtAuth: - - header1 - - header2 + security: + extAuth: + name: securitypolicy/default/policy-for-http-route-1 + failOpen: false + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com hostname: www.foo.com isHTTP2: false @@ -64,23 +65,24 @@ http: port: 8080 protocol: HTTP weight: 1 - extAuth: - name: securitypolicy/default/policy-for-http-route-1 - failOpen: false - grpc: - authority: grpc-backend.default:9000 - destination: - name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend - settings: - - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - protocol: GRPC - weight: 1 - headersToExtAuth: - - header1 - - header2 + security: + extAuth: + name: securitypolicy/default/policy-for-http-route-1 + failOpen: false + grpc: + authority: grpc-backend.default:9000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com hostname: www.bar.com isHTTP2: false @@ -100,21 +102,22 @@ http: port: 8080 protocol: HTTP weight: 1 - extAuth: - name: securitypolicy/default/policy-for-gateway-1 - failOpen: true - http: - authority: http-backend.envoy-gateway:80 - destination: - name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - weight: 1 - headersToBackend: - - header1 - - header2 - path: /auth + security: + extAuth: + name: securitypolicy/default/policy-for-gateway-1 + failOpen: true + http: + authority: http-backend.envoy-gateway:80 + destination: + name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml index 170f1a3f2ea..90fd067480b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml @@ -21,22 +21,30 @@ http: port: 8080 protocol: HTTP weight: 1 - envoyExtensionFeatures: - extProc: - - name: envoyextensionpolicy/default/policy-for-route-2/0 - authority: grpc-backend-4.default:4000 - destination: - name: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 - settings: - - protocol: GRPC - weight: 1 - - name: envoyextensionpolicy/default/policy-for-route-1/0 - authority: grpc-backend-2.default:8000 - destination: - name: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 - settings: - - protocol: GRPC - weight: 1 + extProc: + - name: envoyextensionpolicy/default/policy-for-route-2/0 + failOpen: true + messageTimeout: 5s + requestHeaderProcessing: true + requestBodyProcessingMode: Buffered + responseBodyProcessingMode: Streamed + authority: grpc-backend-4.default:4000 + destination: + name: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 + settings: + - protocol: GRPC + weight: 1 + - name: envoyextensionpolicy/default/policy-for-route-1/0 + failOpen: true + messageTimeout: 5s + responseHeaderProcessing: true + requestBodyProcessingMode: BufferedPartial + authority: grpc-backend-2.default:8000 + destination: + name: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 + settings: + - protocol: GRPC + weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io @@ -56,22 +64,23 @@ http: port: 8080 protocol: HTTP weight: 1 - envoyExtensionFeatures: - extProc: - - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0 - authority: grpc-backend-3.envoy-gateway:3000 - destination: - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 - settings: - - protocol: GRPC - weight: 1 - - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0 - authority: grpc-backend.envoy-gateway:9000 - destination: - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend - settings: - - protocol: GRPC - weight: 1 + extProc: + - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0 + authority: grpc-backend-3.envoy-gateway:3000 + destination: + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 + settings: + - protocol: GRPC + weight: 1 + - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0 + failOpen: false + messageTimeout: 15s + authority: grpc-backend.envoy-gateway:9000 + destination: + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend + settings: + - protocol: GRPC + weight: 1 hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io diff --git a/internal/xds/translator/testdata/in/xds-ir/http-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/http-endpoint-stats.yaml new file mode 100644 index 00000000000..12fc177bde8 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http-endpoint-stats.yaml @@ -0,0 +1,21 @@ +name: "metrics-endpoint-stats" +metrics: + enablePerEndpointStats: true +http: + - name: "listener-enable-endpoint-stats" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "first-route" + hostname: "*" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/http-preserve-client-protocol.yaml b/internal/xds/translator/testdata/in/xds-ir/http-preserve-client-protocol.yaml new file mode 100644 index 00000000000..bfafbc5b96d --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http-preserve-client-protocol.yaml @@ -0,0 +1,31 @@ +http: +- address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + useClientProtocol: true diff --git a/internal/xds/translator/testdata/in/xds-ir/http2.yaml b/internal/xds/translator/testdata/in/xds-ir/http2.yaml new file mode 100644 index 00000000000..c95bc0442c0 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http2.yaml @@ -0,0 +1,22 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "foo.com" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + http2: + initialConnectionWindowSize: 65536 + initialStreamWindowSize: 33554432 + maxConcurrentStreams: 200 + routes: + - name: "first-route" + hostname: "*" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml index e86dd9b8aeb..1aa76efdfab 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch.yaml @@ -9,6 +9,12 @@ envoyPatchPolicies: name: "first-policy" namespace: "default" jsonPatches: + - type: "type.googleapis.com/envoy.config.listener.v3.Listener" + name: first-listener + operation: + op: add + path: "/filter_chains/0/filters/0/typed_config/preserve_external_request_id" + value: true - type: "type.googleapis.com/envoy.config.listener.v3.Listener" name: "first-listener" operation: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml index 2a362a469dc..8d24373fd6a 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-custom-extractor.yaml @@ -12,22 +12,23 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json - extractFrom: - cookies: - - session_access_token - headers: - - name: Authorization - valuePrefix: 'Bearer ' - params: - - token + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json + extractFrom: + cookies: + - session_access_token + headers: + - name: Authorization + valuePrefix: 'Bearer ' + params: + - token destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml index 558049ed562..88f88f5aa35 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-multi-provider.yaml @@ -12,30 +12,31 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: http://localhost/jwt/public-key/jwks.json - claimToHeaders: - - header: one-route-example-key1 - claim: claim.neteased.key - - name: example2 - issuer: https://www.two.example.com - audiences: - - one.foo.com - - two.foo.com - remoteJWKS: - uri: https://192.168.1.250:8080/jwt/public-key/jwks.json - recomputeRoute: true - claimToHeaders: - - header: one-route-example2-key1 - claim: claim.neteased.key - - header: one-route-example2-key2 - claim: name + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: http://localhost/jwt/public-key/jwks.json + claimToHeaders: + - header: one-route-example-key1 + claim: claim.neteased.key + - name: example2 + issuer: https://www.two.example.com + audiences: + - one.foo.com + - two.foo.com + remoteJWKS: + uri: https://192.168.1.250:8080/jwt/public-key/jwks.json + recomputeRoute: true + claimToHeaders: + - header: one-route-example2-key1 + claim: claim.neteased.key + - header: one-route-example2-key2 + claim: name destination: name: "first-route-www.test.com-dest" settings: @@ -46,24 +47,25 @@ http: hostname: "*" pathMatch: exact: "foo/baz" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: http://localhost/jwt/public-key/jwks.json - claimToHeaders: - - header: second-route-example-key1 - claim: claim.neteased.key - - name: example2 - issuer: https://www.two.example.com - audiences: - - one.foo.com - - two.foo.com - remoteJWKS: - uri: https://192.168.1.250:8080/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: http://localhost/jwt/public-key/jwks.json + claimToHeaders: + - header: second-route-example-key1 + claim: claim.neteased.key + - name: example2 + issuer: https://www.two.example.com + audiences: + - one.foo.com + - two.foo.com + remoteJWKS: + uri: https://192.168.1.250:8080/jwt/public-key/jwks.json destination: name: "second-route-www.test.com-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml index 7dd2a4b73c2..324f54d9311 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-multi-route-single-provider.yaml @@ -15,17 +15,18 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json - claimToHeaders: - - header: first-route-key - claim: claim.neteased.key + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json + claimToHeaders: + - header: first-route-key + claim: claim.neteased.key destination: name: "first-route-dest" settings: @@ -36,14 +37,15 @@ http: hostname: "*" pathMatch: exact: "foo/baz" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json destination: name: "second-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-optional.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-optional.yaml new file mode 100644 index 00000000000..b43dd005257 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-optional.yaml @@ -0,0 +1,38 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "first-route" + hostname: "*" + pathMatch: + exact: "foo/bar" + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json + extractFrom: + cookies: + - session_access_token + headers: + - name: Authorization + valuePrefix: 'Bearer ' + params: + - token + allowMissing: true + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml index 9857cb58da2..a4682250ad4 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-ratelimit.yaml @@ -27,14 +27,15 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://192.168.1.250/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://192.168.1.250/jwt/public-key/jwks.json - name: "second-route" hostname: "*" rateLimit: diff --git a/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml b/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml index 4ff905bdc5d..a5b72e0ff53 100644 --- a/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/jwt-single-route-single-match.yaml @@ -12,14 +12,15 @@ http: hostname: "*" pathMatch: exact: "foo/bar" - jwt: - providers: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJWKS: - uri: https://localhost/jwt/public-key/jwks.json + security: + jwt: + providers: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJWKS: + uri: https://localhost/jwt/public-key/jwks.json destination: name: "first-route-dest" settings: diff --git a/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml b/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml index 36984ea69f6..e77e1262245 100644 --- a/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/mixed-tls-jwt-authn.yaml @@ -8,11 +8,12 @@ http: mergeSlashes: true escapedSlashesAction: UnescapeAndRedirect tls: - - name: first-listener - # byte slice representation of "cert-data" - serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] - # byte slice representation of "key-data" - privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + certificates: + - name: first-listener + # byte slice representation of "cert-data" + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + # byte slice representation of "key-data" + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] routes: - name: "first-route" hostname: "*" diff --git a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml index bec261bee5b..07075307b1b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/multiple-listeners-same-port-with-different-filters.yaml @@ -33,9 +33,10 @@ http: port: 8080 protocol: HTTP weight: 1 - basicAuth: - name: securitypolicy/default/policy-for-http-route-1 - users: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" + security: + basicAuth: + name: securitypolicy/default/policy-for-http-route-1 + users: "dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=" - name: httproute/default/httproute-2/rule/0/match/0/www_foo_com hostname: www.foo.com isHTTP2: false @@ -55,24 +56,25 @@ http: port: 8080 protocol: HTTP weight: 1 - extAuth: - name: securitypolicy/default/policy-for-http-route-2 - failOpen: true - http: - authority: http-backend.envoy-gateway:80 - destination: - name: securitypolicy/default/policy-for-http-route-2/envoy-gateway/http-backend - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 80 - protocol: HTTP - weight: 1 - headersToBackend: - - header1 - - header2 - path: /auth + security: + extAuth: + name: securitypolicy/default/policy-for-http-route-2 + failOpen: true + http: + authority: http-backend.envoy-gateway:80 + destination: + name: securitypolicy/default/policy-for-http-route-2/envoy-gateway/http-backend + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 80 + protocol: HTTP + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth - name: default/gateway-2/http address: 0.0.0.0 hostnames: @@ -102,18 +104,19 @@ http: port: 8080 protocol: HTTP weight: 1 - oidc: - name: securitypolicy/default/policy-for-gateway-2 - clientID: client.oauth.foo.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - provider: - authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth - tokenEndpoint: https://oauth.foo.com/token - scopes: - - openid - - email - - profile - redirectURL: "https://www.example.com/foo/oauth2/callback" - redirectPath: "/foo/oauth2/callback" - logoutPath: "/foo/logout" - cookieSuffix: 5F93C2E4 + security: + oidc: + name: securitypolicy/default/policy-for-gateway-2 + clientID: client.oauth.foo.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + provider: + authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + tokenEndpoint: https://oauth.foo.com/token + scopes: + - openid + - email + - profile + redirectURL: "https://www.example.com/foo/oauth2/callback" + redirectPath: "/foo/oauth2/callback" + logoutPath: "/foo/logout" + cookieSuffix: 5F93C2E4 diff --git a/internal/xds/translator/testdata/in/xds-ir/mutual-tls-required-client-certificate-disabled.yaml b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-required-client-certificate-disabled.yaml new file mode 100644 index 00000000000..585b2b6a40f --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/mutual-tls-required-client-certificate-disabled.yaml @@ -0,0 +1,35 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + tls: + alpnProtocols: + - h2 + - http/1.1 + certificates: + - name: secret-1 + # byte slice representation of "key-data" + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + # byte slice representation of "key-data" + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + - name: secret-2 + serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + privateKey: [107, 101, 121, 45, 100, 97, 116, 97] + caCertificate: + name: ca-cert + certificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + requireClientCertificate: false + routes: + - name: "first-route" + hostname: "*" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml b/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml index ea7ebf48a4d..216cd9c90ad 100644 --- a/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/mutual-tls.yaml @@ -23,6 +23,7 @@ http: caCertificate: name: ca-cert certificate: [99, 101, 114, 116, 45, 100, 97, 116, 97] + requireClientCertificate: true routes: - name: "first-route" hostname: "*" diff --git a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml index e2ef1ca7a0f..b2e395f8320 100644 --- a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml @@ -18,24 +18,25 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - oidc: - name: securitypolicy/default/policy-for-first-route - clientID: client.oauth.foo.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= - provider: - authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth - tokenEndpoint: https://oauth.foo.com/token - scopes: - - openid - - email - - profile - resources: - - api - redirectURL: "https://www.example.com/foo/oauth2/callback" - redirectPath: "/foo/oauth2/callback" - logoutPath: "/foo/logout" - cookieSuffix: 5F93C2E4 + security: + oidc: + name: securitypolicy/default/policy-for-first-route + clientID: client.oauth.foo.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= + provider: + authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + tokenEndpoint: https://oauth.foo.com/token + scopes: + - openid + - email + - profile + resources: + - api + redirectURL: "https://www.example.com/foo/oauth2/callback" + redirectPath: "/foo/oauth2/callback" + logoutPath: "/foo/logout" + cookieSuffix: 5F93C2E4 - name: "second-route" hostname: "*" pathMatch: @@ -46,21 +47,22 @@ http: - endpoints: - host: "1.2.3.4" port: 50000 - oidc: - name: securitypolicy/default/policy-for-second-route - clientID: client.oauth.bar.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= - provider: - authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth - tokenEndpoint: https://oauth.bar.com/token - scopes: - - openid - - email - - profile - resources: - - api - redirectURL: "https://www.example.com/bar/oauth2/callback" - redirectPath: "/bar/oauth2/callback" - logoutPath: "/bar/logout" - cookieSuffix: 5f93c2e4 + security: + oidc: + name: securitypolicy/default/policy-for-second-route + clientID: client.oauth.bar.com + clientSecret: Y2xpZW50MTpzZWNyZXQK + hmacSecret: qrOYACHXoe7UEDI/raOjNSx+Z9ufXSc/22C3T6X/zPY= + provider: + authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth + tokenEndpoint: https://oauth.bar.com/token + scopes: + - openid + - email + - profile + resources: + - api + redirectURL: "https://www.example.com/bar/oauth2/callback" + redirectPath: "/bar/oauth2/callback" + logoutPath: "/bar/logout" + cookieSuffix: 5f93c2e4 diff --git a/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml new file mode 100644 index 00000000000..56a4b8d4869 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/ratelimit-endpoint-stats.yaml @@ -0,0 +1,66 @@ +metrics: + enablePerEndpointStats: true +http: + - name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "first-route" + hostname: "*" + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + exact: "one" + limit: + requests: 5 + unit: second + pathMatch: + exact: "foo/bar" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - name: "second-route" + hostname: "*" + rateLimit: + global: + rules: + - headerMatches: + - name: "x-user-id" + distinct: true + limit: + requests: 5 + unit: second + pathMatch: + exact: "example" + destination: + name: "second-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - name: "third-route" + hostname: "*" + rateLimit: + global: + rules: + - limit: + requests: 5 + unit: second + pathMatch: + exact: "test" + destination: + name: "third-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-endpoint-stats.yaml new file mode 100644 index 00000000000..60176773c96 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-endpoint-stats.yaml @@ -0,0 +1,15 @@ +name: "metrics-endpoint-stats" +metrics: + enablePerEndpointStats: true +tcp: +- name: "tcp-route-enable-endpoint-stats" + address: "0.0.0.0" + port: 10080 + destination: + name: "tcp-route-simple-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml new file mode 100644 index 00000000000..4a566033560 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml @@ -0,0 +1,44 @@ +name: "tracing" +metrics: + enablePerEndpointStats: true +tracing: + serviceName: "fake-name.fake-ns" + samplingRate: 90 + customTags: + "literal1": + type: Literal + literal: + value: "value1" + "env1": + type: Environment + environment: + name: "env1" + defaultValue: "-" + "req1": + type: RequestHeader + requestHeader: + name: "X-Request-Id" + defaultValue: "-" + host: otel-collector.monitoring.svc.cluster.local + port: 4317 +http: + - name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + directResponse: + body: "Unknown custom filter type: UnsupportedType" + statusCode: 500 diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml index d67ab2d015f..674eb66acef 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml @@ -17,9 +17,8 @@ tracing: requestHeader: name: "X-Request-Id" defaultValue: "-" - provider: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + host: otel-collector.monitoring.svc.cluster.local + port: 4317 http: - name: "first-listener" address: "0.0.0.0" diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml new file mode 100644 index 00000000000..4b5b9982aee --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml @@ -0,0 +1,15 @@ +name: "metrics-endpoint-stats" +metrics: + enablePerEndpointStats: true +udp: +- name: "udp-route-enable-endpoint-stats" + address: "0.0.0.0" + port: 10080 + destination: + name: "udp-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/wasm.yaml b/internal/xds/translator/testdata/in/xds-ir/wasm.yaml new file mode 100644 index 00000000000..a879c182731 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/wasm.yaml @@ -0,0 +1,84 @@ +http: +- address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-1/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + wasm: + - config: + parameter1: + key1: value1 + parameter2: + key2: + key3: value3 + failOpen: true + httpWasmCode: + sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 + url: https://www.test.com/wasm-filter-3.wasm + name: envoyextensionpolicy/default/policy-for-http-route/0 + wasmName: wasm-filter-3 + - backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-2/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /bar + wasm: + - config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + failOpen: false + httpWasmCode: + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + url: https://www.example.com/wasm-filter-1.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + wasmName: wasm-filter-1 + rootID: my-root-id + - config: + parameter1: value1 + parameter2: value2 + failOpen: false + httpWasmCode: + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + url: https://www.example.com/wasm-filter-2.wasm + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + wasmName: wasm-filter-2 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml new file mode 100644 index 00000000000..ac33653a54f --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml @@ -0,0 +1,53 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: direct-route-dest + lbPolicy: LEAST_REQUEST + name: direct-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: otel-collector.default.svc.cluster.local + portValue: 4317 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: accesslog|otel-collector.default.svc.cluster.local|4317/backend/0 + name: accesslog|otel-collector.default.svc.cluster.local|4317 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + trackClusterStats: + perEndpointStats: true + type: STRICT_DNS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.endpoints.yaml new file mode 100644 index 00000000000..20c80b3aaaa --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: direct-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: direct-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml new file mode 100644 index 00000000000..e6d5535eb15 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.listeners.yaml @@ -0,0 +1,144 @@ +- accessLog: + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + textFormatSource: + inlineString: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + path: /dev/stdout + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + jsonFormat: + method: '%REQ(:METHOD)%' + path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%' + protocol: '%PROTOCOL%' + response_code: '%RESPONSE_CODE%' + start_time: '%START_TIME%' + path: /dev/stdout + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.open_telemetry + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig + attributes: + values: + - key: k8s.namespace.name + value: + stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%' + - key: k8s.pod.name + value: + stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%' + - key: response_code + value: + stringValue: '%RESPONSE_CODE%' + body: + stringValue: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + commonConfig: + grpcService: + envoyGrpc: + authority: otel-collector.default.svc.cluster.local + clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + logName: otel_envoy_accesslog + transportApiVersion: V3 + resourceAttributes: + values: + - key: cluster_name + value: + stringValue: cluster1 + address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + textFormatSource: + inlineString: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + path: /dev/stdout + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + logFormat: + jsonFormat: + method: '%REQ(:METHOD)%' + path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%' + protocol: '%PROTOCOL%' + response_code: '%RESPONSE_CODE%' + start_time: '%START_TIME%' + path: /dev/stdout + - name: envoy.access_loggers.open_telemetry + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig + attributes: + values: + - key: k8s.namespace.name + value: + stringValue: '%ENVIRONMENT(ENVOY_GATEWAY_NAMESPACE)%' + - key: k8s.pod.name + value: + stringValue: '%ENVIRONMENT(ENVOY_POD_NAME)%' + - key: response_code + value: + stringValue: '%RESPONSE_CODE%' + body: + stringValue: | + [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" + commonConfig: + grpcService: + envoyGrpc: + authority: otel-collector.default.svc.cluster.local + clusterName: accesslog|otel-collector.default.svc.cluster.local|4317 + logName: otel_envoy_accesslog + transportApiVersion: V3 + resourceAttributes: + values: + - key: cluster_name + value: + stringValue: cluster1 + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.routes.yaml new file mode 100644 index 00000000000..d4a7fa5ae20 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - directResponse: + body: + inlineString: 'Unknown custom filter type: UnsupportedType' + status: 500 + match: + prefix: / + name: direct-route diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml index bdf4ec12fab..fbc693c569a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.listeners.yaml @@ -15,17 +15,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1 + name: envoy.filters.http.basic_auth typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth users: inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - - disabled: true - name: envoy.filters.http.basic_auth/securitypolicy/default/policy-for-gateway-1 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth - users: - inlineBytes: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml index c7196e28f6f..7e51086d2eb 100644 --- a/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/basic-auth.routes.yaml @@ -13,9 +13,10 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + envoy.filters.http.basic_auth: + '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuthPerRoute + users: + inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - match: pathSeparatedPrefix: /foo2 name: httproute/default/httproute-1/rule/1/match/0/www_foo_com @@ -24,9 +25,10 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + envoy.filters.http.basic_auth: + '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuthPerRoute + users: + inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - domains: - www.bar.com name: default/gateway-1/http/www_bar_com @@ -39,6 +41,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.basic_auth/securitypolicy/default/policy-for-gateway-1: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + envoy.filters.http.basic_auth: + '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuthPerRoute + users: + inlineBytes: Zm9vOntTSEF9WXMyM0FnLzVJT1dxWkN3OVFHYVZEZEh3SDAwPQpmb28xOntTSEF9ZGpaMTFxSFkwS09pamV5bUs3YUt2WXV2aHZNPQo= diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml index 6a277bb94f6..08b38495e69 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml @@ -32,3 +32,91 @@ outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 + lbPolicy: LEAST_REQUEST + name: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 + lbPolicy: LEAST_REQUEST + name: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 + lbPolicy: LEAST_REQUEST + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend + lbPolicy: LEAST_REQUEST + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml index 05442a9a15b..4ec680ce7fd 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml @@ -22,3 +22,23 @@ loadBalancingWeight: 1 locality: region: httproute/default/httproute-2/rule/0/backend/0 +- clusterName: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4/backend/0 +- clusterName: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2/backend/0 +- clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3/backend/0 +- clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml index a593a50af36..f822447967e 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml @@ -14,6 +14,70 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-2/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + failureModeAllow: true + grpcService: + envoyGrpc: + authority: grpc-backend-4.default:4000 + clusterName: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 + timeout: 10s + messageTimeout: 5s + processingMode: + requestBodyMode: BUFFERED + requestHeaderMode: SEND + requestTrailerMode: SKIP + responseBodyMode: STREAMED + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-1/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + failureModeAllow: true + grpcService: + envoyGrpc: + authority: grpc-backend-2.default:8000 + clusterName: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 + timeout: 10s + messageTimeout: 5s + processingMode: + requestBodyMode: BUFFERED_PARTIAL + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SEND + responseTrailerMode: SKIP + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-3.envoy-gateway:3000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.envoy-gateway:9000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend + timeout: 10s + messageTimeout: 15s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml index a7002b63f87..0daf1919cb2 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml @@ -12,6 +12,13 @@ cluster: httproute/default/httproute-1/rule/0 upgradeConfigs: - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-1/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-2/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io @@ -19,3 +26,10 @@ cluster: httproute/default/httproute-2/rule/0 upgradeConfigs: - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.clusters.yaml new file mode 100644 index 00000000000..e9ea29c138f --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.clusters.yaml @@ -0,0 +1,19 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.endpoints.yaml new file mode 100644 index 00000000000..3b3f2d09076 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.listeners.yaml new file mode 100644 index 00000000000..b327b344d25 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.listeners.yaml @@ -0,0 +1,34 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: listener-enable-endpoint-stats + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: listener-enable-endpoint-stats + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.routes.yaml new file mode 100644 index 00000000000..5f0482832e6 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-endpoint-stats.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: listener-enable-endpoint-stats + virtualHosts: + - domains: + - '*' + name: listener-enable-endpoint-stats/* + routes: + - match: + prefix: / + name: first-route + route: + cluster: first-route-dest + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml new file mode 100644 index 00000000000..5de1d1cce34 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml @@ -0,0 +1,23 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-1/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-1/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + useDownstreamProtocolConfig: + http2ProtocolOptions: {} + httpProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.endpoints.yaml new file mode 100644 index 00000000000..29bb6b4e444 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: httproute/default/httproute-1/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-1/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.listeners.yaml new file mode 100644 index 00000000000..a593a50af36 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.listeners.yaml @@ -0,0 +1,34 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: envoy-gateway/gateway-1/http + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.routes.yaml new file mode 100644 index 00000000000..19e1921fb1e --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http + virtualHosts: + - domains: + - gateway.envoyproxy.io + name: envoy-gateway/gateway-1/http/gateway_envoyproxy_io + routes: + - match: + prefix: / + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + route: + cluster: httproute/default/httproute-1/rule/0 + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/http2.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http2.clusters.yaml new file mode 100755 index 00000000000..d53a7a1b2ce --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2.clusters.yaml @@ -0,0 +1,17 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/http2.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http2.endpoints.yaml new file mode 100755 index 00000000000..3b3f2d09076 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http2.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http2.listeners.yaml new file mode 100755 index 00000000000..b0f26ec8184 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2.listeners.yaml @@ -0,0 +1,34 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 33554432 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 200 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/http2.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http2.routes.yaml new file mode 100755 index 00000000000..0b5b4bee7bb --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + prefix: / + name: first-route + route: + cluster: first-route-dest + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml index 4347e1ff749..680cb0ebb68 100644 --- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch.listeners.yaml @@ -33,6 +33,7 @@ mergeSlashes: true normalizePath: true pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + preserveExternalRequestId: true rds: configSource: ads: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.clusters.yaml new file mode 100644 index 00000000000..8ede70cf99a --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.clusters.yaml @@ -0,0 +1,53 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: localhost_443 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: localhost + portValue: 443 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: localhost_443/backend/0 + name: localhost_443 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + validationContext: + trustedCa: + filename: /etc/ssl/certs/ca-certificates.crt + sni: localhost + type: STRICT_DNS diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.endpoints.yaml new file mode 100644 index 00000000000..3b3f2d09076 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.listeners.yaml new file mode 100644 index 00000000000..f173f145470 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.listeners.yaml @@ -0,0 +1,65 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.jwt_authn + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication + providers: + first-route/example: + audiences: + - foo.com + forward: true + fromCookies: + - session_access_token + fromHeaders: + - name: Authorization + valuePrefix: 'Bearer ' + fromParams: + - token + issuer: https://www.example.com + payloadInMetadata: https://www.example.com + remoteJwks: + asyncFetch: {} + cacheDuration: 300s + httpUri: + cluster: localhost_443 + timeout: 10s + uri: https://localhost/jwt/public-key/jwks.json + retryPolicy: {} + requirementMap: + first-route: + requiresAny: + requirements: + - providerName: first-route/example + - allowMissing: {} + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-optional.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.routes.yaml new file mode 100644 index 00000000000..321ecc1ced2 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-optional.routes.yaml @@ -0,0 +1,18 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + path: foo/bar + name: first-route + route: + cluster: first-route-dest + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.jwt_authn: + '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig + requirementName: first-route diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.secrets.yaml new file mode 100644 index 00000000000..ad88ffe43cd --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol.secrets.yaml @@ -0,0 +1,12 @@ +- name: secret-1 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= +- name: secret-2 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml index 7a0c933174e..d53a7a1b2ce 100644 --- a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.clusters.yaml @@ -1,4 +1,7 @@ -- commonLbConfig: +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: localityWeightedLbConfig: {} connectTimeout: 10s dnsLookupFamily: V4_ONLY @@ -12,34 +15,3 @@ outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS -- commonLbConfig: - localityWeightedLbConfig: {} - connectTimeout: 10s - dnsLookupFamily: V4_ONLY - dnsRefreshRate: 30s - lbPolicy: LEAST_REQUEST - loadAssignment: - clusterName: localhost_443 - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: localhost - portValue: 443 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: {} - name: localhost_443 - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 - respectDnsTtl: true - transportSocket: - name: envoy.transport_sockets.tls - typedConfig: - '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext - commonTlsContext: - validationContext: - trustedCa: - filename: /etc/ssl/certs/ca-certificates.crt - type: STRICT_DNS diff --git a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.endpoints.yaml index 0d68b430c20..3b3f2d09076 100644 --- a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.endpoints.yaml @@ -8,4 +8,5 @@ portValue: 50000 loadBalancingWeight: 1 loadBalancingWeight: 1 - locality: {} + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml index 85bb8b4ac73..5fa3f9246df 100644 --- a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.listeners.yaml @@ -2,6 +2,7 @@ socketAddress: address: 0.0.0.0 portValue: 10080 + drainType: MODIFY_ONLY filterChains: - filters: - name: envoy.filters.network.http_connection_manager @@ -14,26 +15,6 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: - - name: envoy.filters.http.jwt_authn - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication - providers: - first-route/example: - audiences: - - foo.com - issuer: https://www.example.com - payloadInMetadata: https://www.example.com - remoteJwks: - asyncFetch: {} - cacheDuration: 300s - httpUri: - cluster: localhost_443 - timeout: 5s - uri: https://localhost/jwt/public-key/jwks.json - retryPolicy: {} - requirementMap: - first-route: - providerName: first-route/example - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -48,8 +29,6 @@ routeConfigName: first-listener serverHeaderTransformation: PASS_THROUGH statPrefix: https - upgradeConfigs: - - upgradeType: websocket useRemoteAddress: true transportSocket: name: envoy.transport_sockets.tls diff --git a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.routes.yaml index c73bec09093..75d30a0592a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/mixed-tls-jwt-authn.routes.yaml @@ -10,7 +10,5 @@ name: first-route route: cluster: first-route-dest - typedPerFilterConfig: - envoy.filters.http.jwt_authn: - '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig - requirementName: first-route + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml index d9a20682c59..cec7fd427db 100755 --- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml @@ -35,7 +35,7 @@ uri: http://http-backend.envoy-gateway:80/auth transportApiVersion: V3 - disabled: true - name: envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1 + name: envoy.filters.http.basic_auth typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth users: @@ -94,7 +94,7 @@ uri: http://http-backend.envoy-gateway:80/auth transportApiVersion: V3 - disabled: true - name: envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1 + name: envoy.filters.http.basic_auth typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth users: diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml index 8474fe67c93..ae520e2676d 100755 --- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml @@ -18,9 +18,10 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.basic_auth/securitypolicy/default/policy-for-http-route-1: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + envoy.filters.http.basic_auth: + '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuthPerRoute + users: + inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= - match: pathSeparatedPrefix: /foo2 name: httproute/default/httproute-2/rule/0/match/0/www_foo_com diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.secrets.yaml new file mode 100644 index 00000000000..81afea10735 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.secrets.yaml @@ -0,0 +1,8 @@ +- genericSecret: + secret: + inlineBytes: Y2xpZW50MTpzZWNyZXQK + name: oauth2/client_secret/securitypolicy/default/policy-for-gateway-2 +- genericSecret: + secret: + inlineBytes: "" + name: oauth2/hmac_secret/securitypolicy/default/policy-for-gateway-2 diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.clusters.yaml new file mode 100644 index 00000000000..d53a7a1b2ce --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.clusters.yaml @@ -0,0 +1,17 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.endpoints.yaml new file mode 100644 index 00000000000..3b3f2d09076 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.listeners.yaml new file mode 100644 index 00000000000..aa3c5612dfa --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.listeners.yaml @@ -0,0 +1,57 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + drainType: MODIFY_ONLY + filterChains: + - filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: https + useRemoteAddress: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + commonTlsContext: + alpnProtocols: + - h2 + - http/1.1 + tlsCertificateSdsSecretConfigs: + - name: secret-1 + sdsConfig: + ads: {} + resourceApiVersion: V3 + - name: secret-2 + sdsConfig: + ads: {} + resourceApiVersion: V3 + validationContextSdsSecretConfig: + name: ca-cert + sdsConfig: + ads: {} + resourceApiVersion: V3 + requireClientCertificate: false + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.routes.yaml new file mode 100644 index 00000000000..0b5b4bee7bb --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + prefix: / + name: first-route + route: + cluster: first-route-dest + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.secrets.yaml new file mode 100644 index 00000000000..052882baf5f --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/mutual-tls-required-client-certificate-disabled.secrets.yaml @@ -0,0 +1,16 @@ +- name: secret-1 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= +- name: secret-2 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= +- name: ca-cert + validationContext: + trustedCa: + inlineBytes: Y2VydC1kYXRh diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml new file mode 100644 index 00000000000..21ea0681611 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml @@ -0,0 +1,104 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: second-route-dest + lbPolicy: LEAST_REQUEST + name: second-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: third-route-dest + lbPolicy: LEAST_REQUEST + name: third-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: ratelimit_cluster + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: envoy-ratelimit.envoy-gateway-system.svc.cluster.local + portValue: 8081 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: ratelimit_cluster/backend/0 + name: ratelimit_cluster + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + trackClusterStats: + perEndpointStats: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + tlsCertificates: + - certificateChain: + filename: /certs/tls.crt + privateKey: + filename: /certs/tls.key + validationContext: + trustedCa: + filename: /certs/ca.crt + type: STRICT_DNS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.endpoints.yaml new file mode 100644 index 00000000000..475b89a087c --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.endpoints.yaml @@ -0,0 +1,36 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 +- clusterName: second-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: second-route-dest/backend/0 +- clusterName: third-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: third-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.listeners.yaml new file mode 100644 index 00000000000..d6f261b7cd5 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.listeners.yaml @@ -0,0 +1,44 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.ratelimit + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit + domain: first-listener + enableXRatelimitHeaders: DRAFT_VERSION_03 + rateLimitService: + grpcService: + envoyGrpc: + clusterName: ratelimit_cluster + transportApiVersion: V3 + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.routes.yaml new file mode 100644 index 00000000000..479c2cd143c --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.routes.yaml @@ -0,0 +1,57 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + path: foo/bar + name: first-route + route: + cluster: first-route-dest + rateLimits: + - actions: + - genericKey: + descriptorKey: first-route + descriptorValue: first-route + - headerValueMatch: + descriptorKey: rule-0-match-0 + descriptorValue: rule-0-match-0 + expectMatch: true + headers: + - name: x-user-id + stringMatch: + exact: one + upgradeConfigs: + - upgradeType: websocket + - match: + path: example + name: second-route + route: + cluster: second-route-dest + rateLimits: + - actions: + - genericKey: + descriptorKey: second-route + descriptorValue: second-route + - requestHeaders: + descriptorKey: rule-0-match-0 + headerName: x-user-id + upgradeConfigs: + - upgradeType: websocket + - match: + path: test + name: third-route + route: + cluster: third-route-dest + rateLimits: + - actions: + - genericKey: + descriptorKey: third-route + descriptorValue: third-route + - genericKey: + descriptorKey: rule-0-match--1 + descriptorValue: rule-0-match--1 + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.secrets.yaml new file mode 100644 index 00000000000..ad88ffe43cd --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/suppress-envoy-headers.secrets.yaml @@ -0,0 +1,12 @@ +- name: secret-1 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= +- name: secret-2 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml new file mode 100644 index 00000000000..4387d9b31e0 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.clusters.yaml @@ -0,0 +1,19 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: tcp-route-simple-dest + lbPolicy: LEAST_REQUEST + name: tcp-route-simple-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml new file mode 100644 index 00000000000..7eb06a08f40 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.endpoints.yaml @@ -0,0 +1,18 @@ +- clusterName: tcp-route-simple-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: tcp-route-simple-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml new file mode 100644 index 00000000000..7cf2660fa72 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.listeners.yaml @@ -0,0 +1,14 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + drainType: MODIFY_ONLY + filterChains: + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + cluster: tcp-route-simple-dest + statPrefix: tcp + name: tcp-route-enable-endpoint-stats + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.routes.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-endpoint-stats.routes.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.secrets.yaml new file mode 100644 index 00000000000..d4d502ac098 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-tls-terminate.secrets.yaml @@ -0,0 +1,6 @@ +- name: envoy-gateway-tls-secret-1 + tlsCertificate: + certificateChain: + inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNxRENDQVpBQ0NRREVNZ1lZblFyQ29EQU5CZ2txaGtpRzl3MEJBUXNGQURBV01SUXdFZ1lEVlFRRERBdG0KYjI4dVltRnlMbU52YlRBZUZ3MHlNekF4TURVeE16UXpNalJhRncweU5EQXhNRFV4TXpRek1qUmFNQll4RkRBUwpCZ05WQkFNTUMyWnZieTVpWVhJdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUFuZEh6d21wS2NUSUViamhGZ2RXd1RSTjc1Y3A4b3VsWnhMMUdydlI2SXc3ejdqaTBSNFcvTm85bkdmOU0KWVAyQ1JqaXN6NTFtd3hTeGVCcm9jTGVBK21reGkxK2lEdk5kQytyU0x4MTN6RUxTQ25xYnVzUHM3bUdmSlpxOAo5TGhlbmx5bzQzaDVjYTZINUxqTXd1L1JHVWlGMzFYck5yaVlGQlB2RTJyQitkd24vTkVrUTRoOFJxcXlwcmtuCkYvcWM5Sk1ZQVlGRld1VkNwa0lFbmRYMUN5dlFOT2FkZmN2cmd6dDV2SmwwT2kxQWdyaU5hWGJFUEdudWY3STQKcXBCSEdVWE5lMVdsOVdlVklxS1g0T2FFWERWQzZGQzdHOHptZWVMVzFBa1lFVm5pcFg2b1NCK0JjL1NIVlZOaApzQkxSbXRuc3pmTnRUMlFyZCttcGt4ODBaUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1VKOElDCkJveUVqT3V3enBHYVJoR044QjRqT1B6aHVDT0V0ZDM3UzAybHUwN09IenlCdmJzVEd6S3dCZ0x5bVdmR2tINEIKajdDTHNwOEZ6TkhLWnVhQmdwblo5SjZETE9Od2ZXZTJBWXA3TGRmT0tWQlVkTVhRaU9tN2pKOUhob0Ntdk1ONwpic2pjaFdKb013ckZmK3dkQUthdHowcUFQeWhMeWUvRnFtaVZ4a09SWmF3K1Q5bURaK0g0OXVBU2d1SnVOTXlRClY2RXlYNmd0Z1dxMzc2SHZhWE1TLzNoYW1Zb1ZXWEk1TXhpUE9ZeG5BQmtKQjRTQ2dJUmVqYkpmVmFRdG9RNGEKejAyaVVMZW5ESUllUU9Zb2JLY01CWGYxQjRQQVFtc2VocVZJYnpzUUNHaTU0VkRyczZiWmQvN0pzMXpDcHBncwpKaUQ1SXFNaktXRHdxN2FLCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + privateKey: + inlineBytes: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K diff --git a/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.secrets.yaml new file mode 100644 index 00000000000..ad88ffe43cd --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tls-with-ciphers-versions-alpn.secrets.yaml @@ -0,0 +1,12 @@ +- name: secret-1 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= +- name: secret-2 + tlsCertificate: + certificateChain: + inlineBytes: Y2VydC1kYXRh + privateKey: + inlineBytes: a2V5LWRhdGE= diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml new file mode 100644 index 00000000000..24a732d8e70 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml @@ -0,0 +1,53 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: direct-route-dest + lbPolicy: LEAST_REQUEST + name: direct-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: tracing|otel-collector.monitoring.svc.cluster.local|4317 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: otel-collector.monitoring.svc.cluster.local + portValue: 4317 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: tracing|otel-collector.monitoring.svc.cluster.local|4317/backend/0 + name: tracing|otel-collector.monitoring.svc.cluster.local|4317 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + trackClusterStats: + perEndpointStats: true + type: STRICT_DNS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.endpoints.yaml new file mode 100644 index 00000000000..20c80b3aaaa --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: direct-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: direct-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml new file mode 100644 index 00000000000..c8277f1e190 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.listeners.yaml @@ -0,0 +1,63 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + tracing: + clientSampling: + value: 100 + customTags: + - environment: + defaultValue: '-' + name: env1 + tag: env1 + - literal: + value: value1 + tag: literal1 + - requestHeader: + defaultValue: '-' + name: X-Request-Id + tag: req1 + overallSampling: + value: 100 + provider: + name: envoy.tracers.opentelemetry + typedConfig: + '@type': type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig + grpcService: + envoyGrpc: + authority: otel-collector.monitoring.svc.cluster.local + clusterName: tracing|otel-collector.monitoring.svc.cluster.local|4317 + serviceName: fake-name.fake-ns + randomSampling: + value: 90 + spawnUpstreamSpan: true + useRemoteAddress: true + drainType: MODIFY_ONLY + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.routes.yaml new file mode 100644 index 00000000000..d4a7fa5ae20 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - directResponse: + body: + inlineString: 'Unknown custom filter type: UnsupportedType' + status: 500 + match: + prefix: / + name: direct-route diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.clusters.yaml new file mode 100644 index 00000000000..e26cb444c5c --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.clusters.yaml @@ -0,0 +1,19 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: udp-route-dest + lbPolicy: LEAST_REQUEST + name: udp-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + trackClusterStats: + perEndpointStats: true + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.endpoints.yaml new file mode 100644 index 00000000000..2e3c84e672c --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.endpoints.yaml @@ -0,0 +1,18 @@ +- clusterName: udp-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: udp-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.listeners.yaml new file mode 100644 index 00000000000..8d9eaea1141 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.listeners.yaml @@ -0,0 +1,18 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + protocol: UDP + listenerFilters: + - name: envoy.filters.udp_listener.udp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig + matcher: + onNoMatch: + action: + name: route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route + cluster: udp-route-dest + statPrefix: service + name: udp-route-enable-endpoint-stats diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.routes.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-endpoint-stats.routes.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml new file mode 100755 index 00000000000..a70d771a1db --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml @@ -0,0 +1,106 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-1/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-1/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-2/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-2/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: www_test_com_443 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: www.test.com + portValue: 443 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: www_test_com_443/backend/0 + name: www_test_com_443 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + validationContext: + trustedCa: + filename: /etc/ssl/certs/ca-certificates.crt + sni: www.test.com + type: STRICT_DNS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: www_example_com_443 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: www.example.com + portValue: 443 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: www_example_com_443/backend/0 + name: www_example_com_443 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + validationContext: + trustedCa: + filename: /etc/ssl/certs/ca-certificates.crt + sni: www.example.com + type: STRICT_DNS diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.endpoints.yaml new file mode 100755 index 00000000000..05442a9a15b --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.endpoints.yaml @@ -0,0 +1,24 @@ +- clusterName: httproute/default/httproute-1/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-1/rule/0/backend/0 +- clusterName: httproute/default/httproute-2/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-2/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml new file mode 100755 index 00000000000..8f0cc2eaf23 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml @@ -0,0 +1,93 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - disabled: true + name: envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-http-route/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":{"key1":"value1"},"parameter2":{"key2":{"key3":"value3"}}}' + failOpen: true + name: wasm-filter-3 + vmConfig: + code: + remote: + httpUri: + cluster: www_test_com_443 + timeout: 10s + uri: https://www.test.com/wasm-filter-3.wasm + sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/default/policy-for-http-route/0 + - disabled: true + name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":{"key1":"value1","key2":"value2"},"parameter2":"value3"}' + name: wasm-filter-1 + rootId: my-root-id + vmConfig: + code: + remote: + httpUri: + cluster: www_example_com_443 + timeout: 10s + uri: https://www.example.com/wasm-filter-1.wasm + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + - disabled: true + name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":"value1","parameter2":"value2"}' + name: wasm-filter-2 + vmConfig: + code: + remote: + httpUri: + cluster: www_example_com_443 + timeout: 10s + uri: https://www.example.com/wasm-filter-2.wasm + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http + serverHeaderTransformation: PASS_THROUGH + statPrefix: http + useRemoteAddress: true + drainType: MODIFY_ONLY + name: envoy-gateway/gateway-1/http + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml new file mode 100755 index 00000000000..8fb6f03a0f0 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml @@ -0,0 +1,32 @@ +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http + virtualHosts: + - domains: + - www.example.com + name: envoy-gateway/gateway-1/http/www_example_com + routes: + - match: + pathSeparatedPrefix: /foo + name: httproute/default/httproute-1/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-1/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-http-route/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + pathSeparatedPrefix: /bar + name: httproute/default/httproute-2/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-2/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go index e0ace0d49cc..44e80681c59 100644 --- a/internal/xds/translator/tracing.go +++ b/internal/xds/translator/tracing.go @@ -33,8 +33,8 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e GrpcService: &corev3.GrpcService{ TargetSpecifier: &corev3.GrpcService_EnvoyGrpc_{ EnvoyGrpc: &corev3.GrpcService_EnvoyGrpc{ - ClusterName: buildClusterName("tracing", tracing.Provider.Host, uint32(tracing.Provider.Port)), - Authority: tracing.Provider.Host, + ClusterName: buildClusterName("tracing", tracing.Host, tracing.Port), + Authority: tracing.Host, }, }, }, @@ -46,7 +46,7 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e return nil, fmt.Errorf("failed to marshal OpenTelemetryConfig: %w", err) } - tags := []*tracingtype.CustomTag{} + tags := make([]*tracingtype.CustomTag, 0, len(tracing.CustomTags)) // TODO: consider add some default tags for better UX for k, v := range tracing.CustomTags { switch v.Type { @@ -106,7 +106,7 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e Value: 100.0, }, RandomSampling: &xdstype.Percent{ - Value: float64(*tracing.SamplingRate), + Value: tracing.SamplingRate, }, Provider: &tracecfg.Tracing_Http{ Name: "envoy.tracers.opentelemetry", @@ -119,23 +119,24 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e }, nil } -func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Tracing) error { +func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Tracing, metrics *ir.Metrics) error { if tracing == nil { return nil } - clusterName := buildClusterName("tracing", tracing.Provider.Host, uint32(tracing.Provider.Port)) + clusterName := buildClusterName("tracing", tracing.Host, tracing.Port) ds := &ir.DestinationSetting{ Weight: ptr.To[uint32](1), Protocol: ir.GRPC, - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(tracing.Provider.Host, uint32(tracing.Provider.Port))}, + Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(tracing.Host, tracing.Port)}, } if err := addXdsCluster(tCtx, &xdsClusterArgs{ name: clusterName, settings: []*ir.DestinationSetting{ds}, tSocket: nil, endpointType: EndpointTypeDNS, + metrics: metrics, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index adc74d53fd6..eaef03e97b5 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -24,6 +24,7 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/wrapperspb" + "k8s.io/utils/ptr" extensionTypes "github.com/envoyproxy/gateway/internal/extension/types" "github.com/envoyproxy/gateway/internal/ir" @@ -86,11 +87,11 @@ func (t *Translator) Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) errs = errors.Join(errs, err) } - if err := processTCPListenerXdsTranslation(tCtx, ir.TCP, ir.AccessLog); err != nil { + if err := processTCPListenerXdsTranslation(tCtx, ir.TCP, ir.AccessLog, ir.Metrics); err != nil { errs = errors.Join(errs, err) } - if err := processUDPListenerXdsTranslation(tCtx, ir.UDP, ir.AccessLog); err != nil { + if err := processUDPListenerXdsTranslation(tCtx, ir.UDP, ir.AccessLog, ir.Metrics); err != nil { errs = errors.Join(errs, err) } @@ -98,11 +99,11 @@ func (t *Translator) Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) errs = errors.Join(errs, err) } - if err := processClusterForAccessLog(tCtx, ir.AccessLog); err != nil { + if err := processClusterForAccessLog(tCtx, ir.AccessLog, ir.Metrics); err != nil { errs = errors.Join(errs, err) } - if err := processClusterForTracing(tCtx, ir.Tracing); err != nil { + if err := processClusterForTracing(tCtx, ir.Tracing, ir.Metrics); err != nil { errs = errors.Join(errs, err) } @@ -126,36 +127,67 @@ func (t *Translator) processHTTPListenerXdsTranslation( // errors and return them at the end. var errs error for _, httpListener := range httpListeners { - addFilterChain := true - var xdsRouteCfg *routev3.RouteConfiguration - - // Search for an existing listener, if it does not exist, create one. - xdsListener := findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_TCP) - var quicXDSListener *listenerv3.Listener - enabledHTTP3 := httpListener.HTTP3 != nil - if xdsListener == nil { - xdsListener = buildXdsTCPListener(httpListener.Name, httpListener.Address, httpListener.Port, httpListener.TCPKeepalive, httpListener.Connection, accessLog) - if enabledHTTP3 { + var ( + http3Enabled = httpListener.HTTP3 != nil // Whether HTTP3 is enabled + tcpXDSListener *listenerv3.Listener // TCP Listener for HTTP1/HTTP2 traffic + quicXDSListener *listenerv3.Listener // UDP(QUIC) Listener for HTTP3 traffic + xdsListenerOnSameAddressPortExists bool // Whether a listener already exists on the same address + port combination + tlsEnabled bool // Whether TLS is enabled for the listener + xdsRouteCfg *routev3.RouteConfiguration // The route config is used by both the TCP and QUIC listeners + addHCM bool // Whether to add an HCM(HTTP Connection Manager filter) to the listener's TCP filter chain + err error + ) + + // Search for an existing TCP listener on the same address + port combination. + tcpXDSListener = findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_TCP) + xdsListenerOnSameAddressPortExists = tcpXDSListener != nil + tlsEnabled = httpListener.TLS != nil + + switch { + // If no existing listener exists, create a new one. + case !xdsListenerOnSameAddressPortExists: + // Create a new UDP(QUIC) listener for HTTP3 traffic if HTTP3 is enabled + if http3Enabled { quicXDSListener = buildXdsQuicListener(httpListener.Name, httpListener.Address, httpListener.Port, accessLog) - if err := tCtx.AddXdsResource(resourcev3.ListenerType, quicXDSListener); err != nil { - return err + if err = tCtx.AddXdsResource(resourcev3.ListenerType, quicXDSListener); err != nil { + errs = errors.Join(errs, err) + continue } } - if err := tCtx.AddXdsResource(resourcev3.ListenerType, xdsListener); err != nil { - // skip this listener if failed to add xds listener to the - // resource version table. Normally, this should not happen. + + // Create a new TCP listener for HTTP1/HTTP2 traffic. + tcpXDSListener = buildXdsTCPListener(httpListener.Name, httpListener.Address, httpListener.Port, httpListener.TCPKeepalive, httpListener.Connection, accessLog) + if err = tCtx.AddXdsResource(resourcev3.ListenerType, tcpXDSListener); err != nil { errs = errors.Join(errs, err) continue } - } else if httpListener.TLS == nil { + + // We need to add an HCM to the newly created listener. + addHCM = true + case xdsListenerOnSameAddressPortExists && !tlsEnabled: + // If a xds listener exists, and Gateway HTTP Listener does not enable TLS, + // we use the listener's default TCP filter chain because we can not + // differentiate the HTTP traffic at the TCP filter chain level using SNI. + // + // A HCM(HTTP Connection Manager filter) is added to the listener's + // default filter chain if it has not yet been added. + // + // The HCM is configured with a RouteConfiguration, which is used to + // route HTTP traffic to the correct virtual host for all the domains + // specified in the Gateway HTTP Listener's routes. + var ( + routeName string + hasHCMInDefaultFilterChain bool + ) + // Find the route config associated with this listener that // maps to the default filter chain for http traffic - routeName := findXdsHTTPRouteConfigName(xdsListener) + // Routes for this listener will be added to this route config + routeName = findXdsHTTPRouteConfigName(tcpXDSListener) + hasHCMInDefaultFilterChain = routeName != "" + addHCM = !hasHCMInDefaultFilterChain + if routeName != "" { - // If an existing listener exists, dont create a new filter chain - // for HTTP traffic, match on the Domains field within VirtualHosts - // within the same RouteConfiguration instead - addFilterChain = false xdsRouteCfg = findXdsRouteConfig(tCtx, routeName) if xdsRouteCfg == nil { // skip this listener if failed to find xds route config @@ -163,174 +195,215 @@ func (t *Translator) processHTTPListenerXdsTranslation( continue } } + case xdsListenerOnSameAddressPortExists && tlsEnabled: + // If an existing xds listener exists, and Gateway HTTP Listener enables + // TLS, we need to create an HCM. + // + // In this case, a new filter chain is created and added to the listener, + // and the HCM is added to the new filter chain. + // The newly created filter chain is configured with a filter chain + // match to match the server names(SNI) based on the listener's hostnames. + addHCM = true } - if addFilterChain { - if err := t.addXdsHTTPFilterChain(xdsListener, httpListener, accessLog, tracing, false, httpListener.Connection); err != nil { - return err + if addHCM { + if err = t.addHCMToXDSListener(tcpXDSListener, httpListener, accessLog, tracing, false, httpListener.Connection); err != nil { + errs = errors.Join(errs, err) + continue } - if enabledHTTP3 { - if err := t.addXdsHTTPFilterChain(quicXDSListener, httpListener, accessLog, tracing, true, httpListener.Connection); err != nil { - return err + if http3Enabled { + if err = t.addHCMToXDSListener(quicXDSListener, httpListener, accessLog, tracing, true, httpListener.Connection); err != nil { + errs = errors.Join(errs, err) + continue } } } else { // When the DefaultFilterChain is shared by multiple Gateway HTTP // Listeners, we need to add the HTTP filters associated with the // HTTPListener to the HCM if they have not yet been added. - if err := t.addHTTPFiltersToHCM(xdsListener.DefaultFilterChain, httpListener); err != nil { + if err = t.addHTTPFiltersToHCM(tcpXDSListener.DefaultFilterChain, httpListener); err != nil { errs = errors.Join(errs, err) continue } - if enabledHTTP3 { - if err := t.addHTTPFiltersToHCM(quicXDSListener.DefaultFilterChain, httpListener); err != nil { + if http3Enabled { + if err = t.addHTTPFiltersToHCM(quicXDSListener.DefaultFilterChain, httpListener); err != nil { errs = errors.Join(errs, err) continue } } } - // Create a route config if we have not found one yet - if xdsRouteCfg == nil { - xdsRouteCfg = &routev3.RouteConfiguration{ - IgnorePortInHostMatching: true, - Name: httpListener.Name, - } - - if err := tCtx.AddXdsResource(resourcev3.RouteType, xdsRouteCfg); err != nil { - errs = errors.Join(errs, err) - } - } - + // Add the secrets referenced by the listener's TLS configuration to the + // resource version table. // 1:1 between IR TLSListenerConfig and xDS Secret if httpListener.TLS != nil { - for t := range httpListener.TLS.Certificates { - secret := buildXdsTLSCertSecret(httpListener.TLS.Certificates[t]) - if err := tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil { + for c := range httpListener.TLS.Certificates { + secret := buildXdsTLSCertSecret(httpListener.TLS.Certificates[c]) + if err = tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil { errs = errors.Join(errs, err) } } if httpListener.TLS.CACertificate != nil { caSecret := buildXdsTLSCaCertSecret(httpListener.TLS.CACertificate) - if err := tCtx.AddXdsResource(resourcev3.SecretType, caSecret); err != nil { + if err = tCtx.AddXdsResource(resourcev3.SecretType, caSecret); err != nil { errs = errors.Join(errs, err) } } } - // store virtual hosts by domain - vHosts := map[string]*routev3.VirtualHost{} - // keep track of order by using a list as well as the map - var vHostsList []*routev3.VirtualHost - - // Check if an extension is loaded that wants to modify xDS Routes after they have been generated - for _, httpRoute := range httpListener.Routes { - // 1:1 between IR HTTPRoute Hostname and xDS VirtualHost. - vHost := vHosts[httpRoute.Hostname] - if vHost == nil { - // Remove dots from the hostname before appending it to the virtualHost name - // since dots are special chars used in stats tag extraction in Envoy - underscoredHostname := strings.ReplaceAll(httpRoute.Hostname, ".", "_") - // Allocate virtual host for this httpRoute. - vHost = &routev3.VirtualHost{ - Name: fmt.Sprintf("%s/%s", httpListener.Name, underscoredHostname), - Domains: []string{httpRoute.Hostname}, - } - if metrics != nil && metrics.EnableVirtualHostStats { - vHost.VirtualClusters = []*routev3.VirtualCluster{ - { - Name: underscoredHostname, - Headers: []*routev3.HeaderMatcher{ - { - Name: AuthorityHeaderKey, - HeaderMatchSpecifier: &routev3.HeaderMatcher_StringMatch{ - StringMatch: &matcherv3.StringMatcher{ - MatchPattern: &matcherv3.StringMatcher_Prefix{ - Prefix: httpRoute.Hostname, - }, - }, - }, - }, - }, - }, - } - } - vHosts[httpRoute.Hostname] = vHost - vHostsList = append(vHostsList, vHost) - } - - // 1:1 between IR HTTPRoute and xDS config.route.v3.Route - xdsRoute, err := buildXdsRoute(httpRoute) - if err != nil { - // skip this route if failed to build xds route - errs = errors.Join(errs, err) - continue + // Create a route config if we have not found one yet + if xdsRouteCfg == nil { + xdsRouteCfg = &routev3.RouteConfiguration{ + IgnorePortInHostMatching: true, + Name: httpListener.Name, } - // Check if an extension want to modify the route we just generated - // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. - if err = processExtensionPostRouteHook(xdsRoute, vHost, httpRoute, t.ExtensionManager); err != nil { + if err = tCtx.AddXdsResource(resourcev3.RouteType, xdsRouteCfg); err != nil { errs = errors.Join(errs, err) } - - if enabledHTTP3 { - http3AltSvcHeader := buildHTTP3AltSvcHeader(int(httpListener.HTTP3.QUICPort)) - if xdsRoute.ResponseHeadersToAdd == nil { - xdsRoute.ResponseHeadersToAdd = make([]*corev3.HeaderValueOption, 0) - } - xdsRoute.ResponseHeadersToAdd = append(xdsRoute.ResponseHeadersToAdd, http3AltSvcHeader) - } - vHost.Routes = append(vHost.Routes, xdsRoute) - - if httpRoute.Destination != nil { - if err = processXdsCluster(tCtx, httpRoute, httpListener.HTTP1); err != nil { - errs = errors.Join(errs, err) - } - } - - if httpRoute.Mirrors != nil { - for _, mirrorDest := range httpRoute.Mirrors { - if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: mirrorDest.Name, - settings: mirrorDest.Settings, - tSocket: nil, - endpointType: EndpointTypeStatic, - }); err != nil && !errors.Is(err, ErrXdsClusterExists) { - errs = errors.Join(errs, err) - } - } - } } - for _, vHost := range vHostsList { - // Check if an extension want to modify the Virtual Host we just generated - // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. - if err := processExtensionPostVHostHook(vHost, t.ExtensionManager); err != nil { - errs = errors.Join(errs, err) - } + // Generate xDS virtual hosts and routes for the given HTTPListener, + // and add them to the xDS route config. + if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Enabled); err != nil { + errs = errors.Join(errs, err) } - xdsRouteCfg.VirtualHosts = append(xdsRouteCfg.VirtualHosts, vHostsList...) // Add all the other needed resources referenced by this filter to the // resource version table. - if err := patchResources(tCtx, httpListener.Routes); err != nil { - return err + if err = patchResources(tCtx, httpListener.Routes); err != nil { + errs = errors.Join(errs, err) } // RateLimit filter is handled separately because it relies on the global // rate limit server configuration. // Check if a ratelimit cluster exists, if not, add it, if it's needed. - if err := t.createRateLimitServiceCluster(tCtx, httpListener); err != nil { + if err = t.createRateLimitServiceCluster(tCtx, httpListener, metrics); err != nil { errs = errors.Join(errs, err) } // Check if an extension want to modify the listener that was just configured/created // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op - if err := processExtensionPostListenerHook(tCtx, xdsListener, t.ExtensionManager); err != nil { + // TODO zhaohuabing should we also process the quicXDSListener? + if err = processExtensionPostListenerHook(tCtx, tcpXDSListener, t.ExtensionManager); err != nil { + errs = errors.Join(errs, err) + } + } + + return errs +} + +// addRouteToRouteConfig generates xDS virtual hosts and routes for the given HTTPListener, +// and adds them to the provided xDS route config. +func (t *Translator) addRouteToRouteConfig( + tCtx *types.ResourceVersionTable, + xdsRouteCfg *routev3.RouteConfiguration, + httpListener *ir.HTTPListener, + metrics *ir.Metrics, + http3Enabled bool, +) error { + var ( + vHosts = map[string]*routev3.VirtualHost{} // store virtual hosts by domain + vHostList []*routev3.VirtualHost // keep track of order by using a list as well as the map + errs error // the accumulated errors + err error + ) + + // Check if an extension is loaded that wants to modify xDS Routes after they have been generated + for _, httpRoute := range httpListener.Routes { + // 1:1 between IR HTTPRoute Hostname and xDS VirtualHost. + vHost := vHosts[httpRoute.Hostname] + if vHost == nil { + // Remove dots from the hostname before appending it to the virtualHost name + // since dots are special chars used in stats tag extraction in Envoy + underscoredHostname := strings.ReplaceAll(httpRoute.Hostname, ".", "_") + // Allocate virtual host for this httpRoute. + vHost = &routev3.VirtualHost{ + Name: fmt.Sprintf("%s/%s", httpListener.Name, underscoredHostname), + Domains: []string{httpRoute.Hostname}, + } + if metrics != nil && metrics.EnableVirtualHostStats { + vHost.VirtualClusters = []*routev3.VirtualCluster{ + { + Name: underscoredHostname, + Headers: []*routev3.HeaderMatcher{ + { + Name: AuthorityHeaderKey, + HeaderMatchSpecifier: &routev3.HeaderMatcher_StringMatch{ + StringMatch: &matcherv3.StringMatcher{ + MatchPattern: &matcherv3.StringMatcher_Prefix{ + Prefix: httpRoute.Hostname, + }, + }, + }, + }, + }, + }, + } + } + vHosts[httpRoute.Hostname] = vHost + vHostList = append(vHostList, vHost) + } + + var xdsRoute *routev3.Route + // 1:1 between IR HTTPRoute and xDS config.route.v3.Route + xdsRoute, err = buildXdsRoute(httpRoute) + if err != nil { + // skip this route if failed to build xds route + errs = errors.Join(errs, err) + continue + } + + // Check if an extension want to modify the route we just generated + // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. + if err = processExtensionPostRouteHook(xdsRoute, vHost, httpRoute, t.ExtensionManager); err != nil { + errs = errors.Join(errs, err) + } + + if http3Enabled { + http3AltSvcHeader := buildHTTP3AltSvcHeader(int(httpListener.HTTP3.QUICPort)) + if xdsRoute.ResponseHeadersToAdd == nil { + xdsRoute.ResponseHeadersToAdd = make([]*corev3.HeaderValueOption, 0) + } + xdsRoute.ResponseHeadersToAdd = append(xdsRoute.ResponseHeadersToAdd, http3AltSvcHeader) + } + vHost.Routes = append(vHost.Routes, xdsRoute) + + if httpRoute.Destination != nil { + if err = processXdsCluster( + tCtx, + httpRoute, + httpListener.HTTP1, + metrics, + ); err != nil { + errs = errors.Join(errs, err) + } + } + + if httpRoute.Mirrors != nil { + for _, mirrorDest := range httpRoute.Mirrors { + if err = addXdsCluster(tCtx, &xdsClusterArgs{ + name: mirrorDest.Name, + settings: mirrorDest.Settings, + tSocket: nil, + endpointType: EndpointTypeStatic, + metrics: metrics, + }); err != nil && !errors.Is(err, ErrXdsClusterExists) { + errs = errors.Join(errs, err) + } + } + } + } + + for _, vHost := range vHostList { + // Check if an extension want to modify the Virtual Host we just generated + // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. + if err = processExtensionPostVHostHook(vHost, t.ExtensionManager); err != nil { errs = errors.Join(errs, err) } } + xdsRouteCfg.VirtualHosts = append(xdsRouteCfg.VirtualHosts, vHostList...) return errs } @@ -391,7 +464,7 @@ func buildHTTP3AltSvcHeader(port int) *corev3.HeaderValueOption { } } -func processTCPListenerXdsTranslation(tCtx *types.ResourceVersionTable, tcpListeners []*ir.TCPListener, accesslog *ir.AccessLog) error { +func processTCPListenerXdsTranslation(tCtx *types.ResourceVersionTable, tcpListeners []*ir.TCPListener, accesslog *ir.AccessLog, metrics *ir.Metrics) error { // The XDS translation is done in a best-effort manner, so we collect all // errors and return them at the end. var errs error @@ -422,6 +495,7 @@ func processTCPListenerXdsTranslation(tCtx *types.ResourceVersionTable, tcpListe healthCheck: tcpListener.HealthCheck, timeout: tcpListener.Timeout, endpointType: buildEndpointType(tcpListener.Destination.Settings), + metrics: metrics, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } @@ -444,7 +518,7 @@ func processTCPListenerXdsTranslation(tCtx *types.ResourceVersionTable, tcpListe return errs } -func processUDPListenerXdsTranslation(tCtx *types.ResourceVersionTable, udpListeners []*ir.UDPListener, accesslog *ir.AccessLog) error { +func processUDPListenerXdsTranslation(tCtx *types.ResourceVersionTable, udpListeners []*ir.UDPListener, accesslog *ir.AccessLog, metrics *ir.Metrics) error { // The XDS translation is done in a best-effort manner, so we collect all // errors and return them at the end. var errs error @@ -472,6 +546,7 @@ func processUDPListenerXdsTranslation(tCtx *types.ResourceVersionTable, udpListe timeout: udpListener.Timeout, tSocket: nil, endpointType: buildEndpointType(udpListener.Destination.Settings), + metrics: metrics, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } @@ -481,7 +556,8 @@ func processUDPListenerXdsTranslation(tCtx *types.ResourceVersionTable, udpListe // findXdsListenerByHostPort finds a xds listener with the same address, port and protocol, and returns nil if there is no match. func findXdsListenerByHostPort(tCtx *types.ResourceVersionTable, address string, port uint32, - protocol corev3.SocketAddress_Protocol) *listenerv3.Listener { + protocol corev3.SocketAddress_Protocol, +) *listenerv3.Listener { if tCtx == nil || tCtx.XdsResources == nil || tCtx.XdsResources[resourcev3.ListenerType] == nil { return nil } @@ -563,19 +639,21 @@ func findXdsEndpoint(tCtx *types.ResourceVersionTable, name string) *endpointv3. } // processXdsCluster processes a xds cluster by its endpoint address type. -func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute, http1Settings *ir.HTTP1Settings) error { +func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute, http1Settings *ir.HTTP1Settings, metrics *ir.Metrics) error { if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: httpRoute.Destination.Name, - settings: httpRoute.Destination.Settings, - tSocket: nil, - endpointType: buildEndpointType(httpRoute.Destination.Settings), - loadBalancer: httpRoute.LoadBalancer, - proxyProtocol: httpRoute.ProxyProtocol, - circuitBreaker: httpRoute.CircuitBreaker, - healthCheck: httpRoute.HealthCheck, - http1Settings: http1Settings, - timeout: httpRoute.Timeout, - tcpkeepalive: httpRoute.TCPKeepalive, + name: httpRoute.Destination.Name, + settings: httpRoute.Destination.Settings, + tSocket: nil, + endpointType: buildEndpointType(httpRoute.Destination.Settings), + loadBalancer: httpRoute.LoadBalancer, + proxyProtocol: httpRoute.ProxyProtocol, + circuitBreaker: httpRoute.CircuitBreaker, + healthCheck: httpRoute.HealthCheck, + http1Settings: http1Settings, + timeout: httpRoute.Timeout, + tcpkeepalive: httpRoute.TCPKeepalive, + metrics: metrics, + useClientProtocol: ptr.Deref(httpRoute.UseClientProtocol, false), }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } @@ -583,29 +661,6 @@ func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute return nil } -// processTLSSocket generates a xDS TransportSocket for a given TLS config. -// It also adds the necessary secrets to the resource version table. -func processTLSSocket(tlsConfig *ir.TLSUpstreamConfig, tCtx *types.ResourceVersionTable) (*corev3.TransportSocket, error) { - if tlsConfig == nil { - return nil, nil - } - // Create a secret for the CA certificate only if it's not using the system trust store - if !tlsConfig.UseSystemTrustStore { - CaSecret := buildXdsUpstreamTLSCASecret(tlsConfig) - if err := tCtx.AddXdsResource(resourcev3.SecretType, CaSecret); err != nil { - return nil, err - } - } - - // for upstreamTLS , a fixed sni can be used. use auto_sni otherwise - // https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/sni#faq-how-to-setup-sni:~:text=For%20clusters%2C%20a,for%20trust%20anchor. - tlsSocket, err := buildXdsUpstreamTLSSocketWthCert(tlsConfig) - if err != nil { - return nil, err - } - return tlsSocket, nil -} - // findXdsSecret finds a xds secret with the same name, and returns nil if there is no match. func findXdsSecret(tCtx *types.ResourceVersionTable, name string) *tlsv3.Secret { if tCtx == nil || tCtx.XdsResources == nil || tCtx.XdsResources[resourcev3.SecretType] == nil { @@ -692,12 +747,11 @@ func buildXdsUpstreamTLSCASecret(tlsConfig *ir.TLSUpstreamConfig) *tlsv3.Secret } func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3.TransportSocket, error) { - var tlsCtx *tlsv3.UpstreamTlsContext - if tlsConfig.UseSystemTrustStore { tlsCtx = &tlsv3.UpstreamTlsContext{ CommonTlsContext: &tlsv3.CommonTlsContext{ + TlsCertificates: nil, ValidationContextType: &tlsv3.CommonTlsContext_ValidationContext{ ValidationContext: &tlsv3.CertificateValidationContext{ TrustedCa: &corev3.DataSource{ @@ -731,6 +785,14 @@ func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3. } } + tlsParams := buildTLSParams(&tlsConfig.TLSConfig) + if tlsParams != nil { + tlsCtx.CommonTlsContext.TlsParams = tlsParams + } + + if len(tlsConfig.ALPNProtocols) > 0 { + tlsCtx.CommonTlsContext.AlpnProtocols = buildALPNProtocols(tlsConfig.ALPNProtocols) + } tlsCtxAny, err := anypb.New(tlsCtx) if err != nil { return nil, err diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index 367e7741277..28868500b68 100644 --- a/internal/xds/translator/translator_test.go +++ b/internal/xds/translator/translator_test.go @@ -41,294 +41,96 @@ var ( overrideTestData = flag.Bool("override-testdata", false, "if override the test output data.") ) -func TestTranslateXds(t *testing.T) { - testCases := []struct { - name string - dnsDomain string - requireSecrets bool - requireEnvoyPatchPolicies bool - err bool - }{ - { - name: "empty", - }, - { - name: "http-route", - }, - { - name: "http-route-regex", - }, - { - name: "http-route-redirect", - }, - { - name: "http-route-mirror", - }, - { - name: "http-route-multiple-mirrors", - }, - { - name: "http-route-multiple-matches", - }, - { - name: "http-route-direct-response", - }, - { - name: "http-route-request-headers", - }, - { - name: "http-route-response-add-headers", - }, - { - name: "http-route-response-remove-headers", - }, - { - name: "http-route-response-add-remove-headers", - }, - { - name: "http-route-weighted-invalid-backend", - }, - { - name: "http-route-dns-cluster", - }, - { - name: "http-route-with-tls-system-truststore", - requireSecrets: true, - }, - { - name: "http-route-with-tlsbundle", - requireSecrets: true, - }, - { - name: "http-route-with-tlsbundle-multiple-certs", - requireSecrets: true, - }, - { - name: "simple-tls", - requireSecrets: true, - }, - { - name: "mutual-tls", - requireSecrets: true, - }, - { - name: "http3", - requireSecrets: true, - }, - { - name: "tls-route-passthrough", - }, - { - name: "tcp-route-simple", - }, - { - name: "tcp-route-complex", - }, - { - name: "tcp-route-tls-terminate", - }, - { - name: "multiple-simple-tcp-route-same-port", - }, - { - name: "http-route-weighted-backend", - }, - { - name: "tcp-route-weighted-backend", - }, - { - name: "multiple-listeners-same-port", - requireSecrets: true, - }, - { - name: "udp-route", - }, - { - name: "http2-route", - }, - { - name: "http-route-rewrite-url-prefix", - }, - { - name: "http-route-rewrite-root-path-url-prefix", - }, - { - name: "http-route-rewrite-url-fullpath", - }, - { - name: "http-route-rewrite-url-host", - }, - { - name: "http-route-timeout", - }, +type testFileConfig struct { + requireEnvoyPatchPolicies bool + dnsDomain string + errMsg string +} - { - name: "ratelimit", - }, - { - name: "ratelimit-custom-domain", +func TestTranslateXds(t *testing.T) { + testConfigs := map[string]testFileConfig{ + "ratelimit-custom-domain": { dnsDomain: "example-cluster.local", }, - { - name: "ratelimit-sourceip", - }, - { - name: "accesslog", - }, - { - name: "tracing", - }, - { - name: "metrics-virtual-host", - }, - { - name: "jsonpatch", + "jsonpatch": { requireEnvoyPatchPolicies: true, - requireSecrets: true, - err: true, }, - { - name: "jsonpatch-missing-resource", + "jsonpatch-missing-resource": { requireEnvoyPatchPolicies: true, - err: true, }, - { - name: "jsonpatch-invalid-patch", + "jsonpatch-invalid-patch": { requireEnvoyPatchPolicies: true, - err: true, + errMsg: "unable to unmarshal xds resource", }, - { - name: "jsonpatch-add-op-without-value", + "jsonpatch-add-op-without-value": { requireEnvoyPatchPolicies: true, - err: true, + errMsg: "the add operation requires a value", }, - { - name: "jsonpatch-move-op-with-value", + "jsonpatch-move-op-with-value": { requireEnvoyPatchPolicies: true, - err: true, - }, - { - name: "listener-tcp-keepalive", - }, - { - name: "load-balancer", - }, - { - name: "cors", - }, - { - name: "jwt-multi-route-multi-provider", - }, - { - name: "jwt-multi-route-single-provider", - }, - { - name: "jwt-ratelimit", - }, - { - name: "jwt-single-route-single-match", - }, - { - name: "oidc", - requireSecrets: true, - }, - { - name: "http-route-partial-invalid", - }, - { - name: "listener-proxy-protocol", - }, - { - name: "jwt-custom-extractor", - }, - { - name: "proxy-protocol-upstream", - }, - { - name: "basic-auth", - }, - { - name: "health-check", - }, - { - name: "local-ratelimit", - }, - { - name: "circuit-breaker", - }, - { - name: "suppress-envoy-headers", - }, - { - name: "fault-injection", + errMsg: "the value field can not be set for the remove operation", }, - { - name: "headers-with-underscores-action", + "http-route-invalid": { + errMsg: "validation failed for xds resource", }, - { - name: "tls-with-ciphers-versions-alpn", + "tcp-route-invalid": { + errMsg: "validation failed for xds resource", }, - { - name: "path-settings", + "tcp-route-invalid-endpoint": { + errMsg: "validation failed for xds resource", }, - { - name: "client-ip-detection", + "udp-route-invalid": { + errMsg: "validation failed for xds resource", }, - { - name: "http1-trailers", + "jsonpatch-invalid": { + errMsg: "validation failed for xds resource", }, - { - name: "http1-preserve-case", + "jsonpatch-invalid-listener": { + errMsg: "validation failed for xds resource", }, - { - name: "timeout", + "accesslog-invalid": { + errMsg: "validation failed for xds resource", }, - { - name: "ext-auth", - }, - { - name: "http10", - }, - { - name: "upstream-tcpkeepalive", - }, - { - name: "client-timeout", - }, - { - name: "client-buffer-limit", - }, - { - name: "retry-partial-invalid", - }, - { - name: "multiple-listeners-same-port-with-different-filters", - }, - { - name: "listener-connection-limit", - }, - { - name: "ext-proc", + "tracing-invalid": { + errMsg: "validation failed for xds resource", }, } - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - dnsDomain := tc.dnsDomain - if dnsDomain == "" { + inputFiles, err := filepath.Glob(filepath.Join("testdata", "in", "xds-ir", "*.yaml")) + require.NoError(t, err) + + for _, inputFile := range inputFiles { + inputFile := inputFile + inputFileName := testName(inputFile) + t.Run(inputFileName, func(t *testing.T) { + cfg, ok := testConfigs[inputFileName] + if !ok { + cfg = testFileConfig{ + requireEnvoyPatchPolicies: false, + dnsDomain: "", + errMsg: "", + } + } + + dnsDomain := cfg.dnsDomain + if len(dnsDomain) == 0 { dnsDomain = "cluster.local" } - ir := requireXdsIRFromInputTestData(t, "xds-ir", tc.name+".yaml") + + x := requireXdsIRFromInputTestData(t, inputFile) tr := &Translator{ GlobalRateLimit: &GlobalRateLimitSettings{ ServiceURL: ratelimit.GetServiceURL("envoy-gateway-system", dnsDomain), }, } - tCtx, err := tr.Translate(ir) - if !strings.HasSuffix(tc.name, "partial-invalid") && !tc.err { + tCtx, err := tr.Translate(x) + if !strings.HasSuffix(inputFileName, "partial-invalid") && len(cfg.errMsg) == 0 { require.NoError(t, err) + } else if len(cfg.errMsg) > 0 { + require.Error(t, err) + require.Contains(t, err.Error(), cfg.errMsg) + return } listeners := tCtx.XdsResources[resourcev3.ListenerType] @@ -336,23 +138,25 @@ func TestTranslateXds(t *testing.T) { clusters := tCtx.XdsResources[resourcev3.ClusterType] endpoints := tCtx.XdsResources[resourcev3.EndpointType] if *overrideTestData { - require.NoError(t, file.Write(requireResourcesToYAMLString(t, listeners), filepath.Join("testdata", "out", "xds-ir", tc.name+".listeners.yaml"))) - require.NoError(t, file.Write(requireResourcesToYAMLString(t, routes), filepath.Join("testdata", "out", "xds-ir", tc.name+".routes.yaml"))) - require.NoError(t, file.Write(requireResourcesToYAMLString(t, clusters), filepath.Join("testdata", "out", "xds-ir", tc.name+".clusters.yaml"))) - require.NoError(t, file.Write(requireResourcesToYAMLString(t, endpoints), filepath.Join("testdata", "out", "xds-ir", tc.name+".endpoints.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, listeners), filepath.Join("testdata", "out", "xds-ir", inputFileName+".listeners.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, routes), filepath.Join("testdata", "out", "xds-ir", inputFileName+".routes.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, clusters), filepath.Join("testdata", "out", "xds-ir", inputFileName+".clusters.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, endpoints), filepath.Join("testdata", "out", "xds-ir", inputFileName+".endpoints.yaml"))) } - require.Equal(t, requireTestDataOutFile(t, "xds-ir", tc.name+".listeners.yaml"), requireResourcesToYAMLString(t, listeners)) - require.Equal(t, requireTestDataOutFile(t, "xds-ir", tc.name+".routes.yaml"), requireResourcesToYAMLString(t, routes)) - require.Equal(t, requireTestDataOutFile(t, "xds-ir", tc.name+".clusters.yaml"), requireResourcesToYAMLString(t, clusters)) - require.Equal(t, requireTestDataOutFile(t, "xds-ir", tc.name+".endpoints.yaml"), requireResourcesToYAMLString(t, endpoints)) - if tc.requireSecrets { - secrets := tCtx.XdsResources[resourcev3.SecretType] + require.Equal(t, requireTestDataOutFile(t, "xds-ir", inputFileName+".listeners.yaml"), requireResourcesToYAMLString(t, listeners)) + require.Equal(t, requireTestDataOutFile(t, "xds-ir", inputFileName+".routes.yaml"), requireResourcesToYAMLString(t, routes)) + require.Equal(t, requireTestDataOutFile(t, "xds-ir", inputFileName+".clusters.yaml"), requireResourcesToYAMLString(t, clusters)) + require.Equal(t, requireTestDataOutFile(t, "xds-ir", inputFileName+".endpoints.yaml"), requireResourcesToYAMLString(t, endpoints)) + + secrets, ok := tCtx.XdsResources[resourcev3.SecretType] + if ok && len(secrets) > 0 { if *overrideTestData { - require.NoError(t, file.Write(requireResourcesToYAMLString(t, secrets), filepath.Join("testdata", "out", "xds-ir", tc.name+".secrets.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, secrets), filepath.Join("testdata", "out", "xds-ir", inputFileName+".secrets.yaml"))) } - require.Equal(t, requireTestDataOutFile(t, "xds-ir", tc.name+".secrets.yaml"), requireResourcesToYAMLString(t, secrets)) + require.Equal(t, requireTestDataOutFile(t, "xds-ir", inputFileName+".secrets.yaml"), requireResourcesToYAMLString(t, secrets)) } - if tc.requireEnvoyPatchPolicies { + + if cfg.requireEnvoyPatchPolicies { got := tCtx.EnvoyPatchPolicyStatuses for _, e := range got { require.NoError(t, field.SetValue(e, "LastTransitionTime", metav1.NewTime(time.Time{}))) @@ -360,10 +164,10 @@ func TestTranslateXds(t *testing.T) { if *overrideTestData { out, err := yaml.Marshal(got) require.NoError(t, err) - require.NoError(t, file.Write(string(out), filepath.Join("testdata", "out", "xds-ir", tc.name+".envoypatchpolicies.yaml"))) + require.NoError(t, file.Write(string(out), filepath.Join("testdata", "out", "xds-ir", inputFileName+".envoypatchpolicies.yaml"))) } - in := requireTestDataOutFile(t, "xds-ir", tc.name+".envoypatchpolicies.yaml") + in := requireTestDataOutFile(t, "xds-ir", inputFileName+".envoypatchpolicies.yaml") want := xtypes.EnvoyPatchPolicyStatuses{} require.NoError(t, yaml.Unmarshal([]byte(in), &want)) opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime") @@ -373,152 +177,52 @@ func TestTranslateXds(t *testing.T) { } } -func TestTranslateXdsNegative(t *testing.T) { - testCases := []struct { - name string - dnsDomain string - requireSecrets bool - }{ - { - name: "http-route-invalid", - }, - { - name: "tcp-route-invalid", - }, - { - name: "tcp-route-invalid-endpoint", - }, - { - name: "udp-route-invalid", - }, - { - name: "jsonpatch-invalid", - }, - { - name: "jsonpatch-invalid-listener", - }, - { - name: "accesslog-invalid", - }, - { - name: "tracing-invalid", - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - dnsDomain := tc.dnsDomain - if dnsDomain == "" { - dnsDomain = "cluster.local" - } - ir := requireXdsIRFromInputTestData(t, "xds-ir", tc.name+".yaml") - tr := &Translator{ - GlobalRateLimit: &GlobalRateLimitSettings{ - ServiceURL: ratelimit.GetServiceURL("envoy-gateway-system", dnsDomain), - }, - } - - _, err := tr.Translate(ir) - require.Error(t, err) - if tc.name != "jsonpatch-invalid" { - require.Contains(t, err.Error(), "validation failed for xds resource") - } - }) - } -} - func TestTranslateRateLimitConfig(t *testing.T) { - testCases := []struct { - name string - }{ - { - name: "empty-header-matches", - }, - { - name: "distinct-match", - }, - { - name: "distinct-remote-address-match", - }, - { - name: "value-match", - }, - { - name: "multiple-matches", - }, - { - name: "multiple-rules", - }, - { - name: "multiple-routes", - }, - { - name: "masked-remote-address-match", - }, - { - name: "multiple-masked-remote-address-match-with-same-cidr", - }, - } + inputFiles, err := filepath.Glob(filepath.Join("testdata", "in", "ratelimit-config", "*.yaml")) + require.NoError(t, err) - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - in := requireXdsIRListenerFromInputTestData(t, "ratelimit-config", tc.name+".yaml") + for _, inputFile := range inputFiles { + inputFile := inputFile + inputFileName := testName(inputFile) + t.Run(inputFileName, func(t *testing.T) { + in := requireXdsIRListenerFromInputTestData(t, inputFile) out := BuildRateLimitServiceConfig(in) if *overrideTestData { - require.NoError(t, file.Write(requireYamlRootToYAMLString(t, out), filepath.Join("testdata", "out", "ratelimit-config", tc.name+".yaml"))) + require.NoError(t, file.Write(requireYamlRootToYAMLString(t, out), filepath.Join("testdata", "out", "ratelimit-config", inputFileName+".yaml"))) } - require.Equal(t, requireTestDataOutFile(t, "ratelimit-config", tc.name+".yaml"), requireYamlRootToYAMLString(t, out)) + require.Equal(t, requireTestDataOutFile(t, "ratelimit-config", inputFileName+".yaml"), requireYamlRootToYAMLString(t, out)) }) } } func TestTranslateXdsWithExtension(t *testing.T) { - testCases := []struct { - name string - requireSecrets bool - err string - }{ - // Require secrets for all the tests since the extension for testing always injects one - { - name: "empty", - requireSecrets: true, - err: "", + testConfigs := map[string]testFileConfig{ + "http-route-extension-route-error": { + errMsg: "route hook resource error", }, - { - name: "http-route", - requireSecrets: true, - err: "", + "http-route-extension-virtualhost-error": { + errMsg: "extension post xds virtual host hook error", }, - { - name: "http-route-extension-filter", - requireSecrets: true, - err: "", - }, - { - name: "http-route-extension-route-error", - requireSecrets: true, - err: "route hook resource error", - }, - { - name: "http-route-extension-virtualhost-error", - requireSecrets: true, - err: "extension post xds virtual host hook error", - }, - { - name: "http-route-extension-listener-error", - requireSecrets: true, - err: "extension post xds listener hook error", + "http-route-extension-listener-error": { + errMsg: "extension post xds listener hook error", }, } - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - // Testdata for the extension tests is similar to the ir test dat + inputFiles, err := filepath.Glob(filepath.Join("testdata", "in", "extension-xds-ir", "*.yaml")) + require.NoError(t, err) + + for _, inputFile := range inputFiles { + inputFile := inputFile + inputFileName := testName(inputFile) + t.Run(inputFileName, func(t *testing.T) { + cfg, ok := testConfigs[inputFileName] + if !ok { + cfg = testFileConfig{} + } + + // Testdata for the extension tests is similar to the ir test data // New directory is just to keep them separate and easy to understand - ir := requireXdsIRFromInputTestData(t, "extension-xds-ir", tc.name+".yaml") + x := requireXdsIRFromInputTestData(t, inputFile) tr := &Translator{ GlobalRateLimit: &GlobalRateLimitSettings{ ServiceURL: ratelimit.GetServiceURL("envoy-gateway-system", "cluster.local"), @@ -546,10 +250,9 @@ func TestTranslateXdsWithExtension(t *testing.T) { extMgr := testutils.NewManager(ext) tr.ExtensionManager = &extMgr - tCtx, err := tr.Translate(ir) - - if tc.err != "" { - require.EqualError(t, err, tc.err) + tCtx, err := tr.Translate(x) + if len(cfg.errMsg) > 0 { + require.EqualError(t, err, cfg.errMsg) } else { require.NoError(t, err) listeners := tCtx.XdsResources[resourcev3.ListenerType] @@ -557,42 +260,46 @@ func TestTranslateXdsWithExtension(t *testing.T) { clusters := tCtx.XdsResources[resourcev3.ClusterType] endpoints := tCtx.XdsResources[resourcev3.EndpointType] if *overrideTestData { - require.NoError(t, file.Write(requireResourcesToYAMLString(t, listeners), filepath.Join("testdata", "out", "extension-xds-ir", tc.name+".listeners.yaml"))) - require.NoError(t, file.Write(requireResourcesToYAMLString(t, routes), filepath.Join("testdata", "out", "extension-xds-ir", tc.name+".routes.yaml"))) - require.NoError(t, file.Write(requireResourcesToYAMLString(t, clusters), filepath.Join("testdata", "out", "extension-xds-ir", tc.name+".clusters.yaml"))) - require.NoError(t, file.Write(requireResourcesToYAMLString(t, endpoints), filepath.Join("testdata", "out", "extension-xds-ir", tc.name+".endpoints.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, listeners), filepath.Join("testdata", "out", "extension-xds-ir", inputFileName+".listeners.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, routes), filepath.Join("testdata", "out", "extension-xds-ir", inputFileName+".routes.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, clusters), filepath.Join("testdata", "out", "extension-xds-ir", inputFileName+".clusters.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, endpoints), filepath.Join("testdata", "out", "extension-xds-ir", inputFileName+".endpoints.yaml"))) } - require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", tc.name+".listeners.yaml"), requireResourcesToYAMLString(t, listeners)) - require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", tc.name+".routes.yaml"), requireResourcesToYAMLString(t, routes)) - require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", tc.name+".clusters.yaml"), requireResourcesToYAMLString(t, clusters)) - require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", tc.name+".endpoints.yaml"), requireResourcesToYAMLString(t, endpoints)) - if tc.requireSecrets { - secrets := tCtx.XdsResources[resourcev3.SecretType] + require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", inputFileName+".listeners.yaml"), requireResourcesToYAMLString(t, listeners)) + require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", inputFileName+".routes.yaml"), requireResourcesToYAMLString(t, routes)) + require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", inputFileName+".clusters.yaml"), requireResourcesToYAMLString(t, clusters)) + require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", inputFileName+".endpoints.yaml"), requireResourcesToYAMLString(t, endpoints)) + + secrets, ok := tCtx.XdsResources[resourcev3.SecretType] + if ok { if *overrideTestData { - require.NoError(t, file.Write(requireResourcesToYAMLString(t, secrets), filepath.Join("testdata", "out", "extension-xds-ir", tc.name+".secrets.yaml"))) + require.NoError(t, file.Write(requireResourcesToYAMLString(t, secrets), filepath.Join("testdata", "out", "extension-xds-ir", inputFileName+".secrets.yaml"))) } - require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", tc.name+".secrets.yaml"), requireResourcesToYAMLString(t, secrets)) + require.Equal(t, requireTestDataOutFile(t, "extension-xds-ir", inputFileName+".secrets.yaml"), requireResourcesToYAMLString(t, secrets)) } } }) } } -func requireXdsIRFromInputTestData(t *testing.T, name ...string) *ir.Xds { +func testName(inputFile string) string { + _, fileName := filepath.Split(inputFile) + return strings.TrimSuffix(fileName, ".yaml") +} + +func requireXdsIRFromInputTestData(t *testing.T, name string) *ir.Xds { t.Helper() - elems := append([]string{"testdata", "in"}, name...) - content, err := inFiles.ReadFile(filepath.Join(elems...)) + content, err := inFiles.ReadFile(name) require.NoError(t, err) - ir := &ir.Xds{} - err = yaml.Unmarshal(content, ir) + x := &ir.Xds{} + err = yaml.Unmarshal(content, x) require.NoError(t, err) - return ir + return x } -func requireXdsIRListenerFromInputTestData(t *testing.T, name ...string) *ir.HTTPListener { +func requireXdsIRListenerFromInputTestData(t *testing.T, name string) *ir.HTTPListener { t.Helper() - elems := append([]string{"testdata", "in"}, name...) - content, err := inFiles.ReadFile(filepath.Join(elems...)) + content, err := inFiles.ReadFile(name) require.NoError(t, err) listener := &ir.HTTPListener{} err = yaml.Unmarshal(content, listener) diff --git a/internal/xds/translator/utils.go b/internal/xds/translator/utils.go index e3002d9a8a3..b4f60b1ae30 100644 --- a/internal/xds/translator/utils.go +++ b/internal/xds/translator/utils.go @@ -13,14 +13,14 @@ import ( "strconv" "strings" - "github.com/envoyproxy/gateway/internal/ir" - "github.com/envoyproxy/gateway/internal/xds/types" - corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" - "google.golang.org/protobuf/types/known/anypb" + "k8s.io/utils/ptr" + + "github.com/envoyproxy/gateway/internal/ir" + "github.com/envoyproxy/gateway/internal/xds/types" ) const ( @@ -144,13 +144,6 @@ func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVer endpointType = EndpointTypeStatic } - if rd.Settings[0].TLS != nil { - tSocket, err = processTLSSocket(rd.Settings[0].TLS, tCtx) - if err != nil { - return err - } - } - if err = addXdsCluster(tCtx, &xdsClusterArgs{ name: rd.Name, settings: rd.Settings, @@ -161,3 +154,39 @@ func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVer } return nil } + +// addClusterFromURL adds a cluster to the resource version table from the provided URL. +func addClusterFromURL(url string, tCtx *types.ResourceVersionTable) error { + var ( + uc *urlCluster + ds *ir.DestinationSetting + tSocket *corev3.TransportSocket + err error + ) + + if uc, err = url2Cluster(url); err != nil { + return err + } + + ds = &ir.DestinationSetting{ + Weight: ptr.To[uint32](1), + Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(uc.hostname, uc.port)}, + } + + clusterArgs := &xdsClusterArgs{ + name: uc.name, + settings: []*ir.DestinationSetting{ds}, + endpointType: uc.endpointType, + } + if uc.tls { + if tSocket, err = buildXdsUpstreamTLSSocket(uc.hostname); err != nil { + return err + } + clusterArgs.tSocket = tSocket + } + + if err = addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) { + return err + } + return nil +} diff --git a/internal/xds/translator/wasm.go b/internal/xds/translator/wasm.go new file mode 100644 index 00000000000..4d358d707f7 --- /dev/null +++ b/internal/xds/translator/wasm.go @@ -0,0 +1,213 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package translator + +import ( + "errors" + + corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + wasmfilterv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" + hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" + wasmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" + "github.com/golang/protobuf/ptypes/duration" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/envoyproxy/gateway/internal/ir" + "github.com/envoyproxy/gateway/internal/xds/types" +) + +const ( + wasmFilter = "envoy.filters.http.wasm" + vmRuntimeV8 = "envoy.wasm.runtime.v8" +) + +func init() { + registerHTTPFilter(&wasm{}) +} + +type wasm struct{} + +var _ httpFilter = &wasm{} + +// patchHCM builds and appends the wasm Filters to the HTTP Connection Manager +// if applicable, and it does not already exist. +// Note: this method creates a wasm filter for each route that contains an wasm config. +// The filter is disabled by default. It is enabled on the route level. +func (*wasm) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { + var errs error + + if mgr == nil { + return errors.New("hcm is nil") + } + if irListener == nil { + return errors.New("ir listener is nil") + } + + for _, route := range irListener.Routes { + if !routeContainsWasm(route) { + continue + } + for _, ep := range route.Wasms { + if hcmContainsFilter(mgr, wasmFilterName(ep)) { + continue + } + filter, err := buildHCMWasmFilter(ep) + if err != nil { + errs = errors.Join(errs, err) + continue + } + mgr.HttpFilters = append(mgr.HttpFilters, filter) + } + } + + return errs +} + +// buildHCMWasmFilter returns a wasm HTTP filter from the provided IR HTTPRoute. +func buildHCMWasmFilter(wasm ir.Wasm) (*hcmv3.HttpFilter, error) { + var ( + wasmProto *wasmfilterv3.Wasm + wasmAny *anypb.Any + err error + ) + + if wasmProto, err = wasmConfig(wasm); err != nil { + return nil, err + } + if err = wasmProto.ValidateAll(); err != nil { + return nil, err + } + if wasmAny, err = anypb.New(wasmProto); err != nil { + return nil, err + } + + // All wasm filters for all Routes are aggregated on HCM and disabled by default + // Per-route config is used to enable the relevant filters on appropriate routes + return &hcmv3.HttpFilter{ + Name: wasmFilterName(wasm), + Disabled: true, + ConfigType: &hcmv3.HttpFilter_TypedConfig{ + TypedConfig: wasmAny, + }, + }, nil +} + +func wasmFilterName(wasm ir.Wasm) string { + return perRouteFilterName(wasmFilter, wasm.Name) +} + +func wasmConfig(wasm ir.Wasm) (*wasmfilterv3.Wasm, error) { + var ( + uc *urlCluster + pluginConfig = "" + configAny *anypb.Any + filterConfig *wasmfilterv3.Wasm + err error + ) + + // We only support HTTP Wasm code source for now + if uc, err = url2Cluster(wasm.HTTPWasmCode.URL); err != nil { + return nil, err + } + + if wasm.Config != nil { + pluginConfig = string(wasm.Config.Raw) + } + + if configAny, err = anypb.New(wrapperspb.String(pluginConfig)); err != nil { + return nil, err + } + + filterConfig = &wasmfilterv3.Wasm{ + Config: &wasmv3.PluginConfig{ + Name: wasm.WasmName, + Vm: &wasmv3.PluginConfig_VmConfig{ + VmConfig: &wasmv3.VmConfig{ + VmId: wasm.Name, // Do not share VMs across different filters + Runtime: vmRuntimeV8, + Code: &corev3.AsyncDataSource{ + Specifier: &corev3.AsyncDataSource_Remote{ + Remote: &corev3.RemoteDataSource{ + HttpUri: &corev3.HttpUri{ + Uri: wasm.HTTPWasmCode.URL, + HttpUpstreamType: &corev3.HttpUri_Cluster{ + Cluster: uc.name, + }, + Timeout: &duration.Duration{ + Seconds: defaultExtServiceRequestTimeout, + }, + }, + Sha256: wasm.HTTPWasmCode.SHA256, + }, + }, + }, + }, + }, + Configuration: configAny, + FailOpen: wasm.FailOpen, + }, + } + + if wasm.RootID != nil { + filterConfig.Config.RootId = *wasm.RootID + } + + return filterConfig, nil +} + +// routeContainsWasm returns true if Wasms exists for the provided route. +func routeContainsWasm(irRoute *ir.HTTPRoute) bool { + if irRoute == nil { + return false + } + + return len(irRoute.Wasms) > 0 +} + +// patchResources patches the cluster resources for the http wasm code source. +func (*wasm) patchResources(tCtx *types.ResourceVersionTable, + routes []*ir.HTTPRoute, +) error { + if tCtx == nil || tCtx.XdsResources == nil { + return errors.New("xds resource table is nil") + } + + var err, errs error + for _, route := range routes { + if !routeContainsWasm(route) { + continue + } + + for _, w := range route.Wasms { + if err = addClusterFromURL(w.HTTPWasmCode.URL, tCtx); err != nil { + errs = errors.Join(errs, err) + } + } + } + + return errs +} + +// patchRoute patches the provided route with the wasm config if applicable. +// Note: this method enables the corresponding wasm filter for the provided route. +func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { + if route == nil { + return errors.New("xds route is nil") + } + if irRoute == nil { + return errors.New("ir route is nil") + } + + for _, ep := range irRoute.Wasms { + filterName := wasmFilterName(ep) + if err := enableFilterOnRoute(route, filterName); err != nil { + return err + } + } + return nil +} diff --git a/internal/xds/types/resourceversiontable.go b/internal/xds/types/resourceversiontable.go index 672096e6ab7..2f7a7926bd8 100644 --- a/internal/xds/types/resourceversiontable.go +++ b/internal/xds/types/resourceversiontable.go @@ -46,7 +46,7 @@ func (t *ResourceVersionTable) DeepCopyInto(out *ResourceVersionTable) { (*out)[key] = nil } else { // Snippet was generated by controller-gen - //G601: Implicit memory aliasing in for loop. + // G601: Implicit memory aliasing in for loop. in, out := &val, &outVal //nolint:gosec,scopelint *out = make([]types.Resource, len(*in)) for i := range *in { diff --git a/proto/extension/context.pb.go b/proto/extension/context.pb.go index 623e30e8c96..d9453224718 100644 --- a/proto/extension/context.pb.go +++ b/proto/extension/context.pb.go @@ -5,18 +5,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.33.0 // protoc (unknown) // source: proto/extension/context.proto package extension import ( - reflect "reflect" - sync "sync" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/proto/extension/service.pb.go b/proto/extension/service.pb.go index 6d4428283d5..9b6cbc65757 100644 --- a/proto/extension/service.pb.go +++ b/proto/extension/service.pb.go @@ -5,22 +5,21 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.33.0 // protoc (unknown) // source: proto/extension/service.proto package extension import ( - reflect "reflect" - sync "sync" - v32 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" v31 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" v33 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) const ( diff --git a/proto/extension/service_grpc.pb.go b/proto/extension/service_grpc.pb.go index e19d68387d3..2d01d54b8a2 100644 --- a/proto/extension/service_grpc.pb.go +++ b/proto/extension/service_grpc.pb.go @@ -13,7 +13,6 @@ package extension import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/site/content/en/_index.md b/site/content/en/_index.md index e453eec5789..dd4456c47ac 100644 --- a/site/content/en/_index.md +++ b/site/content/en/_index.md @@ -6,7 +6,7 @@ title: Envoy Gateway GET STARTED - + CONTRIBUTING

Manages Envoy Proxy as a Standalone or Kubernetes-based API Gateway

@@ -66,7 +66,7 @@ Try Envoy Gateway in GitHub Releases {{% /blocks/feature %}} {{% blocks/feature icon="fab fa-github" title="Contributions Welcome!" - url="/latest/contributions/" %}} + url="/contributions/" %}} We do a [Pull Request](https://github.com/envoyproxy/gateway/pulls) contributions workflow on **GitHub**. {{% /blocks/feature %}} diff --git a/site/content/en/announcements/_index.md b/site/content/en/announcements/_index.md index 89da20bbadc..3c4fe9a2f7d 100644 --- a/site/content/en/announcements/_index.md +++ b/site/content/en/announcements/_index.md @@ -51,5 +51,5 @@ In order to align with the Envoy Proxy [release schedule][], Envoy Gateway relea | 0.6.0 | 2023/10/22 | 2023/11/02 | +10 days | 2024/05/02 | [v2.0.0 spec]: https://semver.org/spec/v2.0.0.html -[release guide]: ../latest/contributions/releasing +[release guide]: ../contributions/releasing [release schedule]: https://github.com/envoyproxy/envoy/blob/main/RELEASES.md#major-release-schedule diff --git a/site/content/en/blog/news/1.0-release/1.0-release.md b/site/content/en/blog/news/1.0-release/1.0-release.md index c0546812d43..5711ee83b91 100644 --- a/site/content/en/blog/news/1.0-release/1.0-release.md +++ b/site/content/en/blog/news/1.0-release/1.0-release.md @@ -58,8 +58,8 @@ Following the 1.0 release, we’ll be focusing on: * **Features**: More API Gateway features such as authorization (IP Addresses, JWT Claims, API Key, etc.) and compression * **Scale**: Building out a performance benchmarking tool into our CI * **Extensibility**: We plan on providing a first-class API for data plane extensions such as Lua, WASM, and Ext Proc to enable users to implement their custom use cases -* **Outside of Kubernetes**: Running Envoy Gateway in non-k8s environments - this has been an [explicit goal](/v1.0.1/contributions/design/goals#all-environments) and we’d like to focus on this in the coming months. Envoy Proxy already supports running on bare metal environments, with Envoy Gateway users getting the added advantage of a simpler API +* **Outside of Kubernetes**: Running Envoy Gateway in non-k8s environments - this has been an [explicit goal](/contributions/design/goals#all-environments) and we’d like to focus on this in the coming months. Envoy Proxy already supports running on bare metal environments, with Envoy Gateway users getting the added advantage of a simpler API * **Debug**: And a lot of capabilities with the [egctl CLI](/v1.0.1/tasks/operations/egctl/) ## Get Started -If you’ve been looking to use Envoy as a Gateway, check out our [quickstart guide](/v1.0.1/tasks/quickstart) and give it a try! If you’re interested in contributing, check out our [guide for getting involved](/v1.0.1/contributions/)! +If you’ve been looking to use Envoy as a Gateway, check out our [quickstart guide](/v1.0.1/tasks/quickstart) and give it a try! If you’re interested in contributing, check out our [guide for getting involved](/contributions/)! diff --git a/site/content/en/latest/contributions/CODEOWNERS.md b/site/content/en/contributions/CODEOWNERS.md similarity index 100% rename from site/content/en/latest/contributions/CODEOWNERS.md rename to site/content/en/contributions/CODEOWNERS.md diff --git a/site/content/en/latest/contributions/CODE_OF_CONDUCT.md b/site/content/en/contributions/CODE_OF_CONDUCT.md similarity index 100% rename from site/content/en/latest/contributions/CODE_OF_CONDUCT.md rename to site/content/en/contributions/CODE_OF_CONDUCT.md diff --git a/site/content/en/latest/contributions/CONTRIBUTING.md b/site/content/en/contributions/CONTRIBUTING.md similarity index 98% rename from site/content/en/latest/contributions/CONTRIBUTING.md rename to site/content/en/contributions/CONTRIBUTING.md index 975a86c85be..6598efb6d47 100644 --- a/site/content/en/latest/contributions/CONTRIBUTING.md +++ b/site/content/en/contributions/CONTRIBUTING.md @@ -49,7 +49,7 @@ to the following guidelines for all code, APIs, and documentation: build. If your PR cannot have 100% coverage for some reason please clearly explain why when you open it. * Any PR that changes user-facing behavior **must** have associated documentation in the [docs](https://github.com/envoyproxy/gateway/tree/main/site) folder of the repo as - well as the [changelog](../releases). + well as the [changelog](./RELEASING). * All code comments and documentation are expected to have proper English grammar and punctuation. If you are not a fluent English speaker (or a bad writer ;-)) please let us know and we will try to find some help but there are no guarantees. @@ -81,7 +81,7 @@ to the following guidelines for all code, APIs, and documentation: ## Maintainer PR Review Policy -* See [CODEOWNERS.md](../codeowners) for the current list of maintainers. +* See [CODEOWNERS.md](./codeowners) for the current list of maintainers. * A maintainer representing a different affiliation from the PR owner is required to review and approve the PR. * When the project matures, it is expected that a "domain expert" for the code the PR touches should diff --git a/site/content/en/latest/contributions/DEVELOP.md b/site/content/en/contributions/DEVELOP.md similarity index 99% rename from site/content/en/latest/contributions/DEVELOP.md rename to site/content/en/contributions/DEVELOP.md index 83702cd81d6..5006f04d995 100644 --- a/site/content/en/latest/contributions/DEVELOP.md +++ b/site/content/en/contributions/DEVELOP.md @@ -158,6 +158,6 @@ and is hosted in the repo. [Envoy admin interface]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface [jwt]: https://tools.ietf.org/html/rfc7519 [jwks]: https://tools.ietf.org/html/rfc7517 -[request authentication]: ../tasks/security/jwt-authentication +[request authentication]: ../latest/tasks/security/jwt-authentication [JWT Debugger]: https://jwt.io/ [JWK Creator]: https://russelldavies.github.io/jwk-creator/ diff --git a/site/content/en/v1.0.1/contributions/DOCS.md b/site/content/en/contributions/DOCS.md similarity index 88% rename from site/content/en/v1.0.1/contributions/DOCS.md rename to site/content/en/contributions/DOCS.md index ae19953a8b5..a2bc120101d 100644 --- a/site/content/en/v1.0.1/contributions/DOCS.md +++ b/site/content/en/contributions/DOCS.md @@ -10,8 +10,8 @@ We migrated from ***Sphinx*** to ***Hugo*** for Envoy Gateway Documents. Read blog: [Welcome to new website!](/blog/2023/10/08/welcome-to-new-website/) {{% /alert %}} -The documentation for the Envoy Gateway lives in the `site/content/en` directory. Any -individual document can be written using [Markdown]. +The documentation for the Envoy Gateway lives in the `site/content/en` directory (the Chinese content in the `site/content/zh` directory). +Any individual document can be written using [Markdown]. ## Documentation Structure @@ -53,8 +53,7 @@ make docs-release TAG=v0.6.0 This will update the VERSION file at the project root, which records current release version, and it will be used in the pages version context and binary version output. Also, this will generate -new dir `site/content/en/v0.6.0`, which contains docs at v0.6.0 and updates artifact links to `v0.6.0` -in all files under `site/content/en/v0.6.0/user`, like `quickstart.md`, `http-routing.md` and etc. +new dir `site/content/en/v0.6.0`, which contains docs at v0.6.0,like `/api`, `/install` and etc. ## Publishing Docs diff --git a/site/content/en/v1.0.1/contributions/RELEASING.md b/site/content/en/contributions/RELEASING.md similarity index 99% rename from site/content/en/v1.0.1/contributions/RELEASING.md rename to site/content/en/contributions/RELEASING.md index 3ee8b970c5f..76211b61e1a 100644 --- a/site/content/en/v1.0.1/contributions/RELEASING.md +++ b/site/content/en/contributions/RELEASING.md @@ -148,7 +148,7 @@ export GITHUB_REMOTE=origin ``` - 6. Uodate the `Documentation` referred link on the menu in `site/hugo.toml`: + 6. Update the `Documentation` referred link on the menu in `site/hugo.toml`: ```shell [[menu.main]] diff --git a/site/content/en/contributions/_index.md b/site/content/en/contributions/_index.md new file mode 100644 index 00000000000..fc9a0518c9b --- /dev/null +++ b/site/content/en/contributions/_index.md @@ -0,0 +1,8 @@ ++++ +title = "Get Involved" +description = "This section includes contents related to Contributions" +linktitle = "Get Involved" + +[[cascade]] +type = "docs" ++++ \ No newline at end of file diff --git a/site/content/en/latest/contributions/design/_index.md b/site/content/en/contributions/design/_index.md similarity index 100% rename from site/content/en/latest/contributions/design/_index.md rename to site/content/en/contributions/design/_index.md diff --git a/site/content/en/latest/contributions/design/accesslog.md b/site/content/en/contributions/design/accesslog.md similarity index 100% rename from site/content/en/latest/contributions/design/accesslog.md rename to site/content/en/contributions/design/accesslog.md diff --git a/site/content/en/latest/contributions/design/backend-traffic-policy.md b/site/content/en/contributions/design/backend-traffic-policy.md similarity index 100% rename from site/content/en/latest/contributions/design/backend-traffic-policy.md rename to site/content/en/contributions/design/backend-traffic-policy.md diff --git a/site/content/en/latest/contributions/design/bootstrap.md b/site/content/en/contributions/design/bootstrap.md similarity index 99% rename from site/content/en/latest/contributions/design/bootstrap.md rename to site/content/en/contributions/design/bootstrap.md index c0581347a24..55f31d2440e 100644 --- a/site/content/en/latest/contributions/design/bootstrap.md +++ b/site/content/en/contributions/design/bootstrap.md @@ -376,6 +376,6 @@ spec: ``` [Issue 31]: https://github.com/envoyproxy/gateway/issues/31 -[EnvoyProxy]: ../../api/extension_types#envoyproxy +[EnvoyProxy]: ../../latest/api/extension_types#envoyproxy [GatewayClass]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass [parametersRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ParametersReference diff --git a/site/content/en/latest/contributions/design/client-traffic-policy.md b/site/content/en/contributions/design/client-traffic-policy.md similarity index 100% rename from site/content/en/latest/contributions/design/client-traffic-policy.md rename to site/content/en/contributions/design/client-traffic-policy.md diff --git a/site/content/en/latest/contributions/design/config-api.md b/site/content/en/contributions/design/config-api.md similarity index 100% rename from site/content/en/latest/contributions/design/config-api.md rename to site/content/en/contributions/design/config-api.md diff --git a/site/content/en/latest/contributions/design/eg-metrics.md b/site/content/en/contributions/design/eg-metrics.md similarity index 100% rename from site/content/en/latest/contributions/design/eg-metrics.md rename to site/content/en/contributions/design/eg-metrics.md diff --git a/site/content/en/latest/contributions/design/egctl.md b/site/content/en/contributions/design/egctl.md similarity index 100% rename from site/content/en/latest/contributions/design/egctl.md rename to site/content/en/contributions/design/egctl.md diff --git a/site/content/en/latest/contributions/design/envoy-extension-policy.md b/site/content/en/contributions/design/envoy-extension-policy.md similarity index 98% rename from site/content/en/latest/contributions/design/envoy-extension-policy.md rename to site/content/en/contributions/design/envoy-extension-policy.md index ffd5c2751bb..4bda1eb85ab 100644 --- a/site/content/en/latest/contributions/design/envoy-extension-policy.md +++ b/site/content/en/contributions/design/envoy-extension-policy.md @@ -158,6 +158,6 @@ Here is a list of features that can be included in this API [Policy Attachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment [Gateway API]: https://gateway-api.sigs.k8s.io/ [Gateway API Route Filters]: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional -[Envoy Patch Policy]: ../../api/extension_types#envoypatchpolicy +[Envoy Patch Policy]: ../../latest/api/extension_types#envoypatchpolicy [Envoy Extension Manager]: ./extending-envoy-gateway [Alternatives]: #Alternatives diff --git a/site/content/en/latest/contributions/design/envoy-patch-policy.md b/site/content/en/contributions/design/envoy-patch-policy.md similarity index 95% rename from site/content/en/latest/contributions/design/envoy-patch-policy.md rename to site/content/en/contributions/design/envoy-patch-policy.md index 343e6bab1e4..2fb2bcba17d 100644 --- a/site/content/en/latest/contributions/design/envoy-patch-policy.md +++ b/site/content/en/contributions/design/envoy-patch-policy.md @@ -167,10 +167,10 @@ patches will work. [Gateway API]: https://gateway-api.sigs.k8s.io/ [Kubernetes]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ [Kustomize]: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/jsonpatch.md -[Extension APIs]: ../../api/extension_types/ +[Extension APIs]: ../../latest/api/extension_types [RateLimit]: ./rate-limit -[EnvoyGateway]: ../../api/extension_types#envoygateway +[EnvoyGateway]: ../../latest/api/extension_types#envoygateway [Extending the Control Plane]: ./extending-envoy-gateway [EnvoyFilter]: https://istio.io/latest/docs/reference/config/networking/envoy-filter -[egctl x translate]: ../../tasks/operations/egctl#egctl-experimental-translate -[Bootstrap configuration using EnvoyProxy API]: ../../tasks/operations/customize-envoyproxy#customize-envoyproxy-bootstrap-config +[egctl x translate]: ../../latest/tasks/operations/egctl#egctl-experimental-translate +[Bootstrap configuration using EnvoyProxy API]: ../../latest/tasks/operations/customize-envoyproxy#customize-envoyproxy-bootstrap-config diff --git a/site/content/en/v1.0.1/contributions/design/extending-envoy-gateway.md b/site/content/en/contributions/design/extending-envoy-gateway.md similarity index 99% rename from site/content/en/v1.0.1/contributions/design/extending-envoy-gateway.md rename to site/content/en/contributions/design/extending-envoy-gateway.md index 0b549460b65..84c9755b179 100644 --- a/site/content/en/v1.0.1/contributions/design/extending-envoy-gateway.md +++ b/site/content/en/contributions/design/extending-envoy-gateway.md @@ -316,10 +316,10 @@ Extending Envoy Gateway by using an external extension server which makes use of [Envoy specific configuration (xDS)]: https://www.envoyproxy.io/docs/envoy/v1.25.1/configuration/configuration [v1]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1 [rate limiting]: ./rate-limit -[authentication]: ../../tasks/security/jwt-authentication +[authentication]: ../../latest/tasks/security/jwt-authentication [HTTPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute [GRPCRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute -[EnvoyGateway config]: ../../api/extension_types/#envoygateway +[EnvoyGateway config]: ../../latest/api/extension_types#envoygateway [controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime [Unstructured]: https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured [Listener]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener diff --git a/site/content/en/latest/contributions/design/gatewayapi-translator.md b/site/content/en/contributions/design/gatewayapi-translator.md similarity index 100% rename from site/content/en/latest/contributions/design/gatewayapi-translator.md rename to site/content/en/contributions/design/gatewayapi-translator.md diff --git a/site/content/en/latest/contributions/design/goals.md b/site/content/en/contributions/design/goals.md similarity index 100% rename from site/content/en/latest/contributions/design/goals.md rename to site/content/en/contributions/design/goals.md diff --git a/site/content/en/latest/contributions/design/local-envoy-gateway.md b/site/content/en/contributions/design/local-envoy-gateway.md similarity index 100% rename from site/content/en/latest/contributions/design/local-envoy-gateway.md rename to site/content/en/contributions/design/local-envoy-gateway.md diff --git a/site/content/en/latest/contributions/design/metrics.md b/site/content/en/contributions/design/metrics.md similarity index 100% rename from site/content/en/latest/contributions/design/metrics.md rename to site/content/en/contributions/design/metrics.md diff --git a/site/content/en/latest/contributions/design/pprof.md b/site/content/en/contributions/design/pprof.md similarity index 100% rename from site/content/en/latest/contributions/design/pprof.md rename to site/content/en/contributions/design/pprof.md diff --git a/site/content/en/latest/contributions/design/rate-limit.md b/site/content/en/contributions/design/rate-limit.md similarity index 100% rename from site/content/en/latest/contributions/design/rate-limit.md rename to site/content/en/contributions/design/rate-limit.md diff --git a/site/content/en/latest/contributions/design/security-policy.md b/site/content/en/contributions/design/security-policy.md similarity index 100% rename from site/content/en/latest/contributions/design/security-policy.md rename to site/content/en/contributions/design/security-policy.md diff --git a/site/content/en/latest/contributions/design/system-design.md b/site/content/en/contributions/design/system-design.md similarity index 100% rename from site/content/en/latest/contributions/design/system-design.md rename to site/content/en/contributions/design/system-design.md diff --git a/site/content/en/latest/contributions/design/tcp-udp-design.md b/site/content/en/contributions/design/tcp-udp-design.md similarity index 100% rename from site/content/en/latest/contributions/design/tcp-udp-design.md rename to site/content/en/contributions/design/tcp-udp-design.md diff --git a/site/content/en/latest/contributions/design/tracing.md b/site/content/en/contributions/design/tracing.md similarity index 100% rename from site/content/en/latest/contributions/design/tracing.md rename to site/content/en/contributions/design/tracing.md diff --git a/site/content/en/latest/contributions/design/watching.md b/site/content/en/contributions/design/watching.md similarity index 100% rename from site/content/en/latest/contributions/design/watching.md rename to site/content/en/contributions/design/watching.md diff --git a/site/content/en/latest/contributions/roadmap.md b/site/content/en/contributions/roadmap.md similarity index 100% rename from site/content/en/latest/contributions/roadmap.md rename to site/content/en/contributions/roadmap.md diff --git a/site/content/en/latest/_index.md b/site/content/en/latest/_index.md index 567b43bfe36..ea08d244d31 100644 --- a/site/content/en/latest/_index.md +++ b/site/content/en/latest/_index.md @@ -9,7 +9,7 @@ type = "docs" {{% alert title="Note" color="primary" %}} -This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](contributions/)! +This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](/contributions)! {{% /alert %}} diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index c3316f67026..d485100eab3 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -36,8 +36,71 @@ _Underlying type:_ _string_ ALPNProtocol specifies the protocol to be negotiated using ALPN _Appears in:_ +- [BackendTLSConfig](#backendtlsconfig) +- [ClientTLSSettings](#clienttlssettings) - [TLSSettings](#tlssettings) +| Value | Description | +| ----- | ----------- | +| `http/1.0` | HTTPProtocolVersion1_0 specifies that HTTP/1.0 should be negotiable with ALPN
| +| `http/1.1` | HTTPProtocolVersion1_1 specifies that HTTP/1.1 should be negotiable with ALPN
| +| `h2` | HTTPProtocolVersion2 specifies that HTTP/2 should be negotiable with ALPN
| + + +#### ALSEnvoyProxyAccessLog + + + +ALSEnvoyProxyAccessLog defines the gRPC Access Log Service (ALS) sink. +The service must implement the Envoy gRPC Access Log Service streaming API: +https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto +Access log format information is passed in the form of gRPC metadata when the +stream is established. Specifically, the following metadata is passed: + + +- `x-accesslog-text` - The access log format string when a Text format is used. +- `x-accesslog-attr` - JSON encoded key/value pairs when a JSON format is used. + +_Appears in:_ +- [ProxyAccessLogSink](#proxyaccesslogsink) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs references a Kubernetes object that represents the gRPC service to which
the access logs will be sent. Currently only Service is supported. | +| `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in
StreamAccessLogsMessage.Identifier. This allows the access log server
to differentiate between different access logs coming from the same Envoy. | +| `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". | +| `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. | + + +#### ALSEnvoyProxyAccessLogType + +_Underlying type:_ _string_ + + + +_Appears in:_ +- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) + +| Value | Description | +| ----- | ----------- | +| `HTTP` | ALSEnvoyProxyAccessLogTypeHTTP defines the HTTP access log type and will populate StreamAccessLogsMessage.http_logs.
| +| `TCP` | ALSEnvoyProxyAccessLogTypeTCP defines the TCP access log type and will populate StreamAccessLogsMessage.tcp_logs.
| + + +#### ALSEnvoyProxyHTTPAccessLogConfig + + + + + +_Appears in:_ +- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `requestHeaders` | _string array_ | false | RequestHeaders defines request headers to include in log entries sent to the access log service. | +| `responseHeaders` | _string array_ | false | ResponseHeaders defines response headers to include in log entries sent to the access log service. | +| `responseTrailers` | _string array_ | false | ResponseTrailers defines response trailers to include in log entries sent to the access log service. | #### ActiveHealthCheck @@ -87,6 +150,10 @@ ActiveHealthCheckPayloadType is the type of the payload. _Appears in:_ - [ActiveHealthCheckPayload](#activehealthcheckpayload) +| Value | Description | +| ----- | ----------- | +| `Text` | ActiveHealthCheckPayloadTypeText defines the Text type payload.
| +| `Binary` | ActiveHealthCheckPayloadTypeBinary defines the Binary type payload.
| #### ActiveHealthCheckerType @@ -98,6 +165,10 @@ ActiveHealthCheckerType is the type of health checker. _Appears in:_ - [ActiveHealthCheck](#activehealthcheck) +| Value | Description | +| ----- | ----------- | +| `HTTP` | ActiveHealthCheckerTypeHTTP defines the HTTP type of health checking.
| +| `TCP` | ActiveHealthCheckerTypeTCP defines the TCP type of health checking.
| #### BackOffPolicy @@ -115,6 +186,48 @@ _Appears in:_ | `maxInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#duration-v1-meta)_ | false | MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval | +#### BackendRef + + + +BackendRef defines how an ObjectReference that is specific to BackendRef. + +_Appears in:_ +- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) +- [ExtProc](#extproc) +- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog) +- [ProxyOpenTelemetrySink](#proxyopentelemetrysink) +- [TracingProvider](#tracingprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `group` | _[Group](#group)_ | false | Group is the group of the referent. For example, "gateway.networking.k8s.io".
When unspecified or empty string, core API group is inferred. | +| `kind` | _[Kind](#kind)_ | false | Kind is the Kubernetes resource kind of the referent. For example
"Service".

Defaults to "Service" when not specified.

ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.

Support: Core (Services with a type other than ExternalName)

Support: Implementation-specific (Services with type ExternalName) | +| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. | +| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.

Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.

Support: Core | +| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource.
Port is required when the referent is a Kubernetes Service. In this
case, the port number is the service port number, not the target port.
For other resources, destination port might be derived from the referent
resource or this field. | + + +#### BackendTLSConfig + + + +BackendTLSConfig describes the BackendTLS configuration for Envoy Proxy. + +_Appears in:_ +- [EnvoyProxySpec](#envoyproxyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `clientCertificateRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | false | ClientCertificateRef defines the reference to a Kubernetes Secret that contains
the client certificate and private key for Envoy to use when connecting to
backend services and external services, such as ExtAuth, ALS, OpenTelemetry, etc. | +| `minVersion` | _[TLSVersion](#tlsversion)_ | false | Min specifies the minimal TLS protocol version to allow.
The default is TLS 1.2 if this is not specified. | +| `maxVersion` | _[TLSVersion](#tlsversion)_ | false | Max specifies the maximal TLS protocol version to allow
The default is TLS 1.3 if this is not specified. | +| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when
negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3.
In non-FIPS Envoy Proxy builds the default cipher list is:
- [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305]
- [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305]
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384
In builds using BoringSSL FIPS the default cipher list is:
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384 | +| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves.
In non-FIPS Envoy Proxy builds the default curves are:
- X25519
- P-256
In builds using BoringSSL FIPS the default curve is:
- P-256 | +| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should
support. | +| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be
exposed by the listener. By default h2 and http/1.1 are enabled.
Supported values are:
- http/1.0
- http/1.1
- h2 | + + #### BackendTrafficPolicy @@ -153,7 +266,7 @@ BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources. -spec defines the desired state of BackendTrafficPolicy. +BackendTrafficPolicySpec defines the desired state of BackendTrafficPolicy. _Appears in:_ - [BackendTrafficPolicy](#backendtrafficpolicy) @@ -169,8 +282,8 @@ _Appears in:_ | `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to
inject delays and abort requests to mimic failure scenarios such as service failures and overloads | | `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests.
If not set, circuit breakers will be enabled with the default thresholds | | `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
If not set, retry will be disabled. | +| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | -| `compression` | _[Compression](#compression) array_ | false | The compression config for the http streams. | #### BasicAuth @@ -196,6 +309,10 @@ BootstrapType defines the types of bootstrap supported by Envoy Gateway. _Appears in:_ - [ProxyBootstrap](#proxybootstrap) +| Value | Description | +| ----- | ----------- | +| `Merge` | Merge merges the provided bootstrap with the default one. The provided bootstrap can add or override a value
within a map, or add a new value to a list.
Please note that the provided bootstrap can't override a value within a list.
| +| `Replace` | Replace replaces the default bootstrap with the provided one.
| #### CORS @@ -265,6 +382,26 @@ _Appears in:_ | `customHeader` | _[CustomHeaderExtensionSettings](#customheaderextensionsettings)_ | false | CustomHeader provides configuration for determining the client IP address for a request based on
a trusted custom HTTP header. This uses the the custom_header original IP detection extension.
Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto
for more details. | +#### ClientTLSSettings + + + + + +_Appears in:_ +- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `clientValidation` | _[ClientValidationContext](#clientvalidationcontext)_ | false | ClientValidation specifies the configuration to validate the client
initiating the TLS connection to the Gateway listener. | +| `minVersion` | _[TLSVersion](#tlsversion)_ | false | Min specifies the minimal TLS protocol version to allow.
The default is TLS 1.2 if this is not specified. | +| `maxVersion` | _[TLSVersion](#tlsversion)_ | false | Max specifies the maximal TLS protocol version to allow
The default is TLS 1.3 if this is not specified. | +| `ciphers` | _string array_ | false | Ciphers specifies the set of cipher suites supported when
negotiating TLS 1.0 - 1.2. This setting has no effect for TLS 1.3.
In non-FIPS Envoy Proxy builds the default cipher list is:
- [ECDHE-ECDSA-AES128-GCM-SHA256\|ECDHE-ECDSA-CHACHA20-POLY1305]
- [ECDHE-RSA-AES128-GCM-SHA256\|ECDHE-RSA-CHACHA20-POLY1305]
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384
In builds using BoringSSL FIPS the default cipher list is:
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384 | +| `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves.
In non-FIPS Envoy Proxy builds the default curves are:
- X25519
- P-256
In builds using BoringSSL FIPS the default curve is:
- P-256 | +| `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should
support. | +| `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be
exposed by the listener. By default h2 and http/1.1 are enabled.
Supported values are:
- http/1.0
- http/1.1
- h2 | + + #### ClientTimeout @@ -328,13 +465,14 @@ _Appears in:_ | `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the downstream client connection.
If defined, sets SO_KEEPALIVE on the listener socket to enable TCP Keepalives.
Disabled by default. | | `enableProxyProtocol` | _boolean_ | false | EnableProxyProtocol interprets the ProxyProtocol header and adds the
Client Address into the X-Forwarded-For header.
Note Proxy Protocol must be present when this field is set, else the connection
is closed. | | `clientIPDetection` | _[ClientIPDetectionSettings](#clientipdetectionsettings)_ | false | ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. | -| `http3` | _[HTTP3Settings](#http3settings)_ | false | HTTP3 provides HTTP/3 configuration on the listener. | -| `tls` | _[TLSSettings](#tlssettings)_ | false | TLS settings configure TLS termination settings with the downstream client. | +| `tls` | _[ClientTLSSettings](#clienttlssettings)_ | false | TLS settings configure TLS termination settings with the downstream client. | | `path` | _[PathSettings](#pathsettings)_ | false | Path enables managing how the incoming path set by clients can be normalized. | -| `http1` | _[HTTP1Settings](#http1settings)_ | false | HTTP1 provides HTTP/1 configuration on the listener. | | `headers` | _[HeaderSettings](#headersettings)_ | false | HeaderSettings provides configuration for header management. | | `timeout` | _[ClientTimeout](#clienttimeout)_ | false | Timeout settings for the client connections. | | `connection` | _[Connection](#connection)_ | false | Connection includes client connection settings. | +| `http1` | _[HTTP1Settings](#http1settings)_ | false | HTTP1 provides HTTP/1 configuration on the listener. | +| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration on the listener. | +| `http3` | _[HTTP3Settings](#http3settings)_ | false | HTTP3 provides HTTP/3 configuration on the listener. | #### ClientValidationContext @@ -346,10 +484,11 @@ to the Gateway. By default, no client specific configuration is validated. _Appears in:_ -- [TLSSettings](#tlssettings) +- [ClientTLSSettings](#clienttlssettings) | Field | Type | Required | Description | | --- | --- | --- | --- | +| `optional` | _boolean_ | false | Optional set to true accepts connections even when a client doesn't present a certificate.
Defaults to false, which rejects connections without a valid client certificate. | | `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to
Kubernetes objects that contain TLS certificates of
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.

A single reference to a Kubernetes ConfigMap or a Kubernetes Secret,
with the CA certificate in a key named `ca.crt` is currently supported.

References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. | @@ -362,6 +501,7 @@ This can help reduce the bandwidth at the expense of higher CPU. _Appears in:_ - [BackendTrafficPolicySpec](#backendtrafficpolicyspec) +- [ProxyPrometheusProvider](#proxyprometheusprovider) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -434,13 +574,16 @@ ConsistentHashType defines the type of input to hash on. _Appears in:_ - [ConsistentHash](#consistenthash) +| Value | Description | +| ----- | ----------- | +| `SourceIP` | SourceIPConsistentHashType hashes based on the source IP address.
| #### CustomHeaderExtensionSettings -CustomHeader provides configuration for determining the client IP address for a request based on +CustomHeaderExtensionSettings provides configuration for determining the client IP address for a request based on a trusted custom HTTP header. This uses the the custom_header original IP detection extension. Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto for more details. @@ -480,6 +623,11 @@ _Underlying type:_ _string_ _Appears in:_ - [CustomTag](#customtag) +| Value | Description | +| ----- | ----------- | +| `Literal` | CustomTagTypeLiteral adds hard-coded value to each span.
| +| `Environment` | CustomTagTypeEnvironment adds value from environment variable to each span.
| +| `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span.
| #### EnvironmentCustomTag @@ -541,9 +689,33 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `targetRef` | _[PolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the Gateway resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway.
TargetRef | -| `wasm` | _[Wasm](#wasm) array_ | false | WASM is a list of Wasm extensions to be loaded by the Gateway.
Order matters, as the extensions will be loaded in the order they are
defined in this list. | -| `extProc` | _[ExtProc](#extproc) array_ | true | ExtProc is an ordered list of external processing filters
that should added to the envoy filter chain | +| `targetRef` | _[PolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy
is being attached to.
This Policy and the TargetRef MUST be in the same namespace
for this Policy to have effect and be applied to the Gateway or xRoute. | +| `wasm` | _[Wasm](#wasm) array_ | false | Wasm is a list of Wasm extensions to be loaded by the Gateway.
Order matters, as the extensions will be loaded in the order they are
defined in this list. | +| `extProc` | _[ExtProc](#extproc) array_ | false | ExtProc is an ordered list of external processing filters
that should added to the envoy filter chain | + + +#### EnvoyFilter + +_Underlying type:_ _string_ + +EnvoyFilter defines the type of Envoy HTTP filter. + +_Appears in:_ +- [FilterPosition](#filterposition) + +| Value | Description | +| ----- | ----------- | +| `envoy.filters.http.fault` | EnvoyFilterFault defines the Envoy HTTP fault filter.
| +| `envoy.filters.http.cors` | EnvoyFilterCORS defines the Envoy HTTP CORS filter.
| +| `envoy.filters.http.ext_authz` | EnvoyFilterExtAuthz defines the Envoy HTTP external authorization filter.
| +| `envoy.filters.http.basic_authn` | EnvoyFilterBasicAuthn defines the Envoy HTTP basic authentication filter.
| +| `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter.
| +| `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter.
| +| `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter.
| +| `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter.
| +| `envoy.filters.http.local_ratelimit` | EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter.
| +| `envoy.filters.http.ratelimit` | EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
| +| `envoy.filters.http.router` | EnvoyFilterRouter defines the Envoy HTTP router filter.
| #### EnvoyGateway @@ -682,6 +854,15 @@ EnvoyGatewayLogComponent defines a component that supports a configured logging _Appears in:_ - [EnvoyGatewayLogging](#envoygatewaylogging) +| Value | Description | +| ----- | ----------- | +| `default` | LogComponentGatewayDefault defines the "default"-wide logging component. When specified,
all other logging components are ignored.
| +| `provider` | LogComponentProviderRunner defines the "provider" runner component.
| +| `gateway-api` | LogComponentGatewayAPIRunner defines the "gateway-api" runner component.
| +| `xds-translator` | LogComponentXdsTranslatorRunner defines the "xds-translator" runner component.
| +| `xds-server` | LogComponentXdsServerRunner defines the "xds-server" runner component.
| +| `infrastructure` | LogComponentInfrastructureRunner defines the "infrastructure" runner component.
| +| `global-ratelimit` | LogComponentGlobalRateLimitRunner defines the "global-ratelimit" runner component.
| #### EnvoyGatewayLogging @@ -906,6 +1087,9 @@ EnvoyPatchType specifies the types of Envoy patching mechanisms. _Appears in:_ - [EnvoyPatchPolicySpec](#envoypatchpolicyspec) +| Value | Description | +| ----- | ----------- | +| `JSONPatch` | JSONPatchEnvoyPatchType allows the user to patch the generated xDS resources using JSONPatch semantics.
For more details on the semantics, please refer to https://datatracker.ietf.org/doc/html/rfc6902
| #### EnvoyProxy @@ -937,6 +1121,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `envoyDeployment` | _[KubernetesDeploymentSpec](#kubernetesdeploymentspec)_ | false | EnvoyDeployment defines the desired state of the Envoy deployment resource.
If unspecified, default settings for the managed Envoy deployment resource
are applied. | +| `envoyDaemonSet` | _[KubernetesDaemonSetSpec](#kubernetesdaemonsetspec)_ | false | EnvoyDaemonSet defines the desired state of the Envoy daemonset resource.
Disabled by default, a deployment resource is used instead to provision the Envoy Proxy fleet | | `envoyService` | _[KubernetesServiceSpec](#kubernetesservicespec)_ | false | EnvoyService defines the desired state of the Envoy service resource.
If unspecified, default settings for the managed Envoy service resource
are applied. | | `envoyHpa` | _[KubernetesHorizontalPodAutoscalerSpec](#kuberneteshorizontalpodautoscalerspec)_ | false | EnvoyHpa defines the Horizontal Pod Autoscaler settings for Envoy Proxy Deployment.
Once the HPA is being set, Replicas field from EnvoyDeployment will be ignored. | @@ -975,6 +1160,7 @@ _Appears in:_ | `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy.
More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options
Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. | | `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure.
Setting this field to true would merge all Gateway Listeners under the parent Gateway Class.
This means that the port, protocol and hostname tuple must be unique for every listener.
If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. | | `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. | +| `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends.
These settings are applied on backends for which TLS policies are specified. | @@ -988,6 +1174,12 @@ EnvoyResourceType specifies the type URL of the Envoy resource. _Appears in:_ - [EnvoyJSONPatchConfig](#envoyjsonpatchconfig) +| Value | Description | +| ----- | ----------- | +| `type.googleapis.com/envoy.config.listener.v3.Listener` | ListenerEnvoyResourceType defines the Type URL of the Listener resource
| +| `type.googleapis.com/envoy.config.route.v3.RouteConfiguration` | RouteConfigurationEnvoyResourceType defines the Type URL of the RouteConfiguration resource
| +| `type.googleapis.com/envoy.config.cluster.v3.Cluster` | ClusterEnvoyResourceType defines the Type URL of the Cluster resource
| +| `type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment` | ClusterLoadAssignmentEnvoyResourceType defines the Type URL of the ClusterLoadAssignment resource
| #### ExtAuth @@ -1018,27 +1210,42 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRef` | _[ExtProcBackendRef](#extprocbackendref)_ | true | Service defines the configuration of the external processing service | +| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs defines the configuration of the external processing service | +| `messageTimeout` | _[Duration](#duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor
Default: 200ms | +| `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the
external processor are terminated or passed-through.
Default: false | +| `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed
Default: header and body are not sent to the external processor | + + +#### ExtProcBodyProcessingMode + +_Underlying type:_ _string_ + + + +_Appears in:_ +- [ProcessingModeOptions](#processingmodeoptions) + +| Value | Description | +| ----- | ----------- | +| `Streamed` | StreamedExtProcBodyProcessingMode will stream the body to the server in pieces as they arrive at the proxy.
| +| `Buffered` | BufferedExtProcBodyProcessingMode will buffer the message body in memory and send the entire body at once. If the body exceeds the configured buffer limit, then the downstream system will receive an error.
| +| `BufferedPartial` | BufferedPartialExtBodyHeaderProcessingMode will buffer the message body in memory and send the entire body in one chunk. If the body exceeds the configured buffer limit, then the body contents up to the buffer limit will be sent.
| -#### ExtProcBackendRef +#### ExtProcProcessingMode -ExtProcService defines the gRPC External Processing service using the envoy grpc client -The processing request and response messages are defined in -https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/ext_proc/v3/external_processor.proto +ExtProcProcessingMode defines if and how headers and bodies are sent to the service. +https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto#envoy-v3-api-msg-extensions-filters-http-ext-proc-v3-processingmode _Appears in:_ - [ExtProc](#extproc) | Field | Type | Required | Description | | --- | --- | --- | --- | -| `group` | _[Group](#group)_ | false | Group is the group of the referent. For example, "gateway.networking.k8s.io".
When unspecified or empty string, core API group is inferred. | -| `kind` | _[Kind](#kind)_ | false | Kind is the Kubernetes resource kind of the referent. For example
"Service".

Defaults to "Service" when not specified.

ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations SHOULD NOT
support ExternalName Services.

Support: Core (Services with a type other than ExternalName)

Support: Implementation-specific (Services with type ExternalName) | -| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. | -| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local
namespace is inferred.

Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.

Support: Core | -| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource.
Port is required when the referent is a Kubernetes Service. In this
case, the port number is the service port number, not the target port.
For other resources, destination port might be derived from the referent
resource or this field. | +| `request` | _[ProcessingModeOptions](#processingmodeoptions)_ | false | Defines processing mode for requests. If present, request headers are sent. Request body is processed according
to the specified mode. | +| `response` | _[ProcessingModeOptions](#processingmodeoptions)_ | false | Defines processing mode for responses. If present, response headers are sent. Response body is processed according
to the specified mode. | #### ExtensionAPISettings @@ -1179,6 +1386,22 @@ _Appears in:_ | `path` | _string_ | true | Path defines the file path used to expose envoy access log(e.g. /dev/stdout). | +#### FilterPosition + + + +FilterPosition defines the position of an Envoy HTTP filter in the filter chain. + +_Appears in:_ +- [EnvoyProxySpec](#envoyproxyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `filter` | _[EnvoyFilter](#envoyfilter)_ | true | Name of the filter. | +| `before` | _[EnvoyFilter](#envoyfilter)_ | true | Before defines the filter that should come before the filter.
Only one of Before or After must be set. | +| `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter.
Only one of Before or After must be set. | + + #### GRPCExtAuthService @@ -1284,6 +1507,22 @@ _Appears in:_ | `http10` | _[HTTP10Settings](#http10settings)_ | false | HTTP10 turns on support for HTTP/1.0 and HTTP/0.9 requests. | +#### HTTP2Settings + + + +HTTP2Settings provides HTTP/2 configuration on the listener. + +_Appears in:_ +- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `initialStreamWindowSize` | _[Quantity](#quantity)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024). | +| `initialConnectionWindowSize` | _[Quantity](#quantity)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB. | +| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
If not set, the default value is 100. | + + #### HTTP3Settings @@ -1396,13 +1635,18 @@ Valid HeaderMatchType values are "Exact", "RegularExpression", and "Distinct". _Appears in:_ - [HeaderMatch](#headermatch) +| Value | Description | +| ----- | ----------- | +| `Exact` | HeaderMatchExact matches the exact value of the Value field against the value of
the specified HTTP Header.
| +| `RegularExpression` | HeaderMatchRegularExpression matches a regular expression against the value of the
specified HTTP Header. The regex string must adhere to the syntax documented in
https://github.com/google/re2/wiki/Syntax.
| +| `Distinct` | HeaderMatchDistinct matches any and all possible unique values encountered in the
specified HTTP Header. Note that each unique value will receive its own rate limit
bucket.
Note: This is only supported for Global Rate Limits.
| #### HeaderSettings -HeaderSettings providess configuration options for headers on the listener. +HeaderSettings provides configuration options for headers on the listener. _Appears in:_ - [ClientTrafficPolicySpec](#clienttrafficpolicyspec) @@ -1453,6 +1697,9 @@ InfrastructureProviderType defines the types of custom infrastructure providers _Appears in:_ - [EnvoyGatewayInfrastructureProvider](#envoygatewayinfrastructureprovider) +| Value | Description | +| ----- | ----------- | +| `Host` | InfrastructureProviderTypeHost defines the "Host" provider.
| #### JSONPatchOperation @@ -1495,6 +1742,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | +| `optional` | _boolean_ | true | Optional determines whether a missing JWT is acceptable, defaulting to false if not specified.
Note: Even if optional is set to true, JWT authentication will still fail if an invalid JWT is presented. | | `providers` | _[JWTProvider](#jwtprovider) array_ | true | Providers defines the JSON Web Token (JWT) authentication provider type.
When multiple JWT providers are specified, the JWT is considered valid if
any of the providers successfully validate the JWT. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html. | @@ -1558,6 +1806,7 @@ _Appears in:_ KubernetesContainerSpec defines the desired state of the Kubernetes container resource. _Appears in:_ +- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec) - [KubernetesDeploymentSpec](#kubernetesdeploymentspec) | Field | Type | Required | Description | @@ -1569,6 +1818,23 @@ _Appears in:_ | `volumeMounts` | _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#volumemount-v1-core) array_ | false | VolumeMounts are volumes to mount into the container's filesystem.
Cannot be updated. | +#### KubernetesDaemonSetSpec + + + +KubernetesDaemonsetSpec defines the desired state of the Kubernetes daemonset resource. + +_Appears in:_ +- [EnvoyProxyKubernetesProvider](#envoyproxykubernetesprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to daemonset | +| `strategy` | _[DaemonSetUpdateStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#daemonsetupdatestrategy-v1-apps)_ | false | The daemonset strategy to use to replace existing pods with new ones. | +| `pod` | _[KubernetesPodSpec](#kubernetespodspec)_ | false | Pod defines the desired specification of pod. | +| `container` | _[KubernetesContainerSpec](#kubernetescontainerspec)_ | false | Container defines the desired specification of main container. | + + #### KubernetesDeployMode @@ -1628,6 +1894,7 @@ _Appears in:_ KubernetesPatchSpec defines how to perform the patch operation _Appears in:_ +- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec) - [KubernetesDeploymentSpec](#kubernetesdeploymentspec) - [KubernetesServiceSpec](#kubernetesservicespec) @@ -1644,6 +1911,7 @@ _Appears in:_ KubernetesPodSpec defines the desired state of the Kubernetes pod resource. _Appears in:_ +- [KubernetesDaemonSetSpec](#kubernetesdaemonsetspec) - [KubernetesDeploymentSpec](#kubernetesdeploymentspec) | Field | Type | Required | Description | @@ -1674,6 +1942,7 @@ _Appears in:_ | `type` | _[ServiceType](#servicetype)_ | false | Type determines how the Service is exposed. Defaults to LoadBalancer.
Valid options are ClusterIP, LoadBalancer and NodePort.
"LoadBalancer" means a service will be exposed via an external load balancer (if the cloud provider supports it).
"ClusterIP" means a service will only be accessible inside the cluster, via the cluster IP.
"NodePort" means a service will be exposed on a static Port on all Nodes of the cluster. | | `loadBalancerClass` | _string_ | false | LoadBalancerClass, when specified, allows for choosing the LoadBalancer provider
implementation if more than one are available or is otherwise expected to be specified | | `allocateLoadBalancerNodePorts` | _boolean_ | false | AllocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for
services with type LoadBalancer. Default is "true". It may be set to "false" if the cluster
load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a
value), those requests will be respected, regardless of this field. This field may only be set for
services with type LoadBalancer and will be cleared if the type is changed to any other type. | +| `loadBalancerSourceRanges` | _string array_ | false | LoadBalancerSourceRanges defines a list of allowed IP addresses which will be configured as
firewall rules on the platform providers load balancer. This is not guaranteed to be working as
it happens outside of kubernetes and has to be supported and handled by the platform provider.
This field may only be set for services with type LoadBalancer and will be cleared if the type
is changed to any other type. | | `loadBalancerIP` | _string_ | false | LoadBalancerIP defines the IP Address of the underlying load balancer service. This field
may be ignored if the load balancer provider does not support this feature.
This field has been deprecated in Kubernetes, but it is still used for setting the IP Address in some cloud
providers such as GCP. | | `externalTrafficPolicy` | _[ServiceExternalTrafficPolicy](#serviceexternaltrafficpolicy)_ | false | ExternalTrafficPolicy determines the externalTrafficPolicy for the Envoy Service. Valid options
are Local and Cluster. Default is "Local". "Local" means traffic will only go to pods on the node
receiving the traffic. "Cluster" means connections are loadbalanced to all pods in the cluster. | | `patch` | _[KubernetesPatchSpec](#kubernetespatchspec)_ | false | Patch defines how to perform the patch operation to the service | @@ -1762,6 +2031,12 @@ LoadBalancerType specifies the types of LoadBalancer. _Appears in:_ - [LoadBalancer](#loadbalancer) +| Value | Description | +| ----- | ----------- | +| `ConsistentHash` | ConsistentHashLoadBalancerType load balancer policy.
| +| `LeastRequest` | LeastRequestLoadBalancerType load balancer policy.
| +| `Random` | RandomLoadBalancerType load balancer policy.
| +| `RoundRobin` | RoundRobinLoadBalancerType load balancer policy.
| #### LocalRateLimit @@ -1788,6 +2063,12 @@ _Appears in:_ - [EnvoyGatewayLogging](#envoygatewaylogging) - [ProxyLogging](#proxylogging) +| Value | Description | +| ----- | ----------- | +| `debug` | LogLevelDebug defines the "debug" logging level.
| +| `info` | LogLevelInfo defines the "Info" logging level.
| +| `warn` | LogLevelWarn defines the "Warn" logging level.
| +| `error` | LogLevelError defines the "Error" logging level.
| @@ -1802,6 +2083,9 @@ _Appears in:_ - [EnvoyGatewayMetricSink](#envoygatewaymetricsink) - [ProxyMetricSink](#proxymetricsink) +| Value | Description | +| ----- | ----------- | +| `OpenTelemetry` | | #### OIDC @@ -1851,9 +2135,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `host` | _string_ | true | Host define the extension service hostname.
Deprecated: Use BackendRef instead. | +| `host` | _string_ | false | Host define the extension service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: Use BackendRef instead. | -| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | false | BackendRef references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | | `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info.
It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). | @@ -1912,6 +2196,12 @@ sequences in the URI path. _Appears in:_ - [PathSettings](#pathsettings) +| Value | Description | +| ----- | ----------- | +| `KeepUnchanged` | KeepUnchangedAction keeps escaped slashes as they arrive without changes
| +| `RejectRequest` | RejectRequestAction rejects client requests containing escaped slashes
with a 400 status. gRPC requests will be rejected with the INTERNAL (13)
error code.
The "httpN.downstream_rq_failed_path_normalization" counter is incremented
for each rejected request.
| +| `UnescapeAndRedirect` | UnescapeAndRedirect unescapes %2F and %5C sequences and redirects to the new path
if these sequences were present.
Redirect occurs after path normalization and merge slashes transformations if
they were configured. gRPC requests will be rejected with the INTERNAL (13)
error code.
This option minimizes possibility of path confusion exploits by forcing request
with unescaped slashes to traverse all parties: downstream client, intermediate
proxies, Envoy and upstream server.
The “httpN.downstream_rq_redirected_with_normalized_path” counter is incremented
for each redirected request.
| +| `UnescapeAndForward` | UnescapeAndForward unescapes %2F and %5C sequences and forwards the request.
Note: this option should not be enabled if intermediaries perform path based access
control as it may lead to path confusion vulnerabilities.
| #### PathSettings @@ -1944,6 +2234,20 @@ _Appears in:_ | `backOff` | _[BackOffPolicy](#backoffpolicy)_ | false | Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
back-off algorithm for retries. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries | +#### ProcessingModeOptions + + + +ProcessingModeOptions defines if headers or body should be processed by the external service + +_Appears in:_ +- [ExtProcProcessingMode](#extprocprocessingmode) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `body` | _[ExtProcBodyProcessingMode](#extprocbodyprocessingmode)_ | false | Defines body processing mode | + + #### ProviderType _Underlying type:_ _string_ @@ -1954,6 +2258,10 @@ _Appears in:_ - [EnvoyGatewayProvider](#envoygatewayprovider) - [EnvoyProxyProvider](#envoyproxyprovider) +| Value | Description | +| ----- | ----------- | +| `Kubernetes` | ProviderTypeKubernetes defines the "Kubernetes" provider.
| +| `File` | ProviderTypeFile defines the "File" provider. This type is not implemented
until https://github.com/envoyproxy/gateway/issues/1001 is fixed.
| #### ProxyAccessLog @@ -1997,6 +2305,10 @@ _Underlying type:_ _string_ _Appears in:_ - [ProxyAccessLogFormat](#proxyaccesslogformat) +| Value | Description | +| ----- | ----------- | +| `Text` | ProxyAccessLogFormatTypeText defines the text accesslog format.
| +| `JSON` | ProxyAccessLogFormatTypeJSON defines the JSON accesslog format.
| #### ProxyAccessLogSetting @@ -2026,6 +2338,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `type` | _[ProxyAccessLogSinkType](#proxyaccesslogsinktype)_ | true | Type defines the type of accesslog sink. | +| `als` | _[ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)_ | false | ALS defines the gRPC Access Log Service (ALS) sink. | | `file` | _[FileEnvoyProxyAccessLog](#fileenvoyproxyaccesslog)_ | false | File defines the file accesslog sink. | | `openTelemetry` | _[OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)_ | false | OpenTelemetry defines the OpenTelemetry accesslog sink. | @@ -2039,6 +2352,11 @@ _Underlying type:_ _string_ _Appears in:_ - [ProxyAccessLogSink](#proxyaccesslogsink) +| Value | Description | +| ----- | ----------- | +| `ALS` | ProxyAccessLogSinkTypeALS defines the gRPC Access Log Service (ALS) sink.
The service must implement the Envoy gRPC Access Log Service streaming API:
https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/accesslog/v3/als.proto
| +| `File` | ProxyAccessLogSinkTypeFile defines the file accesslog sink.
| +| `OpenTelemetry` | ProxyAccessLogSinkTypeOpenTelemetry defines the OpenTelemetry accesslog sink.
When the provider is Kubernetes, EnvoyGateway always sends `k8s.namespace.name`
and `k8s.pod.name` as additional attributes.
| #### ProxyBootstrap @@ -2065,6 +2383,18 @@ ProxyLogComponent defines a component that supports a configured logging level. _Appears in:_ - [ProxyLogging](#proxylogging) +| Value | Description | +| ----- | ----------- | +| `default` | LogComponentDefault defines the default logging component.
See more details: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#cmdoption-l
| +| `upstream` | LogComponentUpstream defines the "upstream" logging component.
| +| `http` | LogComponentHTTP defines the "http" logging component.
| +| `connection` | LogComponentConnection defines the "connection" logging component.
| +| `admin` | LogComponentAdmin defines the "admin" logging component.
| +| `client` | LogComponentClient defines the "client" logging component.
| +| `filter` | LogComponentFilter defines the "filter" logging component.
| +| `main` | LogComponentMain defines the "main" logging component.
| +| `router` | LogComponentRouter defines the "router" logging component.
| +| `runtime` | LogComponentRuntime defines the "runtime" logging component.
| #### ProxyLogging @@ -2112,6 +2442,7 @@ _Appears in:_ | `sinks` | _[ProxyMetricSink](#proxymetricsink) array_ | true | Sinks defines the metric sinks where metrics are sent to. | | `matches` | _[StringMatch](#stringmatch) array_ | true | Matches defines configuration for selecting specific metrics instead of generating all metrics stats
that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats
may after critical functionality. Here are the stats that we strongly recommend not disabling:
`cluster_manager.warming_clusters`, `cluster..membership_total`,`cluster..membership_healthy`,
`cluster..membership_degraded`,reference https://github.com/envoyproxy/envoy/issues/9856,
https://github.com/envoyproxy/envoy/issues/14610 | | `enableVirtualHostStats` | _boolean_ | true | EnableVirtualHostStats enables envoy stat metrics for virtual hosts. | +| `enablePerEndpointStats` | _boolean_ | true | EnablePerEndpointStats enables per endpoint envoy stats metrics.
Please use with caution. | #### ProxyOpenTelemetrySink @@ -2125,9 +2456,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `host` | _string_ | true | Host define the service hostname.
Deprecated: Use BackendRef instead. | +| `host` | _string_ | false | Host define the service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the service is exposed on.
Deprecated: Use BackendRef instead. | -| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | false | BackendRef references a Kubernetes object that represents the
backend server to which the metric will be sent.
Only service Kind is supported for now. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the metric will be sent.
Only service Kind is supported for now. | #### ProxyPrometheusProvider @@ -2142,6 +2473,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `disable` | _boolean_ | true | Disable the Prometheus endpoint. | +| `compression` | _[Compression](#compression)_ | false | Configure the compression on Prometheus endpoint. Compression is useful in situations when bandwidth is scarce and large payloads can be effectively compressed at the expense of higher CPU load. | #### ProxyProtocol @@ -2168,6 +2500,10 @@ ProxyProtocolVersion defines the version of the Proxy Protocol to use. _Appears in:_ - [ProxyProtocol](#proxyprotocol) +| Value | Description | +| ----- | ----------- | +| `V1` | ProxyProtocolVersionV1 is the PROXY protocol version 1 (human readable format).
| +| `V2` | ProxyProtocolVersionV2 is the PROXY protocol version 2 (binary format).
| #### ProxyTelemetry @@ -2247,6 +2583,9 @@ to be used by the rate limit service. _Appears in:_ - [RateLimitDatabaseBackend](#ratelimitdatabasebackend) +| Value | Description | +| ----- | ----------- | +| `Redis` | RedisBackendType uses a redis database for the rate limit service.
| #### RateLimitMetrics @@ -2354,6 +2693,39 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `metrics` | _[RateLimitMetrics](#ratelimitmetrics)_ | true | Metrics defines metrics configuration for RateLimit. | +| `tracing` | _[RateLimitTracing](#ratelimittracing)_ | true | Tracing defines traces configuration for RateLimit. | + + +#### RateLimitTracing + + + + + +_Appears in:_ +- [RateLimitTelemetry](#ratelimittelemetry) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `samplingRate` | _integer_ | false | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. | +| `provider` | _[RateLimitTracingProvider](#ratelimittracingprovider)_ | true | Provider defines the rateLimit tracing provider.
Only OpenTelemetry is supported currently. | + + +#### RateLimitTracingProvider + + + +RateLimitTracingProvider defines the tracing provider configuration of RateLimit + +_Appears in:_ +- [RateLimitTracing](#ratelimittracing) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `type` | _[RateLimitTracingProviderType](#ratelimittracingprovidertype)_ | true | Type defines the tracing provider type.
Since to RateLimit Exporter currently using OpenTelemetry, only OpenTelemetry is supported | +| `url` | _string_ | true | URL is the endpoint of the trace collector that supports the OTLP protocol | + + #### RateLimitType @@ -2365,6 +2737,10 @@ RateLimitType specifies the types of RateLimiting. _Appears in:_ - [RateLimitSpec](#ratelimitspec) +| Value | Description | +| ----- | ----------- | +| `Global` | GlobalRateLimitType allows the rate limits to be applied across all Envoy
proxy instances.
| +| `Local` | LocalRateLimitType allows the rate limits to be applied on a per Envoy
proxy instance basis.
| #### RateLimitUnit @@ -2377,6 +2753,12 @@ Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day". _Appears in:_ - [RateLimitValue](#ratelimitvalue) +| Value | Description | +| ----- | ----------- | +| `Second` | RateLimitUnitSecond specifies the rate limit interval to be 1 second.
| +| `Minute` | RateLimitUnitMinute specifies the rate limit interval to be 1 minute.
| +| `Hour` | RateLimitUnitHour specifies the rate limit interval to be 1 hour.
| +| `Day` | RateLimitUnitDay specifies the rate limit interval to be 1 day.
| #### RateLimitValue @@ -2447,6 +2829,9 @@ ResourceProviderType defines the types of custom resource providers supported by _Appears in:_ - [EnvoyGatewayResourceProvider](#envoygatewayresourceprovider) +| Value | Description | +| ----- | ----------- | +| `File` | ResourceProviderTypeFile defines the "File" provider.
| #### Retry @@ -2533,8 +2918,6 @@ _Appears in:_ | `extAuth` | _[ExtAuth](#extauth)_ | false | ExtAuth defines the configuration for External Authorization. | - - #### ServiceExternalTrafficPolicy _Underlying type:_ _string_ @@ -2546,6 +2929,10 @@ and LoadBalancer IPs. _Appears in:_ - [KubernetesServiceSpec](#kubernetesservicespec) +| Value | Description | +| ----- | ----------- | +| `Cluster` | ServiceExternalTrafficPolicyCluster routes traffic to all endpoints.
| +| `Local` | ServiceExternalTrafficPolicyLocal preserves the source IP of the traffic by
routing only to endpoints on the same node as the traffic was received on
(dropping the traffic if there are no local endpoints).
| #### ServiceType @@ -2557,6 +2944,11 @@ ServiceType string describes ingress methods for a service _Appears in:_ - [KubernetesServiceSpec](#kubernetesservicespec) +| Value | Description | +| ----- | ----------- | +| `ClusterIP` | ServiceTypeClusterIP means a service will only be accessible inside the
cluster, via the cluster IP.
| +| `LoadBalancer` | ServiceTypeLoadBalancer means a service will be exposed via an
external load balancer (if the cloud provider supports it).
| +| `NodePort` | ServiceTypeNodePort means a service will be exposed on each Kubernetes Node
at a static Port, common across all Nodes.
| #### ShutdownConfig @@ -2599,6 +2991,10 @@ _Underlying type:_ _string_ _Appears in:_ - [SourceMatch](#sourcematch) +| Value | Description | +| ----- | ----------- | +| `Exact` | SourceMatchExact All IP Addresses within the specified Source IP CIDR are treated as a single client selector
and share the same rate limit bucket.
| +| `Distinct` | SourceMatchDistinct Each IP Address within the specified Source IP CIDR is treated as a distinct client selector
and uses a separate rate limit bucket/counter.
Note: This is only supported for Global Rate Limits.
| #### StringMatch @@ -2628,6 +3024,12 @@ Valid MatchType values are "Exact", "Prefix", "Suffix", "RegularExpression". _Appears in:_ - [StringMatch](#stringmatch) +| Value | Description | +| ----- | ----------- | +| `Exact` | StringMatchExact :the input string must match exactly the match value.
| +| `Prefix` | StringMatchPrefix :the input string must start with the match value.
| +| `Suffix` | StringMatchSuffix :the input string must end with the match value.
| +| `RegularExpression` | StringMatchRegularExpression :The input string must match the regular expression
specified in the match value.
The regex string must adhere to the syntax documented in
https://github.com/google/re2/wiki/Syntax.
| #### TCPActiveHealthChecker @@ -2683,7 +3085,8 @@ _Appears in:_ _Appears in:_ -- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) +- [BackendTLSConfig](#backendtlsconfig) +- [ClientTLSSettings](#clienttlssettings) | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -2693,7 +3096,6 @@ _Appears in:_ | `ecdhCurves` | _string array_ | false | ECDHCurves specifies the set of supported ECDH curves.
In non-FIPS Envoy Proxy builds the default curves are:
- X25519
- P-256
In builds using BoringSSL FIPS the default curve is:
- P-256 | | `signatureAlgorithms` | _string array_ | false | SignatureAlgorithms specifies which signature algorithms the listener should
support. | | `alpnProtocols` | _[ALPNProtocol](#alpnprotocol) array_ | false | ALPNProtocols supplies the list of ALPN protocols that should be
exposed by the listener. By default h2 and http/1.1 are enabled.
Supported values are:
- http/1.0
- http/1.1
- h2 | -| `clientValidation` | _[ClientValidationContext](#clientvalidationcontext)_ | false | ClientValidation specifies the configuration to validate the client
initiating the TLS connection to the Gateway listener. | #### TLSVersion @@ -2703,8 +3105,17 @@ _Underlying type:_ _string_ TLSVersion specifies the TLS version _Appears in:_ +- [BackendTLSConfig](#backendtlsconfig) +- [ClientTLSSettings](#clienttlssettings) - [TLSSettings](#tlssettings) +| Value | Description | +| ----- | ----------- | +| `Auto` | TLSAuto allows Envoy to choose the optimal TLS Version
| +| `1.0` | TLS1.0 specifies TLS version 1.0
| +| `1.1` | TLS1.1 specifies TLS version 1.1
| +| `1.2` | TLSv1.2 specifies TLS version 1.2
| +| `1.3` | TLSv1.3 specifies TLS version 1.3
| #### Timeout @@ -2734,9 +3145,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type.
EG currently only supports OpenTelemetry. | -| `host` | _string_ | true | Host define the provider service hostname.
Deprecated: Use BackendRef instead. | +| `host` | _string_ | false | Host define the provider service hostname.
Deprecated: Use BackendRef instead. | | `port` | _integer_ | false | Port defines the port the provider service is exposed on.
Deprecated: Use BackendRef instead. | -| `backendRef` | _[BackendObjectReference](#backendobjectreference)_ | false | BackendRef references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the accesslog will be sent.
Only service Kind is supported for now. | #### TracingProviderType @@ -2748,6 +3159,10 @@ _Underlying type:_ _string_ _Appears in:_ - [TracingProvider](#tracingprovider) +| Value | Description | +| ----- | ----------- | +| `OpenTelemetry` | | +| `OpenTelemetry` | | #### TriggerEnum @@ -2759,6 +3174,20 @@ TriggerEnum specifies the conditions that trigger retries. _Appears in:_ - [RetryOn](#retryon) +| Value | Description | +| ----- | ----------- | +| `5xx` | The upstream server responds with any 5xx response code, or does not respond at all (disconnect/reset/read timeout).
Includes connect-failure and refused-stream.
| +| `gateway-error` | The response is a gateway error (502,503 or 504).
| +| `reset` | The upstream server does not respond at all (disconnect/reset/read timeout.)
| +| `connect-failure` | Connection failure to the upstream server (connect timeout, etc.). (Included in *5xx*)
| +| `retriable-4xx` | The upstream server responds with a retriable 4xx response code.
Currently, the only response code in this category is 409.
| +| `refused-stream` | The upstream server resets the stream with a REFUSED_STREAM error code.
| +| `retriable-status-codes` | The upstream server responds with any response code matching one defined in the RetriableStatusCodes.
| +| `cancelled` | The gRPC status code in the response headers is “cancelled”.
| +| `deadline-exceeded` | The gRPC status code in the response headers is “deadline-exceeded”.
| +| `internal` | The gRPC status code in the response headers is “internal”.
| +| `resource-exhausted` | The gRPC status code in the response headers is “resource-exhausted”.
| +| `unavailable` | The gRPC status code in the response headers is “unavailable”.
| #### Wasm @@ -2777,8 +3206,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | _string_ | true | Name is a unique name for this Wasm extension. It is used to identify the
Wasm extension if multiple extensions are handled by the same vm_id and root_id.
It's also used for logging/debugging. | +| `rootID` | _string_ | true | RootID is a unique ID for a set of extensions in a VM which will share a
RootContext and Contexts if applicable (e.g., an Wasm HttpFilter and an Wasm AccessLog).
If left blank, all extensions with a blank root_id with the same vm_id will share Context(s).
RootID must match the root_id parameter used to register the Context in the Wasm code. | | `code` | _[WasmCodeSource](#wasmcodesource)_ | true | Code is the wasm code for the extension. | -| `config` | _[JSON](#json)_ | true | Config is the configuration for the Wasm extension.
This configuration will be passed as a JSON string to the Wasm extension. | +| `config` | _[JSON](#json)_ | false | Config is the configuration for the Wasm extension.
This configuration will be passed as a JSON string to the Wasm extension. | | `failOpen` | _boolean_ | false | FailOpen is a switch used to control the behavior when a fatal error occurs
during the initialization or the execution of the Wasm extension.
If FailOpen is set to true, the system bypasses the Wasm extension and
allows the traffic to pass through. Otherwise, if it is set to false or
not set (defaulting to false), the system blocks the traffic and returns
an HTTP 5xx error. | @@ -2796,6 +3226,7 @@ _Appears in:_ | `type` | _[WasmCodeSourceType](#wasmcodesourcetype)_ | true | Type is the type of the source of the wasm code.
Valid WasmCodeSourceType values are "HTTP" or "Image". | | `http` | _[HTTPWasmCodeSource](#httpwasmcodesource)_ | false | HTTP is the HTTP URL containing the wasm code.

Note that the HTTP server must be accessible from the Envoy proxy. | | `image` | _[ImageWasmCodeSource](#imagewasmcodesource)_ | false | Image is the OCI image containing the wasm code.

Note that the image must be accessible from the Envoy Gateway. | +| `sha256` | _string_ | true | SHA256 checksum that will be used to verify the wasm code.

kubebuilder:validation:Pattern=`^[a-f0-9]{64}$` | #### WasmCodeSourceType @@ -2807,6 +3238,10 @@ WasmCodeSourceType specifies the types of sources for the wasm code. _Appears in:_ - [WasmCodeSource](#wasmcodesource) +| Value | Description | +| ----- | ----------- | +| `HTTP` | HTTPWasmCodeSourceType allows the user to specify the wasm code in an HTTP URL.
| +| `Image` | ImageWasmCodeSourceType allows the user to specify the wasm code in an OCI image.
| #### WithUnderscoresAction @@ -2819,6 +3254,11 @@ is encountered. _Appears in:_ - [HeaderSettings](#headersettings) +| Value | Description | +| ----- | ----------- | +| `Allow` | WithUnderscoresActionAllow allows headers with underscores to be passed through.
| +| `RejectRequest` | WithUnderscoresActionRejectRequest rejects the client request. HTTP/1 requests are rejected with
the 400 status. HTTP/2 requests end with the stream reset.
| +| `DropHeader` | WithUnderscoresActionDropHeader drops the client header with name containing underscores. The header
is dropped before the filter chain is invoked and as such filters will not see
dropped headers.
| #### XDSTranslatorHook @@ -2831,6 +3271,12 @@ for the xds-translator _Appears in:_ - [XDSTranslatorHooks](#xdstranslatorhooks) +| Value | Description | +| ----- | ----------- | +| `VirtualHost` | | +| `Route` | | +| `HTTPListener` | | +| `Translation` | | #### XDSTranslatorHooks diff --git a/site/content/en/latest/contributions/DOCS.md b/site/content/en/latest/contributions/DOCS.md deleted file mode 100644 index ae19953a8b5..00000000000 --- a/site/content/en/latest/contributions/DOCS.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "Working on Envoy Gateway Docs" -description: "This section tells the development of - Envoy Gateway Documents." ---- - -{{% alert title="Note" color="warning" %}} -We migrated from ***Sphinx*** to ***Hugo*** for Envoy Gateway Documents. - -Read blog: [Welcome to new website!](/blog/2023/10/08/welcome-to-new-website/) -{{% /alert %}} - -The documentation for the Envoy Gateway lives in the `site/content/en` directory. Any -individual document can be written using [Markdown]. - -## Documentation Structure - -We supported the versioned Docs now, the directory name under docs represents -the version of docs. The root of the latest site is in `site/content/en/latest`. -This is probably where to start if you're trying to understand how things fit together. - -Note that the new contents should be added to `site/content/en/latest` and will be cut off at -the next release. The contents under `site/content/en/v0.5.0` are auto-generated, -and usually do not need to make changes to them, unless if you find the current release pages have -some incorrect contents. If so, you should send a PR to update contents both of `site/content/en/latest` -and `site/content/en/v0.5.0`. - -You can access the website which represents the current release in default, -and you can access the website which contains the latest version changes in -[Here][latest-website] or at the footer of the pages. - -## Documentation Workflow - -To work with the docs, just edit Markdown files in `site/content/en/latest`, -then run - -```bash -make docs -``` - -This will create `site/public` with the built HTML pages. You can preview it -by running: - -``` shell -make docs-serve -``` - -If you want to generate a new release version of the docs, like `v0.6.0`, then run - -```bash -make docs-release TAG=v0.6.0 -``` - -This will update the VERSION file at the project root, which records current release version, -and it will be used in the pages version context and binary version output. Also, this will generate -new dir `site/content/en/v0.6.0`, which contains docs at v0.6.0 and updates artifact links to `v0.6.0` -in all files under `site/content/en/v0.6.0/user`, like `quickstart.md`, `http-routing.md` and etc. - -## Publishing Docs - -Whenever docs are pushed to `main`, CI will publish the built docs to GitHub -Pages. For more details, see `.github/workflows/docs.yaml`. - -## Reference - -Go to [Hugo](https://gohugo.io) and [Docsy](https://www.docsy.dev/docs) to learn more. - -[Markdown]: https://daringfireball.net/projects/markdown/syntax -[latest-website]: /latest diff --git a/site/content/en/latest/contributions/RELEASING.md b/site/content/en/latest/contributions/RELEASING.md deleted file mode 100644 index 3ee8b970c5f..00000000000 --- a/site/content/en/latest/contributions/RELEASING.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -title: "Release Process" -description: "This section tells the release process of Envoy Gateway." ---- - -This document guides maintainers through the process of creating an Envoy Gateway release. - -- [Release Candidate](#release-candidate) - - [Prerequisites](#prerequisites) - - [Setup cherry picker action](#setup-cherry-picker-action) -- [Minor Release](#minor-release) - - [Prerequisites](#prerequisites-1) -- [Announce the Release](#announce-the-release) - -## Release Candidate - -The following steps should be used for creating a release candidate. - -### Prerequisites - -- Permissions to push to the Envoy Gateway repository. - -Set environment variables for use in subsequent steps: - -```shell -export MAJOR_VERSION=0 -export MINOR_VERSION=3 -export RELEASE_CANDIDATE_NUMBER=1 -export GITHUB_REMOTE=origin -``` - -1. Clone the repo, checkout the `main` branch, ensure it’s up-to-date, and your local branch is clean. -2. Create a topic branch for adding the release notes and updating the [VERSION][] file with the release version. Refer to previous [release notes][] and [VERSION][] for additional details. -3. Sign, commit, and push your changes to your fork. -4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until your PR has merged and - the [Build and Test][] has successfully completed. -5. Create a new release branch from `main`. The release branch should be named - `release/v${MAJOR_VERSION}.${MINOR_VERSION}`, e.g. `release/v0.3`. - - ```shell - git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -6. Push the branch to the Envoy Gateway repo. - - ```shell - git push ${GITHUB_REMOTE} release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -7. Create a topic branch for updating the Envoy proxy image and Envoy Ratelimit image to the tag supported by the release. Reference [PR #2098][] - for additional details on updating the image tag. -8. Sign, commit, and push your changes to your fork. -9. Submit a [Pull Request][] to merge the changes into the `release/v${MAJOR_VERSION}.${MINOR_VERSION}` branch. Do not - proceed until your PR has merged into the release branch and the [Build and Test][] has completed for your PR. -10. Ensure your release branch is up-to-date and tag the head of your release branch with the release candidate number. - - ```shell - git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} Release Candidate' - ``` - -11. Push the tag to the Envoy Gateway repository. - - ```shell - git push ${GITHUB_REMOTE} v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} - ``` - -12. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc. -13. Confirm that the [release workflow][] completed successfully. -14. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub. -15. Confirm that the [release][] was created. -16. Note that the [Quickstart][] references are __not__ updated for release candidates. However, test - the quickstart steps using the release candidate by manually updating the links. -17. [Generate][] the GitHub changelog. -18. Ensure you check the "This is a pre-release" checkbox when editing the GitHub release. -19. If you find any bugs in this process, please create an issue. - -### Setup cherry picker action - -After release branch cut, RM (Release Manager) should add job [cherrypick action](https://github.com/envoyproxy/gateway/blob/main/.github/workflows/cherrypick.yaml) for target release. - -Configuration looks like following: - -```yaml - cherry_pick_release_v0_4: - runs-on: ubuntu-latest - name: Cherry pick into release-v0.4 - if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v0.4') && github.event.pull_request.merged == true }} - steps: - - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - with: - fetch-depth: 0 - - name: Cherry pick into release/v0.4 - uses: carloscastrojumo/github-cherry-pick-action@a145da1b8142e752d3cbc11aaaa46a535690f0c5 # v1.0.9 - with: - branch: release/v0.4 - title: "[release/v0.4] {old_title}" - body: "Cherry picking #{old_pull_request_id} onto release/v0.4" - labels: | - cherrypick/release-v0.4 - # put release manager here - reviewers: | - AliceProxy -``` - -Replace `v0.4` with real branch name, and `AliceProxy` with the real name of RM. - -## Minor Release - -The following steps should be used for creating a minor release. - -### Prerequisites - -- Permissions to push to the Envoy Gateway repository. -- A release branch that has been cut from the corresponding release candidate. Refer to the - [Release Candidate](#release-candidate) section for additional details on cutting a release candidate. - -Set environment variables for use in subsequent steps: - -```shell -export MAJOR_VERSION=0 -export MINOR_VERSION=3 -export GITHUB_REMOTE=origin -``` - -1. Clone the repo, checkout the `main` branch, ensure it’s up-to-date, and your local branch is clean. -2. Create a topic branch for adding the release notes, release announcement, and versioned release docs. - - 1. Create the release notes. Reference previous [release notes][] for additional details. __Note:__ The release - notes should be an accumulation of the release candidate release notes and any changes since the release - candidate. - 2. Create a release announcement. Refer to [PR #635] as an example release announcement. - 3. Include the release in the compatibility matrix. Refer to [PR #1002] as an example. - 4. Generate the versioned release docs: - - ``` shell - make docs-release TAG=v${MAJOR_VERSION}.${MINOR_VERSION}.0 - ``` - - 5. Update the `Get Started` and `Contributing` button referred link in `site/content/en/_index.md`: - - ```shell - - Get Started - - - Contributing - - ``` - - 6. Uodate the `Documentation` referred link on the menu in `site/hugo.toml`: - - ```shell - [[menu.main]] - name = "Documentation" - weight = -101 - pre = "" - url = "/v0.5.0" - ``` - -3. Sign, commit, and push your changes to your fork. -4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until all your PRs have merged - and the [Build and Test][] has completed for your final PR. - -5. Checkout the release branch. - - ```shell - git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -6. If the tip of the release branch does not match the tip of `main`, perform the following: - - 1. Create a topic branch from the release branch. - 2. Cherry-pick the commits from `main` that differ from the release branch. - 3. Run tests locally, e.g. `make lint`. - 4. Sign, commit, and push your topic branch to your Envoy Gateway fork. - 5. Submit a PR to merge the topic from of your fork into the Envoy Gateway release branch. - 6. Do not proceed until the PR has merged and CI passes for the merged PR. - 7. If you are still on your topic branch, change to the release branch: - - ```shell - git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - - 8. Ensure your local release branch is up-to-date: - - ```shell - git pull $GITHUB_REMOTE release/v${MAJOR_VERSION}.${MINOR_VERSION} - ``` - -7. Tag the head of your release branch with the release tag. For example: - - ```shell - git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0 -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0 Release' - ``` - - __Note:__ The tag version differs from the release branch by including the `.0` patch version. - -8. Push the tag to the Envoy Gateway repository. - - ```shell - git push origin v${MAJOR_VERSION}.${MINOR_VERSION}.0 - ``` - -9. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc. -10. Confirm that the [release workflow][] completed successfully. -11. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub. -12. Confirm that the [release][] was created. -13. Confirm that the steps in the [Quickstart][] work as expected. -14. [Generate][] the GitHub changelog and include the following text at the beginning of the release page: - - ```console - # Release Announcement - - Check out the [v${MAJOR_VERSION}.${MINOR_VERSION} release announcement] - (https://gateway.envoyproxy.io/releases/v${MAJOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release. - ``` - -If you find any bugs in this process, please create an issue. - -## Announce the Release - -It's important that the world knows about the release. Use the following steps to announce the release. - -1. Set the release information in the Envoy Gateway Slack channel. For example: - - ```shell - Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION} has been released: https://github.com/envoyproxy/gateway/releases/tag/v${MAJOR_VERSION}.${MINOR_VERSION}.0 - ``` - -2. Send a message to the Envoy Gateway Slack channel. For example: - - ```shell - On behalf of the entire Envoy Gateway community, I am pleased to announce the release of Envoy Gateway - v${MAJOR_VERSION}.${MINOR_VERSION}. A big thank you to all the contributors that made this release possible. - Refer to the official v${MAJOR_VERSION}.${MINOR_VERSION} announcement for release details and the project docs - to start using Envoy Gateway. - ... - ``` - - Link to the GitHub release and release announcement page that highlights the release. - -[release notes]: https://github.com/envoyproxy/gateway/tree/main/release-notes -[Pull Request]: https://github.com/envoyproxy/gateway/pulls -[Quickstart]: https://github.com/envoyproxy/gateway/blob/main/docs/user/quickstart.md -[Build and Test]: https://github.com/envoyproxy/gateway/blob/main/.github/workflows/build_and_test.yaml -[release GitHub action]: https://github.com/envoyproxy/gateway/blob/main/.github/workflows/release.yaml -[release workflow]: https://github.com/envoyproxy/gateway/actions/workflows/release.yaml -[image]: https://hub.docker.com/r/envoyproxy/gateway/tags -[release]: https://github.com/envoyproxy/gateway/releases -[Generate]: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes -[PR #635]: https://github.com/envoyproxy/gateway/pull/635 -[PR #2098]: https://github.com/envoyproxy/gateway/pull/2098 -[PR #1002]: https://github.com/envoyproxy/gateway/pull/1002 -[VERSION]: https://github.com/envoyproxy/gateway/blob/main/VERSION diff --git a/site/content/en/latest/contributions/_index.md b/site/content/en/latest/contributions/_index.md deleted file mode 100644 index 1d3037e609e..00000000000 --- a/site/content/en/latest/contributions/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Get Involved -description: "This section includes contents related to Contributions" -weight: 100 ---- diff --git a/site/content/en/latest/contributions/design/extending-envoy-gateway.md b/site/content/en/latest/contributions/design/extending-envoy-gateway.md deleted file mode 100644 index 0b549460b65..00000000000 --- a/site/content/en/latest/contributions/design/extending-envoy-gateway.md +++ /dev/null @@ -1,327 +0,0 @@ ---- -title: "Envoy Gateway Extensions Design" ---- - -As outlined in the [official goals][] for the Envoy Gateway project, one of the main goals is to "provide a common foundation for vendors to build value-added products -without having to re-engineer fundamental interactions". Development of the Envoy Gateway project has been focused on developing the core features for the project and -Kubernetes Gateway API conformance. This system focuses on the “common foundation for vendors” component by introducing a way for vendors to extend Envoy Gateway. - -To meaningfully extend Envoy Gateway and provide additional features, Extensions need to be able to introduce their own custom resources and have a high level of control -over the configuration generated by Envoy Gateway. Simply applying some static xDS configuration patches or relying on the existing Gateway API resources are both insufficient on their own -as means to add larger features that require dynamic user-configuration. - -As an example, an extension developer may wish to provide their own out-of-the-box authentication filters that require configuration from the end-user. This is a scenario where the ability to introduce -custom resources and attach them to [HTTPRoute][]s as an [ExtensionRef][] is necessary. Providing the same feature through a series of xDS patch resources would be too cumbersome for many end-users that want to avoid -that level of complexity when managing their clusters. - -## Goals - -- Provide a foundation for extending the Envoy Gateway control plane -- Allow Extension Developers to introduce their own custom resources for extending the Gateway-API via [ExtensionRefs][], [policyAttachments][] (future) and [backendRefs][] (future). -- Extension developers should **NOT** have to maintain a custom fork of Envoy Gateway -- Provide a system for extending Envoy Gateway which allows extension projects to ship updates independent of Envoy Gateway's release schedule -- Modify the generated Envoy xDS config -- Setup a foundation for the initial iteration of Extending Envoy Gateway -- Allow an Extension to hook into the infra manager pipeline (future) - -## Non-Goals - -- The initial design does not capture every hook that Envoy Gateway will eventually support. -- Extend [Gateway API Policy Attachments][]. At some point, these will be addressed using this extension system, but the initial implementation omits these. -- Support multiple extensions at the same time. Due to the fact that extensions will be modifying xDS resources after they are generated, handling the order of extension execution for each individual hook point is a challenge. Additionally, there is no -real way to prevent one extension from overwriting or breaking modifications to xDS resources that were made by another extension that was executed first. - -## Overview - -Envoy Gateway can be extended by vendors by means of an extension server developed by the vendor and deployed alongside Envoy Gateway. -An extension server can make use of one or more pre/post hooks inside Envoy Gateway before and after its major components (translator, etc.) to allow the extension to modify the data going into or coming out of these components. -An extension can be created external to Envoy Gateway as its own Kubernetes deployment or loaded as a sidecar. gRPC is used for the calls between Envoy Gateway and an extension. In the hook call, Envoy Gateway sends data as well -as context information to the extension and expects a reply with a modified version of the data that was sent to the extension. Since extensions fundamentally alter the logic and data that Envoy Gateway provides, Extension projects assume responsibility for any bugs and issues -they create as a direct result of their modification of Envoy Gateway. - -## Diagram - -![Architecture](/img/extension-example.png) - -## Registering Extensions in Envoy Gateway - -Information about the extension that Envoy Gateway needs to load is configured in the Envoy Gateway config. - -An example configuration: - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -extensionManager: - resources: - - group: example.myextension.io - version: v2 - kind: OAuth2Filter - hooks: - xdsTranslator: - post: - - Route - - VirtualHost - - HTTPListener - - Translation - service: - host: my-extension.example - port: 443 - tls: - certificateRef: - name: my-secret - namespace: default -``` - -An extension must supply connection information in the `extension.service` field so that Envoy Gateway can communicate with the extension. The `tls` configuration is optional. - -If the extension wants Envoy Gateway to watch resources for it then the extension must configure the optional `extension.resources` field and supply a list of: - -- `group`: the API group of the resource -- `version`: the API version of the resource -- `kind`: the Kind of resource - -The extension can configure the `extensionManager.hooks` field to specify which hook points it would like to support. If a given hook is not listed here then it will not be executed even -if the extension is configured properly. This allows extension developers to only opt-in to the hook points they want to make use of. - -This configuration is required to be provided at bootstrap and modifying the registered extension during runtime is not currently supported. -Envoy Gateway will keep track of the registered extension and its API `groups` and `kinds` when processing Gateway API resources. - -## Extending Gateway API and the Data Plane - -Envoy Gateway manages [Envoy][] deployments, which act as the data plane that handles actual user traffic. Users configure the data plane using the K8s Gateway API resources which Envoy -Gateway converts into [Envoy specific configuration (xDS)][] to send over to Envoy. - -Gateway API offers [ExtensionRef filters][] and [Policy Attachments][] as extension points for implementers to use. Envoy Gateway extends the Gateway API using these extension points to provide support for [rate limiting][] -and [authentication][] native to the project. The initial design of Envoy Gateway extensions will primarily focus on ExtensionRef filters so that extension developers can reference their own resources as HTTP Filters in the same way -that Envoy Gateway has native support for rate limiting and authentication filters. - -When Envoy Gateway encounters an [HTTPRoute][] or [GRPCRoute][] that has an `ExtensionRef` `filter` with a `group` and `kind` that Envoy Gateway does not support, it will first -check the registered extension to determine if it supports the referenced object before considering it a configuration error. - -This allows users to be able to reference additional filters provided by their Envoy Gateway Extension, in their `HTTPRoute`s / `GRPCRoute`s: - -```yaml -apiVersion: example.myextension.io/v1alpha1 -kind: OAuth2Filter -metadata: - name: oauth2-filter -spec: - ... - ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - clientSelectors: - - path: - type: PathPrefix - value: / - filters: - - type: ExtensionRef - extensionRef: - group: example.myextension.io - kind: OAuth2Filter - name: oauth2-filter - backendRefs: - - name: backend - port: 3000 -``` - -In order to enable the usage of new resources introduced by an extension for translation and xDS modification, Envoy Gateway provides hook points within the translation pipeline, where it calls out to the extension service registered in the [EnvoyGateway config][] -if they specify an `group` that matches the `group` of an `ExtensionRef` filter. The extension will then be able to modify the xDS that Envoy Gateway generated and send back the -modified configuration. If an extension is not registered or if the registered extension does not specify support for the `group` of an `ExtensionRef` filter then Envoy Gateway will treat it as an unknown resource -and provide an error to the user. - -**Note:** Currently (as of [v1][]) Gateway API does not provide a means to specify the namespace or version of an object referenced as an `ExtensionRef`. The extension mechanism will assume that -the namespace of any `ExtensionRef` is the same as the namespace of the `HTTPRoute` or `GRPCRoute` it is attached to rather than treating the `name` field of an `ExtensionRef` as a `name.namespace` string. -If Gateway API adds support for these fields then the design of the Envoy Gateway extensions will be updated to support them. - -## Watching New Resources - -Envoy Gateway will dynamically create new watches on resources introduced by the registered Extension. It does so by using the [controller-runtime][] to create new watches on [Unstructured][] resources that match the `version`s, `group`s, and `kind`s that the -registered extension configured. When communicating with an extension, Envoy Gateway sends these Unstructured resources over to the extension. This eliminates the need for the extension to create its own watches which would have a strong chance of creating race conditions and reconciliation loops when resources change. When an extension receives the Unstructured resources from Envoy Gateway it can perform its own type validation on them. Currently we make the simplifying assumption that the registered extension's `Kinds` are filters referenced by `extensionRef` in `HTTPRouteFilter`s . Support for Policy attachments will be introduced at a later time. - -## xDS Hooks API - -Envoy Gateway supports the following hooks as the initial foundation of the Extension system. Additional hooks can be developed using this extension system at a later point as new use-cases and needs are discovered. The primary iteration of the extension hooks -focuses solely on the modification of xDS resources. - -### Route Modification Hook - -The [Route][] level Hook provides a way for extensions to modify a route generated by Envoy Gateway before it is finalized. -Doing so allows extensions to configure/modify route fields configured by Envoy Gateway and also to configure the -Route's TypedPerFilterConfig which may be desirable to do things such as pass settings and information to ext_authz filters. -The Post Route Modify hook also passes a list of Unstructured data for the externalRefs owned by the extension on the HTTPRoute that created this xDS route -This hook is always executed when an extension is loaded that has added `Route` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`, and only on Routes which were generated from an HTTPRoute that uses extension resources as externalRef filters. - -```go -// PostRouteModifyRequest sends a Route that was generated by Envoy Gateway along with context information to an extension so that the Route can be modified -message PostRouteModifyRequest { - envoy.config.route.v3.Route route = 1; - PostRouteExtensionContext post_route_context = 2; -} - -// RouteExtensionContext provides resources introduced by an extension and watched by Envoy Gateway -// additional context information can be added to this message as more use-cases are discovered -message PostRouteExtensionContext { - // Resources introduced by the extension that were used as extensionRefs in an HTTPRoute/GRPCRoute - repeated ExtensionResource extension_resources = 1; - - // hostnames are the fully qualified domain names attached to the HTTPRoute - repeated string hostnames = 2; -} - -// ExtensionResource stores the data for a K8s API object referenced in an HTTPRouteFilter -// extensionRef. It is constructed from an unstructured.Unstructured marshalled to JSON. An extension -// can marshal the bytes from this resource back into an unstructured.Unstructured and then -// perform type checking to obtain the resource. -message ExtensionResource { - bytes unstructured_bytes = 1; -} - -// PostRouteModifyResponse is the expected response from an extension and contains a modified version of the Route that was sent -// If an extension returns a nil Route then it will not be modified -message PostRouteModifyResponse { - envoy.config.route.v3.Route route = 1; -} -``` - -### VirtualHost Modification Hook - -The [VirtualHost][] Hook provides a way for extensions to modify a VirtualHost generated by Envoy Gateway before it is finalized. -An extension can also make use of this hook to generate and insert entirely new Routes not generated by Envoy Gateway. -This hook is always executed when an extension is loaded that has added `VirtualHost` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`. -An extension may return nil to not make any changes to the VirtualHost. - -```protobuf -// PostVirtualHostModifyRequest sends a VirtualHost that was generated by Envoy Gateway along with context information to an extension so that the VirtualHost can be modified -message PostVirtualHostModifyRequest { - envoy.config.route.v3.VirtualHost virtual_host = 1; - PostVirtualHostExtensionContext post_virtual_host_context = 2; -} - -// Empty for now but we can add fields to the context as use-cases are discovered without -// breaking any clients that use the API -// additional context information can be added to this message as more use-cases are discovered -message PostVirtualHostExtensionContext {} - -// PostVirtualHostModifyResponse is the expected response from an extension and contains a modified version of the VirtualHost that was sent -// If an extension returns a nil Virtual Host then it will not be modified -message PostVirtualHostModifyResponse { - envoy.config.route.v3.VirtualHost virtual_host = 1; -} -``` - -### HTTP Listener Modification Hook - -The HTTP [Listener][] modification hook is the broadest xDS modification Hook available and allows an extension to make changes to a Listener generated by Envoy Gateway before it is finalized. -This hook is always executed when an extension is loaded that has added `HTTPListener` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`. An extension may return nil -in order to not make any changes to the Listener. - -```protobuf -// PostVirtualHostModifyRequest sends a Listener that was generated by Envoy Gateway along with context information to an extension so that the Listener can be modified -message PostHTTPListenerModifyRequest { - envoy.config.listener.v3.Listener listener = 1; - PostHTTPListenerExtensionContext post_listener_context = 2; -} - -// Empty for now but we can add fields to the context as use-cases are discovered without -// breaking any clients that use the API -// additional context information can be added to this message as more use-cases are discovered -message PostHTTPListenerExtensionContext {} - -// PostHTTPListenerModifyResponse is the expected response from an extension and contains a modified version of the Listener that was sent -// If an extension returns a nil Listener then it will not be modified -message PostHTTPListenerModifyResponse { - envoy.config.listener.v3.Listener listener = 1; -} -``` - -### Post xDS Translation Modify Hook - -The Post Translate Modify hook allows an extension to modify the clusters and secrets in the xDS config. -This allows for inserting clusters that may change along with extension specific configuration to be dynamically created rather than -using custom bootstrap config which would be sufficient for clusters that are static and not prone to have their configurations changed. -An example of how this may be used is to inject a cluster that will be used by an ext_authz http filter created by the extension. -The list of clusters and secrets returned by the extension are used as the final list of all clusters and secrets -This hook is always executed when an extension is loaded that has added `Translation` to the `EnvoyProxy.extensionManager.hooks.xdsTranslator.post`. - -```protobuf -// PostTranslateModifyRequest currently sends only clusters and secrets to an extension. -// The extension is free to add/modify/remove the resources it received. -message PostTranslateModifyRequest { - PostTranslateExtensionContext post_translate_context = 1; - repeated envoy.config.cluster.v3.Cluster clusters = 2; - repeated envoy.extensions.transport_sockets.tls.v3.Secret secrets = 3; -} - -// PostTranslateModifyResponse is the expected response from an extension and contains -// the full list of xDS clusters and secrets to be used for the xDS config. -message PostTranslateModifyResponse { - repeated envoy.config.cluster.v3.Cluster clusters = 1; - repeated envoy.extensions.transport_sockets.tls.v3.Secret secrets = 2; -} -``` - -### Extension Service - -Currently, an extension must implement all of the following hooks although it may return the input(s) it received -if no modification of the resource is desired. A future expansion of the extension hooks will allow an Extension to specify -with config which Hooks it would like to "subscribe" to and which Hooks it does not wish to support. These specific Hooks were chosen -in order to provide extensions with the ability to have both broad and specific control over xDS resources and to minimize the amount of data being sent. - -```protobuf -service EnvoyGatewayExtension { - rpc PostRouteModify (PostRouteModifyRequest) returns (PostRouteModifyResponse) {}; - rpc PostVirtualHostModify(PostVirtualHostModifyRequest) returns (PostVirtualHostModifyResponse) {}; - rpc PostHTTPListenerModify(PostHTTPListenerModifyRequest) returns (PostHTTPListenerModifyResponse) {}; - rpc PostTranslateModify(PostTranslateModifyRequest) returns (PostTranslateModifyResponse) {}; -} -``` - -## Design Decisions - -- Envoy Gateway watches new custom resources introduced by a loaded extension and passes the resources back to the extension when they are used. - - This decision was made to solve the problem about how resources introduced by an extension get watched. If an extension server watches its own resources then it would need some way to trigger an Envoy Gateway reconfigure when a resource that Envoy Gateway is not watching gets updated. Having Envoy Gateway watch all resources removes any concern about creating race confitions or reconcile loops that would result from Envoy Gateway and the extension server both having so much separate state that needs to be synchronized. -- The Extension Server takes ownership of producing the correct xDS configuration in the hook responses -- The Extension Server will be responsible for ensuring the performance of the hook processing time -- The Post xDS level gRPC hooks all currently send a context field even though it contains nothing for several hooks. These fields exist so that they can be updadated in the future to pass -additional information to extensions as new use-cases and needs are discovered. -- The initial design supplies the scaffolding for both "pre xDS" and "post xDS" hooks. Only the post hooks are currently implemented which operate on xDS resources after they have been generated. -The pre hooks will be implemented at a later date along with one or more hooks in the infra manager. The infra manager level hook(s) will exist to power use-cases such as dynamically creating Deployments/Services for the extension the -whenever Envoy Gateway creates an instance of Envoy Proxy. An extension developer might want to take advantage of this functionality to inject a new authorization service as a sidecar on the Envoy Proxy deployment for reduced latency. -- Multiple extensions are not be supported at the same time. Preventing conflict between multiple extensions that are mangling xDS resources is too difficult to ensure compatibility with and is likely to only generate issues. - -## Known Challenges - -Extending Envoy Gateway by using an external extension server which makes use of hook points in Envoy Gateway does comes with a few trade-offs. One known trade-off is the impact of the time that it takes for the hook calls to be executed. Since an extension would make use of hook points in Envoy Gateway that use gRPC for communication, the time it takes to perform these requests could become a concern for some extension developers. One way to minimize the request time of the hook calls is to load the extension server as a sidecar to Envoy Gateway to minimize the impact of networking on the hook calls. - -[official goals]: https://github.com/envoyproxy/gateway/blob/main/GOALS.md#extensibility -[ExtensionRef filters]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalObjectReference -[ExtensionRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalObjectReference -[ExtensionRefs]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalObjectReference -[backendRefs]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.BackendObjectReference -[Gateway API Policy attachments]: https://gateway-api.sigs.k8s.io/references/policy-attachment/?h=policy -[Policy Attachments]: https://gateway-api.sigs.k8s.io/references/policy-attachment/?h=policy -[policyAttachments]: https://gateway-api.sigs.k8s.io/references/policy-attachment/?h=policy -[Envoy]: https://www.envoyproxy.io/ -[Envoy specific configuration (xDS)]: https://www.envoyproxy.io/docs/envoy/v1.25.1/configuration/configuration -[v1]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1 -[rate limiting]: ./rate-limit -[authentication]: ../../tasks/security/jwt-authentication -[HTTPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute -[GRPCRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute -[EnvoyGateway config]: ../../api/extension_types/#envoygateway -[controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime -[Unstructured]: https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured -[Listener]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/listener/v3/listener.proto#config-listener-v3-listener -[VirtualHost]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/route/v3/route_components.proto#config-route-v3-virtualhost -[Route]: https://www.envoyproxy.io/docs/envoy/v1.23.0/api-v3/config/route/v3/route_components.proto#config-route-v3-route diff --git a/site/content/en/latest/install/api.md b/site/content/en/latest/install/api.md index 47351ba771b..b156702164a 100644 --- a/site/content/en/latest/install/api.md +++ b/site/content/en/latest/install/api.md @@ -26,7 +26,7 @@ The Helm chart for Envoy Gateway |-----|------|---------|-------------| | certgen.job.annotations | object | `{}` | | | certgen.job.resources | object | `{}` | | -| certgen.job.ttlSecondsAfterFinished | int | `0` | | +| certgen.job.ttlSecondsAfterFinished | int | `30` | | | certgen.rbac.annotations | object | `{}` | | | certgen.rbac.labels | object | `{}` | | | config.envoyGateway.gateway.controllerName | string | `"gateway.envoyproxy.io/gatewayclass-controller"` | | @@ -35,7 +35,7 @@ The Helm chart for Envoy Gateway | createNamespace | bool | `false` | | | deployment.envoyGateway.image.repository | string | `"${ImageRepository}"` | | | deployment.envoyGateway.image.tag | string | `"${ImageTag}"` | | -| deployment.envoyGateway.imagePullPolicy | string | `"Always"` | | +| deployment.envoyGateway.imagePullPolicy | string | `"IfNotPresent"` | | | deployment.envoyGateway.imagePullSecrets | list | `[]` | | | deployment.envoyGateway.resources.limits.cpu | string | `"500m"` | | | deployment.envoyGateway.resources.limits.memory | string | `"1024Mi"` | | diff --git a/site/content/en/latest/install/install-helm.md b/site/content/en/latest/install/install-helm.md index 50c372d3e2a..69efd45390c 100644 --- a/site/content/en/latest/install/install-helm.md +++ b/site/content/en/latest/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/latest/install/install-yaml.md b/site/content/en/latest/install/install-yaml.md index 4fc9b38b0dd..b8b02582b2d 100644 --- a/site/content/en/latest/install/install-yaml.md +++ b/site/content/en/latest/install/install-yaml.md @@ -25,7 +25,7 @@ Refer to the [Version Compatibility Matrix](./matrix) to learn more. Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} 1. In your terminal, run the following command: diff --git a/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md b/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md index 94d71fc7c77..ff819754d1f 100644 --- a/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md +++ b/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md @@ -32,6 +32,8 @@ Before proceeding, you should be able to query the example backend using HTTP. * The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it using a `ConfigMap`. In the next step, we will update this resource to enable EnvoyPatchPolicy. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell cat <}} + * After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in ```shell @@ -63,10 +91,13 @@ kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system ### Customize Response -* Lets use EnvoyProxy's [Local Reply Modification][] feature to return a custom response back to the client when +* Use EnvoyProxy's [Local Reply Modification][] feature to return a custom response back to the client when the status code is `404` -* Lets apply the configuration +* Apply the configuration + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell cat <// + name: default/eg/http + operation: + op: add + path: "/default_filter_chain/filters/0/typed_config/local_reply_config" + value: + mappers: + - filter: + status_code_filter: + comparison: + op: EQ + value: + default_value: 404 + runtime_key: key_b + status_code: 406 + body: + inline_string: "could not find what you are looking for" +``` + +{{% /tab %}} +{{< /tabpane >}} + When mergeGateways is enabled, there will be one Envoy deployment for all Gateways in the cluster. Then the EnvoyPatchPolicy should target a specific GatewayClass. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <// + name: default/eg/http + operation: + op: add + path: "/default_filter_chain/filters/0/typed_config/local_reply_config" + value: + mappers: + - filter: + status_code_filter: + comparison: + op: EQ + value: + default_value: 404 + runtime_key: key_b + status_code: 406 + body: + inline_string: "could not find what you are looking for" ``` -kubectl patch httproute backend --type=json --patch '[{ - "op": "add", - "path": "/spec/rules/0/matches/0/path/value", - "value": "/get", -}]' + +{{% /tab %}} +{{< /tabpane >}} + +* Edit the HTTPRoute resource from the Quickstart to only match on paths with value `/get` + +```shell +kubectl patch httproute backend --type=json --patch ' + - op: add + path: /spec/rules/0/matches/0/path/value + value: /get + ' ``` -* Lets test it out by specifying a path apart from `/get` +* Test it out by specifying a path apart from `/get` ``` $ curl --header "Host: www.example.com" http://localhost:8888/find @@ -169,7 +287,7 @@ could not find what you are looking for `Accepted=True` and `Programmed=True` conditions are set to ensure that the policy has been applied to Envoy Proxy. -``` +```yaml apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyPatchPolicy metadata: diff --git a/site/content/en/latest/tasks/observability/rate-limit-observability.md b/site/content/en/latest/tasks/observability/rate-limit-observability.md new file mode 100644 index 00000000000..478b85859b9 --- /dev/null +++ b/site/content/en/latest/tasks/observability/rate-limit-observability.md @@ -0,0 +1,107 @@ +--- +title: "RateLimit Observability" +--- + +Envoy Gateway provides observability for the RateLimit instances. +This guide show you how to config RateLimit observability, includes traces. + +## Prerequisites + +Follow the steps from the [Quickstart Guide](../quickstart) to install Envoy Gateway and the HTTPRoute example manifest. +Before proceeding, you should be able to query the example backend using HTTP. Follow the steps from the [Global Rate Limit](../traffic/global-rate-limit) to install RateLimit. + +[OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) offers a vendor-agnostic implementation of how to receive, process and export telemetry data. + +Install OTel-Collector: + +```shell +helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts +helm repo update +helm upgrade --install otel-collector open-telemetry/opentelemetry-collector -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/otel-collector/helm-values.yaml -n monitoring --create-namespace --version 0.60.0 +``` + +## Traces + +By default, the Envoy Gateway does not configure RateLimit to send traces to the OpenTelemetry Sink. +You can configure the collector in the `rateLimit.telemetry.tracing` of the `EnvoyGateway`CRD. + +RateLimit uses the OpenTelemetry Exporter to export traces to the collector. +You can configure a collector that supports the OTLP protocol, which includes but is not limited to: OpenTelemetry Collector, Jaeger, Zipkin, and so on. + +***Note:*** + +* By default, the Envoy Gateway configures a `100%` sampling rate for RateLimit, which may lead to performance issues. + +Assuming the OpenTelemetry Collector is running in the `observability` namespace, and it has a service named `otel-svc`, +we only want to sample `50%` of the trace data. We would configure it as follows: + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +After updating the ConfigMap, you will need to restart the envoy-gateway deployment so the configuration kicks in: + +```shell +kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system +``` diff --git a/site/content/en/latest/tasks/operations/customize-envoyproxy.md b/site/content/en/latest/tasks/operations/customize-envoyproxy.md index 76004a83676..152f9e7ff44 100644 --- a/site/content/en/latest/tasks/operations/customize-envoyproxy.md +++ b/site/content/en/latest/tasks/operations/customize-envoyproxy.md @@ -15,6 +15,9 @@ Before proceeding, you should be able to query the example backend using HTTP. First, you need to add ParametersRef in GatewayClass, and refer to EnvoyProxy Config: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Customize EnvoyProxy Deployment Replicas You can customize the EnvoyProxy Deployment Replicas via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After you apply the config, you should see the replicas of envoyproxy changes to 2. And also you can dynamically change the value. @@ -62,6 +112,9 @@ kubectl get deployment -l gateway.envoyproxy.io/owning-gateway-name=eg -n envoy- You can customize the EnvoyProxy Image via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the deployment image, and see it has changed. ## Customize EnvoyProxy Pod Annotations You can customize the EnvoyProxy Pod Annotations via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the envoyproxy pods, and see new annotations has been added. ## Customize EnvoyProxy Deployment Resources You can customize the EnvoyProxy Deployment Resources via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Customize EnvoyProxy Deployment Env You can customize the EnvoyProxy Deployment Env via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + > Envoy Gateway has provided two initial `env` `ENVOY_GATEWAY_NAMESPACE` and `ENVOY_POD_NAME` for envoyproxy container. After applying the config, you can get the envoyproxy deployment, and see resources has been changed. @@ -166,6 +332,9 @@ After applying the config, you can get the envoyproxy deployment, and see resour You can customize the EnvoyProxy Deployment Volumes or VolumeMounts via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the envoyproxy deployment, and see resources has been changed. ## Customize EnvoyProxy Service Annotations You can customize the EnvoyProxy Service Annotations via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the envoyproxy service, and see annotations has been added. ## Customize EnvoyProxy Bootstrap Config @@ -226,6 +452,9 @@ There are two ways to customize it: * Replace: the whole bootstrap config will be replaced by the config you provided. * Merge: the config you provided will be merged into the default bootstrap config. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + You can use [egctl translate][] to get the default xDS Bootstrap configuration used by Envoy Gateway. @@ -323,6 +642,9 @@ You can enable [Horizontal Pod Autoscaler](https://github.com/envoyproxy/gateway Once confirmed, you can apply it via EnvoyProxy Config as shown below: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, the EnvoyProxy HPA (Horizontal Pod Autoscaler) is generated. However, upon activating the EnvoyProxy's HPA, the Envoy Gateway will no longer reference the `replicas` field specified in the `envoyDeployment`, as outlined [here](#customize-envoyproxy-deployment-replicas). ## Customize EnvoyProxy Command line options @@ -354,6 +706,9 @@ After applying the config, the EnvoyProxy HPA (Horizontal Pod Autoscaler) is gen You can customize the EnvoyProxy Command line options via `spec.extraArgs` in EnvoyProxy Config. For example, the following configuration will add `--disable-extensions` arg in order to disable `envoy.access_loggers/envoy.access_loggers.wasm` extension: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Customize EnvoyProxy with Patches You can customize the EnvoyProxy using patches. For example, the following configuration will add resource limits to the `envoy` and the `shutdown-manager` containers in the `envoyproxy` deployment: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the configuration, you will see the change in both containers in the `envoyproxy` deployment. [Gateway API documentation]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/latest/tasks/operations/deployment-mode.md b/site/content/en/latest/tasks/operations/deployment-mode.md index dd3ea9ea6f8..16b339fe571 100644 --- a/site/content/en/latest/tasks/operations/deployment-mode.md +++ b/site/content/en/latest/tasks/operations/deployment-mode.md @@ -57,6 +57,9 @@ eg-marketing oci://docker.io/envoyproxy/gateway-helm \ Lets create a `GatewayClass` linked to the marketing team's Envoy Gateway controller, and as well other resources linked to it, so the `backend` application operated by this team can be exposed to external clients. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Lets port forward to the generated envoy proxy service in the `marketing` namespace and send a request to it. ```shell @@ -235,6 +345,9 @@ eg-product oci://docker.io/envoyproxy/gateway-helm \ Lets create a `GatewayClass` linked to the product team's Envoy Gateway controller, and as well other resources linked to it, so the `backend` application operated by this team can be exposed to external clients. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Lets port forward to the generated envoy proxy service in the `product` namespace and send a request to it. ```shell @@ -608,6 +828,9 @@ kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/ Lets create also and additional `Gateway` linked to the GatewayClass and `backend` application from Quickstart example. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify that Gateways are deployed and programmed ```shell diff --git a/site/content/en/latest/tasks/operations/egctl.md b/site/content/en/latest/tasks/operations/egctl.md index c8ee3a34a99..3b25bc23456 100644 --- a/site/content/en/latest/tasks/operations/egctl.md +++ b/site/content/en/latest/tasks/operations/egctl.md @@ -884,11 +884,11 @@ We can specify to install only CRDs resources via `--only-crds` egctl x install --only-crds ``` -We can specify `--release-name` and `--namespace` to install envoy-gateway in different places to support multi-tenant mode. +We can specify `--name` and `--namespace` to install envoy-gateway in different places to support multi-tenant mode. > Note: If CRDs are already installed, then we need to specify `--skip-crds` to avoid repeated installation of CRDs resources. ```bash -egctl x install --release-name shop-backend --namespace shop +egctl x install --name shop-backend --namespace shop ``` diff --git a/site/content/en/latest/tasks/quickstart.md b/site/content/en/latest/tasks/quickstart.md index 980190b2bbf..4f345fa289a 100644 --- a/site/content/en/latest/tasks/quickstart.md +++ b/site/content/en/latest/tasks/quickstart.md @@ -47,6 +47,28 @@ consideration when debugging. ## Testing the Configuration +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} + +You can also test the same functionality by sending traffic to the External IP. To get the external IP of the +Envoy service, run: + +```shell +export GATEWAY_HOST=$(kubectl get svc/${ENVOY_SERVICE} -n envoy-gateway-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +``` + +In certain environments, the load balancer may be exposed using a hostname, instead of an IP address. If so, replace +`ip` in the above command with `hostname`. + +Curl the example app through Envoy proxy: + +```shell +curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get +``` + +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} + Get the name of the Envoy service created the by the example Gateway: ```shell @@ -65,23 +87,25 @@ Curl the example app through Envoy proxy: curl --verbose --header "Host: www.example.com" http://localhost:8888/get ``` -### External LoadBalancer Support +{{% /tab %}} +{{< /tabpane >}} -You can also test the same functionality by sending traffic to the External IP. To get the external IP of the -Envoy service, run: +## What to explore next? -```shell -export GATEWAY_HOST=$(kubectl get svc/${ENVOY_SERVICE} -n envoy-gateway-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}') -``` +In this quickstart, you have: +- Installed Envoy Gateway +- Deployed a backend service, and a gateway +- Configured the gateway using Kubernetes Gateway API resources [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway/) and [HttpRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/) to direct incoming requests over HTTP to the backend service. -In certain environments, the load balancer may be exposed using a hostname, instead of an IP address. If so, replace -`ip` in the above command with `hostname`. +Here is a suggested list of follow-on tasks to guide you in your exploration of Envoy Gateway: -Curl the example app through Envoy proxy: +- [HTTP Routing](traffic/http-routing) +- [Traffic Splitting](traffic/http-traffic-splitting) +- [Secure Gateways](security/secure-gateways/) +- [Global Rate Limit](traffic/global-rate-limit/) +- [gRPC Routing](traffic/grpc-routing/) -```shell -curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get -``` +Review the [Tasks](./) section for the scenario matching your use case. The Envoy Gateway tasks are organized by category: traffic management, security, extensibility, observability, and operations. ## Clean-Up @@ -101,4 +125,4 @@ helm uninstall eg -n envoy-gateway-system ## Next Steps -Checkout the [Developer Guide](../contributions/develop) to get involved in the project. +Checkout the [Developer Guide](../../contributions/develop) to get involved in the project. diff --git a/site/content/en/latest/tasks/security/backend-tls.md b/site/content/en/latest/tasks/security/backend-tls.md index 975e8a5f13c..aeedcd503d4 100644 --- a/site/content/en/latest/tasks/security/backend-tls.md +++ b/site/content/en/latest/tasks/security/backend-tls.md @@ -29,7 +29,7 @@ Create a certificate and a private key for `www.example.com`: ```shell openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" -openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt +openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt ``` Store the cert/key in a Secret: @@ -49,60 +49,41 @@ kubectl create configmap example-ca --from-file=ca.crt Patch the existing quickstart backend to enable TLS. The patch will mount the TLS certificate secret into the backend as volume. ```shell -kubectl patch deployment backend --type=json --patch '[ - { - "op": "add", - "path": "/spec/template/spec/containers/0/volumeMounts", - "value": [ - { - "name": "secret-volume", - "mountPath": "/etc/secret-volume" - } - ] - }, - { - "op": "add", - "path": "/spec/template/spec/volumes", - "value": [ - { - "name": "secret-volume", - "secret": { - "secretName": "example-cert", - "items": [ - { - "key": "tls.crt", - "path": "crt" - }, - { - "key": "tls.key", - "path": "key" - } - ] - } - } - ] - }, - { - "op": "add", - "path": "/spec/template/spec/containers/0/env/-", - "value": { - "name": "TLS_SERVER_CERT", - "value": "/etc/secret-volume/crt" - } - }, - { - "op": "add", - "path": "/spec/template/spec/containers/0/env/-", - "value": { - "name": "TLS_SERVER_PRIVKEY", - "value": "/etc/secret-volume/key" - } - } -]' +kubectl patch deployment backend --type=json --patch ' + - op: add + path: /spec/template/spec/containers/0/volumeMounts + value: + - name: secret-volume + mountPath: /etc/secret-volume + - op: add + path: /spec/template/spec/volumes + value: + - name: secret-volume + secret: + secretName: example-cert + items: + - key: tls.crt + path: crt + - key: tls.key + path: key + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: TLS_SERVER_CERT + value: /etc/secret-volume/crt + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: TLS_SERVER_PRIVKEY + value: /etc/secret-volume/key + ' ``` Create a service that exposes port 443 on the backend service. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Create a [BackendTLSPolicy][] instructing Envoy Gateway to establish a TLS connection with the backend and validate the backend certificate is issued by a trusted CA and contains an appropriate DNS SAN. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Patch the HTTPRoute's backend reference, so that it refers to the new TLS-enabled service: ```shell -kubectl patch HTTPRoute backend --type=json --patch '[ - { - "op": "replace", - "path": "/spec/rules/0/backendRefs/0/port", - "value": 443 - }, - { - "op": "replace", - "path": "/spec/rules/0/backendRefs/0/name", - "value": "tls-backend" - } -]' +kubectl patch HTTPRoute backend --type=json --patch ' + - op: replace + path: /spec/rules/0/backendRefs/0/port + value: 443 + - op: replace + path: /spec/rules/0/backendRefs/0/name + value: tls-backend + ' ``` Verify the HTTPRoute status: @@ -173,24 +208,19 @@ kubectl get HTTPRoute backend -o yaml ## Testing -### Clusters without External LoadBalancer Support - -Get the name of the Envoy service created the by the example Gateway: - -```shell -export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') -``` +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} -Port forward to the Envoy service: +Get the External IP of the Gateway: ```shell -kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 80:80 & +export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') ``` -Query the TLS-enabled backend through Envoy proxy: +Query the example app through the Gateway: ```shell -curl -v -HHost:www.example.com --resolve "www.example.com:80:127.0.0.1" \ +curl -v -HHost:www.example.com --resolve "www.example.com:80:${GATEWAY_HOST}" \ http://www.example.com:80/get ``` @@ -207,18 +237,25 @@ Inspect the output and see that the response contains the details of the TLS han } ``` -### Clusters with External LoadBalancer Support +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} -Get the External IP of the Gateway: +Get the name of the Envoy service created the by the example Gateway: ```shell -export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') +export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') ``` -Query the example app through the Gateway: +Port forward to the Envoy service: ```shell -curl -v -HHost:www.example.com --resolve "www.example.com:80:${GATEWAY_HOST}" \ +kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 80:80 & +``` + +Query the TLS-enabled backend through Envoy proxy: + +```shell +curl -v -HHost:www.example.com --resolve "www.example.com:80:127.0.0.1" \ http://www.example.com:80/get ``` @@ -235,4 +272,7 @@ Inspect the output and see that the response contains the details of the TLS han } ``` +{{% /tab %}} +{{< /tabpane >}} + [BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/ diff --git a/site/content/en/latest/tasks/security/basic-auth.md b/site/content/en/latest/tasks/security/basic-auth.md index 28c3ca53d5c..04559a8d2bc 100644 --- a/site/content/en/latest/tasks/security/basic-auth.md +++ b/site/content/en/latest/tasks/security/basic-auth.md @@ -49,23 +49,20 @@ Update the Gateway from the Quickstart to include an HTTPS listener that listens `example-cert` Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https", - "protocol": "HTTPS", - "port": 443, - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "example-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: example-cert + ' ``` ### Create a .htpasswd file @@ -103,6 +100,9 @@ kubectl create secret generic basic-auth --from-file=.htpasswd The below example defines a SecurityPolicy that authenticates requests against the user list in the kubernetes secret generated in the previous step. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the SecurityPolicy configuration: ```shell @@ -188,9 +211,9 @@ kubectl delete secret/example-cert ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [http Basic authentication]: https://tools.ietf.org/html/rfc2617 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/cors.md b/site/content/en/latest/tasks/security/cors.md index 1abbe77a737..cfbe979cd22 100644 --- a/site/content/en/latest/tasks/security/cors.md +++ b/site/content/en/latest/tasks/security/cors.md @@ -22,6 +22,9 @@ In addition to that the entire origin (with or without specifying a scheme) can The below example defines a SecurityPolicy that allows CORS for all HTTP requests originating from `www.foo.com`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the SecurityPolicy configuration: ```shell @@ -132,9 +168,9 @@ kubectl delete securitypolicy/cors-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/ext-auth.md b/site/content/en/latest/tasks/security/ext-auth.md index b3eafd7e0be..1676b60ded1 100644 --- a/site/content/en/latest/tasks/security/ext-auth.md +++ b/site/content/en/latest/tasks/security/ext-auth.md @@ -34,6 +34,9 @@ kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/exa Create a new HTTPRoute resource to route traffic on the path `/myapp` to the backend service. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the HTTPRoute status: ```shell @@ -69,6 +100,9 @@ Create a new SecurityPolicy resource to configure the external authorization. Th authorization. The `headersToBackend` field specifies the headers that will be sent to the backend service if the request is successfully authorized. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the SecurityPolicy configuration: ```shell @@ -162,6 +222,9 @@ not created the HTTPRoute, you can create it now. Create a new HTTPRoute resource to route traffic on the path `/myapp` to the backend service. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the HTTPRoute status: ```shell @@ -195,6 +286,9 @@ kubectl get httproute/myapp -o yaml Update the SecurityPolicy that was created in the previous section to use the gRPC external authorization service. It calls the gRPC external authorization service "grpc-ext-auth" on port 9002 for authorization. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the SecurityPolicy configuration: ```shell @@ -223,6 +342,9 @@ kubectl get securitypolicy/ext-auth-example -o yaml Because the gRPC external authorization service is enabled with TLS, a BackendTLSConfig needs to be created to configure the communication between the Envoy proxy and the gRPC auth service. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the BackendTLSPolicy configuration: ```shell @@ -304,8 +453,8 @@ kubectl delete backendtlspolicy/grpc-ext-auth-btls ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/jwt-authentication.md b/site/content/en/latest/tasks/security/jwt-authentication.md index 2e129b387f1..8b160403882 100644 --- a/site/content/en/latest/tasks/security/jwt-authentication.md +++ b/site/content/en/latest/tasks/security/jwt-authentication.md @@ -160,9 +160,9 @@ kubectl delete securitypolicy/jwt-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [jwt]: https://tools.ietf.org/html/rfc7519 [jwks]: https://tools.ietf.org/html/rfc7517 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway diff --git a/site/content/en/latest/tasks/security/mutual-tls.md b/site/content/en/latest/tasks/security/mutual-tls.md index 69bb744cacc..64f471ba19d 100644 --- a/site/content/en/latest/tasks/security/mutual-tls.md +++ b/site/content/en/latest/tasks/security/mutual-tls.md @@ -54,23 +54,20 @@ Update the Gateway from the Quickstart to include an HTTPS listener that listens `example-cert` Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https", - "protocol": "HTTPS", - "port": 443, - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "example-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: example-cert + ' ``` Verify the Gateway status: @@ -81,6 +78,9 @@ kubectl get gateway/eg -o yaml Create a [ClientTrafficPolicy][] to enforce client validation using the CA Certificate as a trusted anchor. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Testing -### Clusters without External LoadBalancer Support +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} -Get the name of the Envoy service created the by the example Gateway: +Get the External IP of the Gateway: ```shell -export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') +export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') ``` -Port forward to the Envoy service: +Query the example app through the Gateway: ```shell -kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 & +curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ +--cert client.example.com.crt --key client.example.com.key \ +--cacert example.com.crt https://www.example.com/get ``` -Query the example app through Envoy proxy: +Don't specify the client key and certificate in the above command, and ensure that the connection fails: ```shell -curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \ ---cert client.example.com.crt --key client.example.com.key \ ---cacert example.com.crt https://www.example.com:8443/get +curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ +--cacert example.com.crt https://www.example.com/get ``` -### Clusters with External LoadBalancer Support +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} -Get the External IP of the Gateway: +Get the name of the Envoy service created the by the example Gateway: ```shell -export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') +export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') ``` -Query the example app through the Gateway: +Port forward to the Envoy service: ```shell -curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ ---cert client.example.com.crt --key client.example.com.key \ ---cacert example.com.crt https://www.example.com/get +kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 & ``` -Dont specify the client key and certificate in the above command, and ensure that the connection fails +Query the example app through Envoy proxy: ```shell -curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ ---cacert example.com.crt https://www.example.com/get +curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \ +--cert client.example.com.crt --key client.example.com.key \ +--cacert example.com.crt https://www.example.com:8443/get ``` +{{% /tab %}} +{{< /tabpane >}} + [ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy diff --git a/site/content/en/latest/tasks/security/oidc.md b/site/content/en/latest/tasks/security/oidc.md index 9b168822796..ac7d6d60ba9 100644 --- a/site/content/en/latest/tasks/security/oidc.md +++ b/site/content/en/latest/tasks/security/oidc.md @@ -4,7 +4,7 @@ title: "OIDC Authentication" This task provides instructions for configuring [OpenID Connect (OIDC)][oidc] authentication. OpenID Connect (OIDC) is an authentication standard built on top of OAuth 2.0. -It enables client applications to rely on authentication that is performed by an OpenID Connect Provider (OP) +It enables EG to rely on authentication that is performed by an OpenID Connect Provider (OP) to verify the identity of a user. Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure OIDC @@ -16,19 +16,20 @@ This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute] Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP. +EG OIDC authentication requires the redirect URL to be HTTPS. Follow the [Secure Gateways](../secure-gateways) guide +to generate the TLS certificates and update the Gateway configuration to add an HTTPS listener. + Verify the Gateway status: ```shell kubectl get gateway/eg -o yaml ``` -OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with -the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations. - -This task demonstrates the configuration of OIDC at the HTTPRoute level. - Let's create an HTTPRoute that represents an application protected by OIDC. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the HTTPRoute status: ```shell kubectl get httproute/myapp -o yaml ``` -## Configuration +## OIDC Authentication for a HTTPRoute -This task uses Google as the OIDC provider to demonstrate the configuration of OIDC. However, EG works with any OIDC -providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA, etc. +OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with +the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations. + +This section demonstrates how to configure OIDC authentication for a specific HTTPRoute. ### Register an OIDC application +This task uses Google as the OIDC provider to demonstrate the configuration of OIDC. However, EG works with any OIDC +providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA, etc. + Follow the steps in the [Google OIDC documentation][google-oidc] to register an OIDC application. Please make sure the redirect URL is set to the one you configured in the SecurityPolicy that you will create in the step below. In this example, -the redirect URL is `http://www.example.com:8080/myapp/oauth2/callback`. +the redirect URL is `http://www.example.com:8443/myapp/oauth2/callback`. After registering the application, you should have the following information: * Client ID: The client ID of the OIDC application. @@ -79,20 +112,22 @@ and the Client Secret must be stored in the key "client-secret". Note: please replace the ${CLIENT_SECRET} with the actual Client Secret that you got from the previous step. ```shell -$ kubectl create secret generic my-app-client-secret --from-literal=client-secret=${CLIENT_SECRET} -secret "my-app-client-secret" created +kubectl create secret generic my-app-client-secret --from-literal=client-secret=${CLIENT_SECRET} ``` ### Create a SecurityPolicy -Please notice that the `redirectURL` and `logoutPath` must match the target HTTPRoute. In this example, the target +**Please notice that the `redirectURL` and `logoutPath` must match the target HTTPRoute.** In this example, the target HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed -with `http://www.example.com:8080/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication +with `https://www.example.com:8443/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed by the OAuth2 filter on that HTTPRoute. Note: please replace the ${CLIENT_ID} in the below yaml snippet with the actual Client ID that you got from the OIDC provider. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the SecurityPolicy configuration: ```shell kubectl get securitypolicy/oidc-example -o yaml ``` -## Testing +### Testing Port forward gateway port to localhost: ```shell export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') -kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8080:80 +kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 ``` Put www.example.com in the /etc/hosts file in your test machine, so we can use this host name to access the gateway from a browser: @@ -138,9 +201,104 @@ Put www.example.com in the /etc/hosts file in your test machine, so we can use t 127.0.0.1 www.example.com ``` -Open a browser and navigate to the `http://www.example.com:8080/myapp` address. You should be redirected to the Google +Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google +login page. After you successfully login, you should see the response from the backend service. + +Clean the cookies in the browser and try to access `https://www.example.com:8443/foo` address. You should be able to see +this page since the path `/foo` is not protected by the OIDC policy. + +## OIDC Authentication for a Gateway + +OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with +the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations. + +This section demonstrates how to configure OIDC authentication for a Gateway. + +### Register an OIDC application + +If you haven't registered an OIDC application, follow the steps in the previous section to register an OIDC application. + +### Create a kubernetes secret + +If you haven't created a kubernetes secret, follow the steps in the previous section to create a kubernetes secret. + +### Create a SecurityPolicy + +Create or update the SecurityPolicy to target the Gateway instead of the HTTPRoute. **Please notice that the `redirectURL` +and `logoutPath` must match one of the HTTPRoutes associated with the Gateway.** In this example, the target Gateway has +two HTTPRoutes associated with it, one with the host `www.example.com` and the path `/myapp`, and the other with the host +`www.example.com` and the path `/`. Either one of the HTTPRoutes can be used to match the `redirectURL` and `logoutPath`. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +Verify the SecurityPolicy configuration: + +```shell +kubectl get securitypolicy/oidc-example -o yaml +``` + +### Testing + +If you haven't done so, follow the steps in the previous section to port forward gateway port to localhost and put +www.example.com in the /etc/hosts file in your test machine. + +Open a browser and navigate to the `https://www.example.com:8443/foo` address. You should be redirected to the Google login page. After you successfully login, you should see the response from the backend service. +You can also try to access `https://www.example.com:8443/myapp` address. You should be able to see this page since the +path `/myapp` is protected by the same OIDC policy. + ## Clean-Up Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest. @@ -155,10 +313,10 @@ kubectl delete httproute/myapp ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../../contributions/develop) to get involved in the project. [oidc]: https://openid.net/connect/ [google-oidc]: https://developers.google.com/identity/protocols/oauth2/openid-connect -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/latest/tasks/security/private-key-provider.md b/site/content/en/latest/tasks/security/private-key-provider.md index 447e61cb353..cf40a96e9e1 100644 --- a/site/content/en/latest/tasks/security/private-key-provider.md +++ b/site/content/en/latest/tasks/security/private-key-provider.md @@ -114,25 +114,52 @@ It required the node with 3rd generation Intel Xeon Scalable processor server pr * Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway. -* Lets enable the EnvoyPatchPolicy feature, which will allow us to directly configure the Private Key Provider Envoy Filter, since Envoy Gateway does not directly expose this functionality. +* Enable the EnvoyPatchPolicy feature, which will allow us to directly configure the Private Key Provider Envoy Filter, since Envoy Gateway does not directly expose this functionality. - ```shell - cat <}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} * After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in @@ -146,26 +173,54 @@ It required the node with 3rd generation Intel Xeon Scalable processor server pr * Update GatewayClass for using the envoyproxy image with contrib extensions and requests required resources. - ```shell - cat <}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} ### Change EnvoyProxy configuration for QAT Using the envoyproxy image with contrib extensions and add qat resources requesting, ensure the k8s scheduler find out a machine with required resource. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### Change EnvoyProxy configuration for CryptoMB Using the envoyproxy image with contrib extensions and add the node affinity to scheduling the Envoy Gateway pod on the machine with required CPU instructions. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Or using `preferredDuringSchedulingIgnoredDuringExecution` for best effort scheduling, or not doing any node affinity, just doing the random scheduling. The CryptoMB private key provider supports software fallback if the required CPU instructions aren't here. ## Apply EnvoyPatchPolicy to enable private key provider @@ -276,6 +418,9 @@ fortio load -c 10 -k -qps 0 -t 30s -keepalive=false https://www.example.com:${NO ### For QAT +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### For CryptoMB +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### Benchmark after enabling private key provider First follow the instructions in [TLS Termination for TCP](./tls-termination) to do the functionality test again. diff --git a/site/content/en/latest/tasks/security/secure-gateways.md b/site/content/en/latest/tasks/security/secure-gateways.md index f1f1f525526..af5e922412d 100644 --- a/site/content/en/latest/tasks/security/secure-gateways.md +++ b/site/content/en/latest/tasks/security/secure-gateways.md @@ -41,23 +41,20 @@ Update the Gateway from the Quickstart to include an HTTPS listener that listens `example-cert` Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https", - "protocol": "HTTPS", - "port": 443, - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "example-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: example-cert + ' ``` Verify the Gateway status: @@ -68,7 +65,24 @@ kubectl get gateway/eg -o yaml ## Testing -### Clusters without External LoadBalancer Support +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} + +Get the External IP of the Gateway: + +```shell +export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') +``` + +Query the example app through the Gateway: + +```shell +curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ +--cacert example.com.crt https://www.example.com/get +``` + +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} Get the name of the Envoy service created the by the example Gateway: @@ -89,20 +103,9 @@ curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \ --cacert example.com.crt https://www.example.com:8443/get ``` -### Clusters with External LoadBalancer Support - -Get the External IP of the Gateway: - -```shell -export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') -``` - -Query the example app through the Gateway: +{{% /tab %}} +{{< /tabpane >}} -```shell -curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ ---cacert example.com.crt https://www.example.com/get -``` ## Multiple HTTPS Listeners @@ -122,34 +125,31 @@ kubectl create secret tls foo-cert --key=foo.example.com.key --cert=foo.example. Create another HTTPS listener on the example Gateway: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https-foo", - "protocol": "HTTPS", - "port": 443, - "hostname": "foo.example.com", - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "foo-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https-foo + protocol: HTTPS + port: 443 + hostname: foo.example.com + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: foo-cert + ' ``` Update the HTTPRoute to route traffic for hostname `foo.example.com` to the example backend service: ```shell -kubectl patch httproute backend --type=json --patch '[{ - "op": "add", - "path": "/spec/hostnames/-", - "value": "foo.example.com", -}]' +kubectl patch httproute backend --type=json --patch ' + - op: add + path: /spec/hostnames/- + value: foo.example.com + ' ``` Verify the Gateway status: @@ -171,9 +171,12 @@ Before proceeding, ensure you can query the HTTPS backend service from the [Test To demonstrate cross namespace certificate references, create a ReferenceGrant that allows Gateways from the "default" namespace to reference Secrets in the "envoy-gateway-system" namespace: -```console -$ cat <}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + Delete the previously created Secret: ```shell @@ -210,8 +237,11 @@ kubectl create secret tls example-cert -n envoy-gateway-system --key=www.example Update the Gateway HTTPS listener with `namespace: envoy-gateway-system`, for example: -```console -$ cat <}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + The Gateway HTTPS listener status should now surface the `Ready: True` condition and you should once again be able to query the HTTPS backend through the Gateway. @@ -242,7 +303,7 @@ Lastly, test connectivity using the above [Testing section](#testing). ## Clean-Up -Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest. +Follow the steps from the [Quickstart](../quickstart) to uninstall Envoy Gateway and the example manifest. Delete the Secrets: @@ -316,13 +377,12 @@ kubectl create secret tls example-cert-ecdsa --key=www.example.com.ecdsa.key --c Patch the Gateway with this additional ECDSA Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/1/tls/certificateRefs/-", - "value": { - "name": "example-cert-ecdsa", - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/1/tls/certificateRefs/- + value: + name: example-cert-ecdsa + ' ``` Verify the Gateway status: @@ -369,7 +429,7 @@ This sections gives a walkthrough to generate multiple certificates correspondin ## Prerequisites -Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest. +Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP. Follow the steps in the [TLS Certificates](#tls-certificates) section to generate self-signed RSA derived Server certificate and private key, and configure those in the Gateway listener configuration to terminate HTTPS traffic. @@ -393,28 +453,34 @@ Note that all occurrences of `example.com` were just replaced with `sample.com` Next we update the `Gateway` configuration to accommodate the new Certificate which will be used to Terminate TLS traffic: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/1/tls/certificateRefs/-", - "value": { - "name": "sample-cert", - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/1/tls/certificateRefs/- + value: + name: sample-cert + ' ``` Finally, we update the HTTPRoute to route traffic for hostname `www.sample.com` to the example backend service: ```shell -kubectl patch httproute backend --type=json --patch '[{ - "op": "add", - "path": "/spec/hostnames/-", - "value": "www.sample.com", -}]' +kubectl patch httproute backend --type=json --patch ' + - op: add + path: /spec/hostnames/- + value: www.sample.com + ' ``` ## Testing -### Clusters without External LoadBalancer Support +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} + +Refer to the steps mentioned earlier under [Testing in clusters with External LoadBalancer Support](#testing) + + +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} Get the name of the Envoy service created the by the example Gateway: @@ -444,12 +510,11 @@ curl -v -HHost:www.sample.com --resolve "www.sample.com:8443:127.0.0.1" \ Since the multiple certificates are configured on the same Gateway listener, Envoy was able to provide the client with appropriate certificate based on the SNI in the client request. -### Clusters with External LoadBalancer Support - -Refer to the steps mentioned earlier under [Testing in clusters with External LoadBalancer Support](#clusters-with-external-loadbalancer-support) +{{% /tab %}} +{{< /tabpane >}} ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [ReferenceGrant]: https://gateway-api.sigs.k8s.io/api-types/referencegrant/ diff --git a/site/content/en/latest/tasks/security/threat-model.md b/site/content/en/latest/tasks/security/threat-model.md index 7fd334e6143..fcf8643e184 100644 --- a/site/content/en/latest/tasks/security/threat-model.md +++ b/site/content/en/latest/tasks/security/threat-model.md @@ -528,7 +528,7 @@ When considering internal threat actors, we chose to follow the [security model] **Threat**: Threat actors establish persistence and move laterally through the cluster unnoticed. - **Recommendation**: Configure [access logging](https://gateway.envoyproxy.io/latest/contributions/design/accesslog/) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout. + **Recommendation**: Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout. Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). @@ -589,33 +589,33 @@ Set runAsUser and runAsGroup security context options to specific UIDs (e.g., ru ### Identified Threats by Priority -|ID|UID|Category|Risk|Threat|Priority| Recommendation | -|-|-|-|-|-|-|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.

| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) task shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | -|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | -|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | -|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | -|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | -|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | -|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | -|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | -|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | -|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | -|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | -|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | +|ID|UID|Category|Risk|Threat|Priority| Recommendation | +|-|-|-|-|-|-|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.

| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) task shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | +|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | +|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | +|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | +|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | +|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | +|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | +|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | +|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | +|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | +|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | +|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | |EGTM-018|EGTM-GW-006|Gateway API| There is a risk that malicious requests could lead to a Denial of Service (DoS) attack, thereby reducing API gateway availability due to misconfigurations in rate-limiting or load balancing controls, or a lack of route timeout enforcement.

| Reduced API gateway availability due to an attacker\'s maliciously crafted request (e.g., QoD) potentially inducing a Denial of Service (DoS) attack.

|Medium| To ensure high availability and to mitigate potential security threats, adhere to the Envoy Gateway documentation for the configuration of a [rate-limiting](https://gateway.envoyproxy.io/v0.6.0/user/rate-limit/) filter and load balancing.

Further, adhere to best practices for configuring Envoy Proxy as an edge proxy documented [here](https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#configuring-envoy-as-an-edge-proxy) within the EnvoyProxy docs. This involves configuring TCP and HTTP proxies with specific settings, including restricting access to the admin endpoint, setting the [overload manager](https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager#config-overload-manager) and [listener](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-per-connection-buffer-limit-bytes) / [cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-per-connection-buffer-limit-bytes) buffer limits, enabling [use_remote_address](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-use-remote-address), setting [connection and stream timeouts](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#faq-configuration-timeouts), limiting [maximum concurrent streams](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-max-concurrent-streams), setting [initial stream window size limit](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size), and configuring action on [headers_with_underscores](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-headers-with-underscores-action).

[Path normalisation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-normalize-path) should be enabled to minimise path confusion vulnerabilities. These measures help protect against volumetric threats such as Denial of Service (DoS)nattacks. Utilise custom resources to implement policy attachment, thereby exposing request limit configuration for route types. | -|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | -|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | -|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | -|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | -|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | -|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | -|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | -|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | -|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | -|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | -|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | -|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | +|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | +|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | +|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | +|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | +|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | +|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | +|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | +|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | +|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | +|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | +|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | +|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | ## Attack Trees diff --git a/site/content/en/latest/tasks/security/tls-passthrough.md b/site/content/en/latest/tasks/security/tls-passthrough.md index 874ec2aac4e..4f9665d6763 100644 --- a/site/content/en/latest/tasks/security/tls-passthrough.md +++ b/site/content/en/latest/tasks/security/tls-passthrough.md @@ -53,57 +53,62 @@ Patch the Gateway from the Quickstart to include a TLS listener that listens on TLS mode Passthrough: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "tls", - "protocol": "TLS", - "hostname": "passthrough.example.com", - "tls": {"mode": "Passthrough"}, - "port": 6443, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: tls + protocol: TLS + hostname: passthrough.example.com + port: 6443 + tls: + mode: Passthrough + ' ``` ## Testing -### Clusters without External LoadBalancer Support +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} -Get the name of the Envoy service created the by the example Gateway: +You can also test the same functionality by sending traffic to the External IP of the Gateway: ```shell -export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') +export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') ``` -Port forward to the Envoy service: +Curl the example app through the Gateway, e.g. Envoy proxy: ```shell -kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 6043:6443 & +curl -v -HHost:passthrough.example.com --resolve "passthrough.example.com:6443:${GATEWAY_HOST}" \ +--cacert example.com.crt https://passthrough.example.com:6443/get ``` -Curl the example app through Envoy proxy: +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} + +Get the name of the Envoy service created the by the example Gateway: ```shell -curl -v --resolve "passthrough.example.com:6043:127.0.0.1" https://passthrough.example.com:6043 \ ---cacert passthrough.example.com.crt +export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') ``` -### Clusters with External LoadBalancer Support - -You can also test the same functionality by sending traffic to the External IP of the Gateway: +Port forward to the Envoy service: ```shell -export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') +kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 6043:6443 & ``` -Curl the example app through the Gateway, e.g. Envoy proxy: +Curl the example app through Envoy proxy: ```shell -curl -v -HHost:passthrough.example.com --resolve "passthrough.example.com:6443:${GATEWAY_HOST}" \ ---cacert example.com.crt https://passthrough.example.com:6443/get +curl -v --resolve "passthrough.example.com:6043:127.0.0.1" https://passthrough.example.com:6043 \ +--cacert passthrough.example.com.crt ``` +{{% /tab %}} +{{< /tabpane >}} + ## Clean-Up Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest. @@ -116,4 +121,4 @@ kubectl delete secret/server-certs ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. diff --git a/site/content/en/latest/tasks/security/tls-termination.md b/site/content/en/latest/tasks/security/tls-termination.md index 77a701a443a..e4534dd57e1 100644 --- a/site/content/en/latest/tasks/security/tls-termination.md +++ b/site/content/en/latest/tasks/security/tls-termination.md @@ -49,38 +49,43 @@ kubectl get gateway/eg -o yaml ## Testing -### Clusters without External LoadBalancer Support +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} -Get the name of the Envoy service created the by the example Gateway: +Get the External IP of the Gateway: ```shell -export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') +export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') ``` -Port forward to the Envoy service: +Query the example app through the Gateway: ```shell -kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 & +curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ +--cacert example.com.crt https://www.example.com/get ``` -Query the example app through Envoy proxy: +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} + +Get the name of the Envoy service created the by the example Gateway: ```shell -curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \ ---cacert example.com.crt https://www.example.com:8443/get +export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') ``` -### Clusters with External LoadBalancer Support - -Get the External IP of the Gateway: +Port forward to the Envoy service: ```shell -export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') +kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 & ``` -Query the example app through the Gateway: +Query the example app through Envoy proxy: ```shell -curl -v -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ ---cacert example.com.crt https://www.example.com/get +curl -v -HHost:www.example.com --resolve "www.example.com:8443:127.0.0.1" \ +--cacert example.com.crt https://www.example.com:8443/get ``` + +{{% /tab %}} +{{< /tabpane >}} diff --git a/site/content/en/latest/tasks/traffic/circuit-breaker.md b/site/content/en/latest/tasks/traffic/circuit-breaker.md index cf00d926a2c..9480a86a2cd 100644 --- a/site/content/en/latest/tasks/traffic/circuit-breaker.md +++ b/site/content/en/latest/tasks/traffic/circuit-breaker.md @@ -62,6 +62,9 @@ The default circuit breaker threshold (1024) is not met. As a result, requests d In order to fail fast, apply a `BackendTrafficPolicy` that limits concurrent requests to 10 and pending requests to 0. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Execute the load simulation again. ```shell diff --git a/site/content/en/latest/tasks/traffic/client-traffic-policy.md b/site/content/en/latest/tasks/traffic/client-traffic-policy.md index 98659941f72..7132453da38 100644 --- a/site/content/en/latest/tasks/traffic/client-traffic-policy.md +++ b/site/content/en/latest/tasks/traffic/client-traffic-policy.md @@ -23,6 +23,9 @@ Before proceeding, you should be able to query the example backend using HTTP. ### Support TCP keepalive for downstream client +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify that ClientTrafficPolicy is Accepted: ```shell @@ -176,6 +205,9 @@ You can see keepalive connection marked by the output in: This example configures Proxy Protocol for downstream clients. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify that ClientTrafficPolicy is Accepted: ```shell @@ -289,6 +344,9 @@ You should now expect 200 response status and also see that source IP was preser This example configures the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address and determines whether or not `x-forwarded-proto` headers will be trusted. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for for details. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify that ClientTrafficPolicy is Accepted: ```shell @@ -415,6 +498,9 @@ Handling connection for 8888 This feature allows you to limit the take taken by the Envoy Proxy fleet to receive the entire request from the client, which is useful in preventing certain clients from consuming too much memory in Envoy This example configures the HTTP request timeout for the client, please check out the details [here](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#stream-timeouts). +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Curl the example app through Envoy proxy: ```shell diff --git a/site/content/en/latest/tasks/traffic/connection-limit.md b/site/content/en/latest/tasks/traffic/connection-limit.md index 138e620bf9b..aac8437dc45 100644 --- a/site/content/en/latest/tasks/traffic/connection-limit.md +++ b/site/content/en/latest/tasks/traffic/connection-limit.md @@ -57,6 +57,9 @@ There are no connection limits, and so all 100 requests succeed. Next, we apply a limit of 5 connections. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Execute the load simulation again. ```shell diff --git a/site/content/en/latest/tasks/traffic/fault-injection.md b/site/content/en/latest/tasks/traffic/fault-injection.md index 657b3e1453d..d4f536dbb33 100644 --- a/site/content/en/latest/tasks/traffic/fault-injection.md +++ b/site/content/en/latest/tasks/traffic/fault-injection.md @@ -26,6 +26,9 @@ Allow requests with a valid faultInjection by creating an [BackendTrafficPolicy] ### HTTPRoute +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + + +Two HTTPRoute resources were created, one for `/foo` and another for `/bar`. `fault-injection-abort` BackendTrafficPolicy has been created and targeted HTTPRoute foo to abort requests for `/foo`. `fault-injection-delay` BackendTrafficPolicy has been created and targeted HTTPRoute foo to delay `2s` requests for `/bar`. Verify the HTTPRoute configuration and status: @@ -118,6 +200,9 @@ kubectl get backendtrafficpolicy/fault-injection-delay -o yaml ### GRPCRoute +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + A BackendTrafficPolicy has been created and targeted GRPCRoute yages to abort requests for `yages` service.. Verify the GRPCRoute configuration and status: diff --git a/site/content/en/latest/tasks/traffic/gateway-address.md b/site/content/en/latest/tasks/traffic/gateway-address.md index d211d315c1a..bd87726c139 100644 --- a/site/content/en/latest/tasks/traffic/gateway-address.md +++ b/site/content/en/latest/tasks/traffic/gateway-address.md @@ -21,21 +21,22 @@ The Envoy Gateway deploys Envoy Proxy Service as `LoadBalancer` by default, so you can set the address of the Gateway directly (the address settings here are for reference only): ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/addresses", - "value": [{ - "type": "IPAddress", - "value": "1.2.3.4" - }] -}]' +kubectl patch gateway eg --type=json --patch ' +- op: add + path: /spec/addresses + value: + - type: IPAddress + value: 1.2.3.4 +' ``` Verify the Gateway status: ```shell kubectl get gateway +``` +```console NAME CLASS ADDRESS PROGRAMMED AGE eg eg 1.2.3.4 True 14m ``` @@ -44,7 +45,9 @@ Verify the Envoy Proxy Service status: ```shell kubectl get service -n envoy-gateway-system +``` +```console NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE envoy-default-eg-64656661 LoadBalancer 10.96.236.219 1.2.3.4 80:31017/TCP 15m envoy-gateway ClusterIP 10.96.192.76 18000/TCP 15m diff --git a/site/content/en/latest/tasks/traffic/gatewayapi-support.md b/site/content/en/latest/tasks/traffic/gatewayapi-support.md index 778a9972d62..7ea0e91e54b 100644 --- a/site/content/en/latest/tasks/traffic/gatewayapi-support.md +++ b/site/content/en/latest/tasks/traffic/gatewayapi-support.md @@ -94,7 +94,7 @@ these types of cross-namespace references. Envoy Gateway supports the following namespace. - Allowing a Gateway's [SecretObjectReference][] to reference a secret in a different namespace. -[system design]: ../../contributions/design/system-design/ +[system design]: ../../../contributions/design/system-design [Gateway API]: https://gateway-api.sigs.k8s.io/ [GatewayClass]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass [parameters reference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ParametersReference @@ -110,7 +110,7 @@ these types of cross-namespace references. Envoy Gateway supports the following [TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute [ReferenceGrant]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.ReferenceGrant [SecretObjectReference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.SecretObjectReference -[rate limiting]: ../../contributions/design/rate-limit +[rate limiting]: ../../../contributions/design/rate-limit [request authentication]: ../security/jwt-authentication [EnvoyProxy]: ../../../api/extension_types#envoyproxy [resolving conflicts]: https://gateway-api.sigs.k8s.io/concepts/guidelines/?h=conflict#conflicts diff --git a/site/content/en/latest/tasks/traffic/global-rate-limit.md b/site/content/en/latest/tasks/traffic/global-rate-limit.md index a0734928bd7..3f1bfa4f301 100644 --- a/site/content/en/latest/tasks/traffic/global-rate-limit.md +++ b/site/content/en/latest/tasks/traffic/global-rate-limit.md @@ -35,6 +35,9 @@ Before proceeding, you should be able to query the example backend using HTTP. * The global rate limit feature is based on [Envoy Ratelimit][] which requires a Redis instance as its caching layer. Lets install a Redis deployment in the `redis-system` namespce. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### Enable Global Rate limit in Envoy Gateway * The default installation of Envoy Gateway installs a default [EnvoyGateway][] configuration and attaches it using a `ConfigMap`. In the next step, we will update this resource to enable rate limit in Envoy Gateway as well as configure the URL for the Redis instance used for Global rate limiting. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell cat <}} + * After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in ```shell kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system ``` - ## Rate Limit Specific User Here is an example of a rate limit implemented by the application developer to limit a specific user by matching on a custom `x-user-id` header with a value set to `one`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### HTTPRoute +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -286,6 +446,9 @@ Here is an example of a rate limit implemented by the application developer to l value in the `x-user-id` header. Here, user `one` (recognised from the traffic flow using the header `x-user-id` and value `one`) will be rate limited at 3 requests/hour and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`). +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### HTTPRoute +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Lets run the same command again with the header `x-user-id` and value `one` set in the request. We should the first 3 requests succeeding and the 4th request being rate limited. @@ -421,6 +649,9 @@ transfer-encoding: chunked This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### HTTPRoute +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ```shell for i in {1..4}; do curl -I --header "Host: ratelimit.example" http://${GATEWAY_HOST}/get ; sleep 1; done ``` @@ -511,9 +803,12 @@ transfer-encoding: chunked Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on their IP address (also reflected in the `X-Forwarded-For` header). -Note: EG supports two kinds of rate limit for the IP address: exact and distinct. -* exact means that all IP addresses within the specified Source IP CIDR share the same rate limit bucket. -* distinct means that each IP address within the specified Source IP CIDR has its own rate limit bucket. +Note: EG supports two kinds of rate limit for the IP address: Exact and Distinct. +* Exact means that all IP addresses within the specified Source IP CIDR share the same rate limit bucket. +* Distinct means that each IP address within the specified Source IP CIDR has its own rate limit bucket. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell cat <}} + ```shell for i in {1..4}; do curl -I --header "Host: ratelimit.example" http://${GATEWAY_HOST}/get ; sleep 1; done ``` @@ -602,6 +949,9 @@ transfer-encoding: chunked Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on the value of the Jwt claims carried. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Get the JWT used for testing request authentication: ```shell @@ -767,6 +1187,9 @@ like container `image`, `securityContext`, `env` and pod `annotations` and `secu * `tls.certificateRef` set the client certificate for redis server TLS connections. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + * After updating the `ConfigMap`, you will need to restart the `envoy-gateway` deployment so the configuration kicks in ```shell diff --git a/site/content/en/latest/tasks/traffic/grpc-routing.md b/site/content/en/latest/tasks/traffic/grpc-routing.md index 4c27ef993cc..7c41b54c885 100644 --- a/site/content/en/latest/tasks/traffic/grpc-routing.md +++ b/site/content/en/latest/tasks/traffic/grpc-routing.md @@ -95,6 +95,9 @@ It supports two match types: `Exact` and `RegularExpression`. The following example shows how to match a request based on the service and method names for `grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo`, as well as a match for all services with a method name `Ping` which matches `yages.Echo/Ping` in our deployment. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the GRPCRoute status: ```shell @@ -142,6 +180,9 @@ The following example shows how to match a request based on the service and meth with match type `RegularExpression`. It matches all the services and methods with pattern `/.*.Echo/Pin.+`, which matches `yages.Echo/Ping` in our deployment. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the GRPCRoute status: ```shell diff --git a/site/content/en/latest/tasks/traffic/http-redirect.md b/site/content/en/latest/tasks/traffic/http-redirect.md index 8639c2c9d7c..2a41777f80b 100644 --- a/site/content/en/latest/tasks/traffic/http-redirect.md +++ b/site/content/en/latest/tasks/traffic/http-redirect.md @@ -19,6 +19,9 @@ Redirects return HTTP 3XX responses to a client, instructing it to retrieve a di For example, to issue a permanent redirect (301) from HTTP to HTTPS, configure `requestRedirect.statusCode=301` and `requestRedirect.scheme="https"`: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + __Note:__ `301` (default) and `302` are the only supported statusCodes. The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. @@ -104,8 +135,11 @@ kubectl create secret tls example-com --key=tls.key --cert=tls.crt Define a https listener on the existing gateway +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell -cat <}} + Check for any TLS certificate issues on the gateway. ```bash @@ -137,9 +202,11 @@ kubectl -n default describe gateway eg Create two HTTPRoutes and attach them to the HTTP and HTTPS listeners using the [sectionName][] field. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell -cat <}} + Curl the example app through http listener: ```bash @@ -200,6 +316,9 @@ curl -v -H 'Host:www.example.com' --resolve "www.example.com:443:$GATEWAY_HOST" Path redirects use an HTTP Path Modifier to replace either entire paths or path prefixes. For example, the HTTPRoute below will issue a 302 redirect to all `path.redirect.example` requests whose path begins with `/get` to `/status/200`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell diff --git a/site/content/en/latest/tasks/traffic/http-request-headers.md b/site/content/en/latest/tasks/traffic/http-request-headers.md index 05cb770c4a7..7bc709c49c6 100644 --- a/site/content/en/latest/tasks/traffic/http-request-headers.md +++ b/site/content/en/latest/tasks/traffic/http-request-headers.md @@ -24,6 +24,9 @@ does not have the header configured by the filter, then that header will be adde has the header configured by the filter, then the value of the header in the filter will be appended to the value of the header in the request. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -107,6 +148,9 @@ will be added, but unlike [adding request headers](#adding-request-headers) whic the request already contains it, setting a header will cause the value to be replaced by the value configured in the filter. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Querying `headers.example/get` should result in a `200` response from the example Gateway and the output from the example app should indicate that the upstream example app received the header `add-header` with the original value `something` replaced by `foo`. @@ -178,6 +259,9 @@ will be added, but unlike [adding request headers](#adding-request-headers) whic the request already contains it, setting a header will cause the value to be replaced by the value configured in the filter. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Querying `headers.example/get` should result in a `200` response from the example Gateway and the output from the example app should indicate that the upstream example app received the header `add-header`, but the header `remove-header` that was sent by curl was removed before the upstream received the request. @@ -243,6 +362,9 @@ $ curl -vvv --header "Host: headers.example" "http://${GATEWAY_HOST}/get" --head Headers can be added/set/removed in a single filter on the same HTTPRoute and they will all perform as expected +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/ [HTTPRoute filters]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter [Gateway API documentation]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/latest/tasks/traffic/http-request-mirroring.md b/site/content/en/latest/tasks/traffic/http-request-mirroring.md index e5caa3fdc89..f22ef51da36 100644 --- a/site/content/en/latest/tasks/traffic/http-request-mirroring.md +++ b/site/content/en/latest/tasks/traffic/http-request-mirroring.md @@ -16,8 +16,11 @@ Before proceeding, you should be able to query the example backend using HTTP. Next, create a new `Deployment` and `Service` to mirror requests to. The following example will use a second instance of the application deployed in the quickstart. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell -kubectl apply -f - <}} Then create an `HTTPRoute` that uses a `HTTPRequestMirrorFilter` to send requests to the original service from the quickstart, and mirror request to the service that was just deployed. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell -kubectl apply -f - <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -142,6 +247,7 @@ $ curl -v --header "Host: backends.example" "http://${GATEWAY_HOST}/get" < server: envoy < ... + "namespace": "default", "ingress": "", "service": "", @@ -164,6 +270,9 @@ Echoing back request made to /get to client (10.42.0.10:45096) When an `HTTPRoute` has multiple `backendRefs` and an `HTTPRequestMirrorFilter`, traffic splitting will still behave the same as it normally would for the main `backendRefs` while the `backendRef` of the `HTTPRequestMirrorFilter` will continue receiving mirrored copies of the incoming requests. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Multiple HTTPRequestMirrorFilters Multiple `HTTPRequestMirrorFilters` are not supported on the same `HTTPRoute` `rule`. When attempting to do so, the admission webhook will reject the configuration. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ```console Error from server: error when creating "STDIN": admission webhook "validate.gateway.networking.k8s.io" denied the request: spec.rules[0].filters: Invalid value: "RequestMirror": cannot be used multiple times in the same rule ``` diff --git a/site/content/en/latest/tasks/traffic/http-response-headers.md b/site/content/en/latest/tasks/traffic/http-response-headers.md index 8e13f146493..60121674b00 100644 --- a/site/content/en/latest/tasks/traffic/http-response-headers.md +++ b/site/content/en/latest/tasks/traffic/http-response-headers.md @@ -22,6 +22,9 @@ does not have the header configured by the filter, then that header will be adde already has the header configured by the filter, then the value of the header in the filter will be appended to the value of the header in the response. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -105,6 +145,9 @@ will be added, but unlike [adding response headers](#adding-response-headers) wh if the response already contains it, setting a header will cause the value to be replaced by the value configured in the filter. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Querying `headers.example/get` should result in a `200` response from the example Gateway and the output from the example app should indicate that the downstream client received the header `set-header` with the original value `value1` replaced by `foo`. @@ -177,6 +257,9 @@ will be added, but unlike [adding response headers](#adding-response-headers) wh if the response already contains it, setting a header will cause the value to be replaced by the value configured in the filter. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Querying `headers.example/get` should result in a `200` response from the example Gateway and the output from the example app should indicate that the header `remove-header` that was sent by curl was removed before the upstream received the response. @@ -242,6 +360,9 @@ $ curl -vvv --header "Host: headers.example" "http://${GATEWAY_HOST}/get" -H 'X- Headers can be added/set/removed in a single filter on the same HTTPRoute and they will all perform as expected +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/ [Gateway API documentation]: https://gateway-api.sigs.k8s.io/ [req_filter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPHeaderFilter diff --git a/site/content/en/latest/tasks/traffic/http-routing.md b/site/content/en/latest/tasks/traffic/http-routing.md index bf1a7596637..aba57adc9b2 100644 --- a/site/content/en/latest/tasks/traffic/http-routing.md +++ b/site/content/en/latest/tasks/traffic/http-routing.md @@ -131,6 +131,9 @@ For this feature to work please make sure * you have a fallback route rule defined, the backend for this route rule can be invalid. * The SecurityPolicy is applied to both the fallback route as well as the route with the claim header matches, to avoid spoofing. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Get the JWT used for testing request authentication: ```shell @@ -204,7 +277,7 @@ TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/ Test routing to the `foo-svc` backend by specifying a JWT Token with a claim `name: John Doe`. ```shell -curl -sS -H "Authorization: Bearer $TOKEN" "http://${GATEWAY_HOST}/" | jq .pod +curl -sS -H "Host: foo.example.com" -H "Authorization: Bearer $TOKEN" "http://${GATEWAY_HOST}/login" | jq .pod "foo-backend-6df8cc6b9f-fmwcg" ``` @@ -217,7 +290,7 @@ TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/ Test HTTP routing to the `bar-svc` backend by specifying a JWT Token with a claim `name: Tom`. ```shell -curl -sS -H "Authorization: Bearer $TOKEN" "http://${GATEWAY_HOST}/" | jq .pod +curl -sS -H "Host: bar.example.com" -H "Authorization: Bearer $TOKEN" "http://${GATEWAY_HOST}/" | jq .pod "bar-backend-6688b8944c-s8htr" ``` diff --git a/site/content/en/latest/tasks/traffic/http-timeouts.md b/site/content/en/latest/tasks/traffic/http-timeouts.md index 01e166fe87e..3ab863608ce 100644 --- a/site/content/en/latest/tasks/traffic/http-timeouts.md +++ b/site/content/en/latest/tasks/traffic/http-timeouts.md @@ -22,6 +22,9 @@ backend has the ability to delay responses; we use it as the backend to control ### request timeout We configure the backend to delay responses by 3 seconds, then we set the request timeout to 4 seconds. Envoy Gateway will successfully respond to the request. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ```shell curl --header "Host: timeout.example.com" http://${GATEWAY_HOST}/?delay=3s -I ``` @@ -65,6 +103,9 @@ content-length: 480 Then we set the request timeout to 2 seconds. In this case, Envoy Gateway will respond with a timeout. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ```shell curl --header "Host: timeout.example.com" http://${GATEWAY_HOST}/?delay=3s -v ``` diff --git a/site/content/en/latest/tasks/traffic/http-traffic-splitting.md b/site/content/en/latest/tasks/traffic/http-traffic-splitting.md index 924d36970e9..06e4a236589 100644 --- a/site/content/en/latest/tasks/traffic/http-traffic-splitting.md +++ b/site/content/en/latest/tasks/traffic/http-traffic-splitting.md @@ -15,6 +15,9 @@ Before proceeding, you should be able to query the example backend using HTTP. When a single backendRef is configured in a HTTPRoute, it will receive 100% of the traffic. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -87,6 +120,9 @@ configured. First, create a second instance of the example app from the quickstart: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Then create an HTTPRoute that uses both the app from the quickstart and the second instance that was just created +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Querying `backends.example/get` should result in `200` responses from the example Gateway and the output from the example app that indicates which pod handled the request should switch between the first pod and the second one from the new deployment on subsequent requests. @@ -217,6 +353,9 @@ HTTPRoute. The weight is not a percentage and the sum of all weights does not ne The HTTPRoute below will configure the gateway to send 80% of the traffic to the backend service, and 20% to the backend-2 service. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Invalid backendRefs backendRefs can be considered invalid for the following reasons: @@ -263,6 +438,9 @@ Modifying the above example to make the backend-2 backendRef invalid by using a will result in 80% of the traffic being sent to the backend service, and 20% of the traffic receiving an HTTP response with status code `500`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Querying `backends.example/get` should result in `200` responses 80% of the time, and `500` responses 20% of the time. ```console diff --git a/site/content/en/latest/tasks/traffic/http-urlrewrite.md b/site/content/en/latest/tasks/traffic/http-urlrewrite.md index 5acca036714..0ebb7595c22 100644 --- a/site/content/en/latest/tasks/traffic/http-urlrewrite.md +++ b/site/content/en/latest/tasks/traffic/http-urlrewrite.md @@ -15,6 +15,9 @@ Before proceeding, you should be able to query the example backend using HTTP. You can configure to rewrite the prefix in the url like below. In this example, any curls to `http://${GATEWAY_HOST}/get/xxx` will be rewritten to `http://${GATEWAY_HOST}/replace/xxx`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -114,6 +150,9 @@ You can configure to rewrite the fullpath in the url like below. In this example `http://${GATEWAY_HOST}/get/origin/path/xxxx` will be rewritten to `http://${GATEWAY_HOST}/force/replace/fullpath`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -208,6 +281,9 @@ You can see that the `X-Envoy-Original-Path` is `/get/origin/path/extra`, but th You can configure to rewrite the hostname like below. In this example, any requests sent to `http://${GATEWAY_HOST}/get` with `--header "Host: path.rewrite.example"` will rewrite host into `envoygateway.io`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell diff --git a/site/content/en/latest/tasks/traffic/http3.md b/site/content/en/latest/tasks/traffic/http3.md index 3b83bc7def5..af95ab8ba57 100644 --- a/site/content/en/latest/tasks/traffic/http3.md +++ b/site/content/en/latest/tasks/traffic/http3.md @@ -41,29 +41,29 @@ Update the Gateway from the Quickstart to include an HTTPS listener that listens `example-cert` Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https", - "protocol": "HTTPS", - "port": 443, - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "example-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: example-cert + ' ``` Apply the following ClientTrafficPolicy to enable HTTP3 +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell -kubectl apply -f - <}} + Verify the Gateway status: ```shell @@ -86,13 +108,8 @@ kubectl get gateway/eg -o yaml ## Testing -### Clusters without External LoadBalancer Support - -It is not possible at the moment to port-forward UDP protocol in kubernetes service -check out https://github.com/kubernetes/kubernetes/issues/47862. -Hence we need external loadbalancer to test this feature out. - -### Clusters with External LoadBalancer Support +{{< tabpane text=true >}} +{{% tab header="With External LoadBalancer Support" %}} Get the External IP of the Gateway: @@ -102,8 +119,18 @@ export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0]. Query the example app through the Gateway: -Below example uses a custom docker image with custom curl binary with built-in http3. +The below example uses a custom docker image with custom `curl` binary with built-in http3. ```shell docker run --net=host --rm ghcr.io/macbre/curl-http3 curl -kv --http3 -HHost:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" https://www.example.com/get ``` + +{{% /tab %}} +{{% tab header="Without LoadBalancer Support" %}} + +It is not possible at the moment to port-forward UDP protocol in kubernetes service +check out https://github.com/kubernetes/kubernetes/issues/47862. +Hence we need external loadbalancer to test this feature out. + +{{% /tab %}} +{{< /tabpane >}} diff --git a/site/content/en/latest/tasks/traffic/local-rate-limit.md b/site/content/en/latest/tasks/traffic/local-rate-limit.md index 067756b3109..37fb5590a44 100644 --- a/site/content/en/latest/tasks/traffic/local-rate-limit.md +++ b/site/content/en/latest/tasks/traffic/local-rate-limit.md @@ -36,6 +36,9 @@ Before proceeding, you should be able to query the example backend using HTTP. Here is an example of a rate limit implemented by the application developer to limit a specific user by matching on a custom `x-user-id` header with a value set to `one`. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### HTTPRoute +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway. ```shell @@ -186,6 +254,9 @@ server: envoy This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ### HTTPRoute +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ```shell for i in {1..4}; do curl -I --header "Host: ratelimit.example" http://${GATEWAY_HOST}/get ; sleep 1; done ``` diff --git a/site/content/en/latest/tasks/traffic/retry.md b/site/content/en/latest/tasks/traffic/retry.md index cde27f5c2bf..4de8f604f96 100644 --- a/site/content/en/latest/tasks/traffic/retry.md +++ b/site/content/en/latest/tasks/traffic/retry.md @@ -46,6 +46,9 @@ Let's create a `BackendTrafficPolicy` with a retry setting. The request will be retried 5 times with a 100ms base interval and a 10s maximum interval. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Execute the test again. ```shell diff --git a/site/content/en/latest/tasks/traffic/routing-outside-kubernetes.md b/site/content/en/latest/tasks/traffic/routing-outside-kubernetes.md index 95b91eaa0e1..7720d899954 100644 --- a/site/content/en/latest/tasks/traffic/routing-outside-kubernetes.md +++ b/site/content/en/latest/tasks/traffic/routing-outside-kubernetes.md @@ -3,7 +3,7 @@ title: "Routing outside Kubernetes" --- Routing to endpoints outside the Kubernetes cluster where Envoy Gateway and its corresponding Envoy Proxy fleet is -running is a common use. This can be achieved by defining FQDN addresses in a [EndpointSlice][]. +running is a common use case. This can be achieved by defining FQDN addresses in a [EndpointSlice][]. ## Installation @@ -12,7 +12,10 @@ Before proceeding, you should be able to query the example backend using HTTP. ## Configuration -* Lets define a Service and EndpointSlice that represents https://httpbin.org +Define a Service and EndpointSlice that represents https://httpbin.org + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell cat <}} + +Update the [Gateway][] to include a TLS Listener on port 443 ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "tls", - "protocol": "TLS", - "port": 443, - "tls": { - "mode": "Passthrough", - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: tls + protocol: TLS + port: 443 + tls: + mode: Passthrough + ' ``` -* Lets add a [TLSRoute][] that can route incoming traffic to the above backend that we created +Add a [TLSRoute][] that can route incoming traffic to the above backend that we created + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell cat <}} + +Get the Gateway address: ```shell export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}') ``` - -Lets send a request and view the response +Send a request and view the response: ```shell -curl -I -HHost:httpbin.org --resolve "httpbin.org:443:${GATEWAY_HOST}" https://httpbin.org:443 +curl -I -HHost:httpbin.org --resolve "httpbin.org:443:${GATEWAY_HOST}" https://httpbin.org/ ``` [EndpointSlice]: https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/ diff --git a/site/content/en/latest/tasks/traffic/tcp-routing.md b/site/content/en/latest/tasks/traffic/tcp-routing.md index 4eea863f5f8..d36f145e266 100644 --- a/site/content/en/latest/tasks/traffic/tcp-routing.md +++ b/site/content/en/latest/tasks/traffic/tcp-routing.md @@ -23,6 +23,9 @@ TCPRoutes, note that the protocol set for the listeners on the Gateway is TCP: Install the GatewayClass and a `tcp-gateway` Gateway first. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + +Install two services `foo` and `bar`, which are bound to `backend-1` and `backend-2`. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} ```shell cat <}} + Install two TCPRoutes `tcp-app-1` and `tcp-app-2` with different `sectionName`: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + In the above example we separate the traffic for the two separate backend TCP Services by using the sectionName field in the parentRefs: diff --git a/site/content/en/latest/tasks/traffic/udp-routing.md b/site/content/en/latest/tasks/traffic/udp-routing.md index c703abe804f..b9d8e379282 100644 --- a/site/content/en/latest/tasks/traffic/udp-routing.md +++ b/site/content/en/latest/tasks/traffic/udp-routing.md @@ -33,20 +33,17 @@ kubectl wait --timeout=5m deployment/coredns --for=condition=Available Update the Gateway from the Quickstart to include a UDP listener that listens on UDP port `5300`: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "coredns", - "protocol": "UDP", - "port": 5300, - "allowedRoutes": { - "kinds": [{ - "kind": "UDPRoute" - }] - } - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: coredns + protocol: UDP + port: 5300 + allowedRoutes: + kinds: + - kind: UDPRoute + ' ``` Verify the Gateway status: @@ -59,6 +56,9 @@ kubectl get gateway/eg -o yaml Create a UDPRoute resource to route UDP traffic received on Gateway port 5300 to the CoredDNS backend. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the UDPRoute status: ```shell @@ -141,7 +164,7 @@ kubectl delete udproute/coredns ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. [UDPRoute]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.UDPRoute [UDP proxy documentation]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/udp_filters/udp_proxy diff --git a/site/content/en/v0.5.0/install/install-helm.md b/site/content/en/v0.5.0/install/install-helm.md index ad6f945bddb..44e84aaa9df 100644 --- a/site/content/en/v0.5.0/install/install-helm.md +++ b/site/content/en/v0.5.0/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](/contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/v0.6.0/install/install-helm.md b/site/content/en/v0.6.0/install/install-helm.md index 3f3c57e1db9..7bb4b63952b 100644 --- a/site/content/en/v0.6.0/install/install-helm.md +++ b/site/content/en/v0.6.0/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](/contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/v0.6.0/install/install-yaml.md b/site/content/en/v0.6.0/install/install-yaml.md index 4b13529f000..0b617d34be6 100644 --- a/site/content/en/v0.6.0/install/install-yaml.md +++ b/site/content/en/v0.6.0/install/install-yaml.md @@ -25,7 +25,7 @@ Refer to the [Version Compatibility Matrix](/blog/2022/10/01/versions/) to learn Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](/contributions/develop) to learn more. {{% /alert %}} 1. In your terminal, run the following command: diff --git a/site/content/en/v1.0.1/_index.md b/site/content/en/v1.0.1/_index.md index 567b43bfe36..ea08d244d31 100644 --- a/site/content/en/v1.0.1/_index.md +++ b/site/content/en/v1.0.1/_index.md @@ -9,7 +9,7 @@ type = "docs" {{% alert title="Note" color="primary" %}} -This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](contributions/)! +This project is under **active** development. Many features are not complete. We would love for you to [Get Involved](/contributions)! {{% /alert %}} diff --git a/site/content/en/v1.0.1/contributions/CODEOWNERS.md b/site/content/en/v1.0.1/contributions/CODEOWNERS.md deleted file mode 100644 index aeec0b7439b..00000000000 --- a/site/content/en/v1.0.1/contributions/CODEOWNERS.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: "Maintainers" -description: "This section includes Maintainers of Envoy Gateway." ---- - -## The following maintainers, listed in alphabetical order, own everything - -- @AliceProxy -- @arkodg -- @qicz -- @Xunzhuo -- @zirain -- @zhaohuabing - -## Emeritus Maintainers - -- @alexgervais -- @danehans -- @LukeShu -- @skriss -- @youngnick diff --git a/site/content/en/v1.0.1/contributions/CODE_OF_CONDUCT.md b/site/content/en/v1.0.1/contributions/CODE_OF_CONDUCT.md deleted file mode 100644 index e19da050dff..00000000000 --- a/site/content/en/v1.0.1/contributions/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Code of Conduct" -description: "This section includes Code of Conduct of Envoy Gateway." ---- - -Envoy Gateway follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/site/content/en/v1.0.1/contributions/CONTRIBUTING.md b/site/content/en/v1.0.1/contributions/CONTRIBUTING.md deleted file mode 100644 index 6964a31e9fe..00000000000 --- a/site/content/en/v1.0.1/contributions/CONTRIBUTING.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: "Contributing" -description: "This section tells how to contribute to Envoy Gateway." -weight: 3 ---- - -We welcome contributions from the community. Please carefully review the [project goals](/about) -and following guidelines to streamline your contributions. - -## Communication - -* Before starting work on a major feature, please contact us via GitHub or Slack. We will ensure no - one else is working on it and ask you to open a GitHub issue. -* A "major feature" is defined as any change that is > 100 LOC altered (not including tests), or - changes any user-facing behavior. We will use the GitHub issue to discuss the feature and come to - agreement. This is to prevent your time being wasted, as well as ours. The GitHub review process - for major features is also important so that [affiliations with commit access](./codeowners) can - come to agreement on the design. If it's appropriate to write a design document, the document must - be hosted either in the GitHub issue, or linked to from the issue and hosted in a world-readable - location. -* Small patches and bug fixes don't need prior communication. - -## Inclusivity - -The Envoy Gateway community has an explicit goal to be inclusive to all. As such, all PRs must adhere -to the following guidelines for all code, APIs, and documentation: - -* The following words and phrases are not allowed: - * *Whitelist*: use allowlist instead. - * *Blacklist*: use denylist or blocklist instead. - * *Master*: use primary instead. - * *Slave*: use secondary or replica instead. -* Documentation should be written in an inclusive style. The [Google developer - documentation](https://developers.google.com/style/inclusive-documentation) contains an excellent - reference on this topic. -* The above policy is not considered definitive and may be amended in the future as industry best - practices evolve. Additional comments on this topic may be provided by maintainers during code - review. - -## Submitting a PR - -* Fork the repo. -* Hack -* DCO sign-off each commit. This can be done with `git commit -s`. -* Submit your PR. -* Tests will automatically run for you. -* We will **not** merge any PR that is not passing tests. -* PRs are expected to have 100% test coverage for added code. This can be verified with a coverage - build. If your PR cannot have 100% coverage for some reason please clearly explain why when you - open it. -* Any PR that changes user-facing behavior **must** have associated documentation in the [docs](https://github.com/envoyproxy/gateway/tree/main/site) folder of the repo as - well as the [changelog](../releases). -* All code comments and documentation are expected to have proper English grammar and punctuation. - If you are not a fluent English speaker (or a bad writer ;-)) please let us know and we will try - to find some help but there are no guarantees. -* Your PR title should be descriptive, and generally start with type that contains a subsystem name with `()` if necessary - and summary followed by a colon. format `chore/docs/feat/fix/refactor/style/test: summary`. - Examples: - * "docs: fix grammar error" - * "feat(translator): add new feature" - * "fix: fix xx bug" - * "chore: change ci & build tools etc" -* Your PR commit message will be used as the commit message when your PR is merged. You should - update this field if your PR diverges during review. -* Your PR description should have details on what the PR does. If it fixes an existing issue it - should end with "Fixes #XXX". -* If your PR is co-authored or based on an earlier PR from another contributor, - please attribute them with `Co-authored-by: name `. See - GitHub's [multiple author - guidance](https://help.github.com/en/github/committing-changes-to-your-project/creating-a-commit-with-multiple-authors) - for further details. -* When all tests are passing and all other conditions described herein are satisfied, a maintainer - will be assigned to review and merge the PR. -* Once you submit a PR, *please do not rebase it*. It's much easier to review if subsequent commits - are new commits and/or merges. We squash and merge so the number of commits you have in the PR - doesn't matter. -* We expect that once a PR is opened, it will be actively worked on until it is merged or closed. - We reserve the right to close PRs that are not making progress. This is generally defined as no - changes for 7 days. Obviously PRs that are closed due to lack of activity can be reopened later. - Closing stale PRs helps us to keep on top of all the work currently in flight. - -## Maintainer PR Review Policy - -* See [CODEOWNERS.md](../codeowners) for the current list of maintainers. -* A maintainer representing a different affiliation from the PR owner is required to review and - approve the PR. -* When the project matures, it is expected that a "domain expert" for the code the PR touches should - review the PR. This person does not require commit access, just domain knowledge. -* The above rules may be waived for PRs which only update docs or comments, or trivial changes to - tests and tools (where trivial is decided by the maintainer in question). -* If there is a question on who should review a PR please discuss in Slack. -* Anyone is welcome to review any PR that they want, whether they are a maintainer or not. -* Please make sure that the PR title, commit message, and description are updated if the PR changes - significantly during review. -* Please **clean up the title and body** before merging. By default, GitHub fills the squash merge - title with the original title, and the commit body with every individual commit from the PR. - The maintainer doing the merge should make sure the title follows the guidelines above and should - overwrite the body with the original commit message from the PR (cleaning it up if necessary) - while preserving the PR author's final DCO sign-off. - -## Decision making - -This is a new and complex project, and we need to make a lot of decisions very quickly. -To this end, we've settled on this process for making (possibly contentious) decisions: - -* For decisions that need a record, we create an issue. -* In that issue, we discuss opinions, then a maintainer can call for a vote in a comment. -* Maintainers can cast binding votes on that comment by reacting or replying in another comment. -* Non-maintainer community members are welcome to cast non-binding votes by either of these methods. -* Voting will be resolved by simple majority. -* In the event of deadlocks, the question will be put to steering instead. - -## DCO: Sign your work - -The sign-off is a simple line at the end of the explanation for the -patch, which certifies that you wrote it or otherwise have the right to -pass it on as an open-source patch. The rules are pretty simple: if you -can certify the below (from -[developercertificate.org](https://developercertificate.org/)): - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -660 York Street, Suite 102, -San Francisco, CA 94110 USA - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -then you just add a line to every git commit message: - - Signed-off-by: Joe Smith - -using your real name (sorry, no pseudonyms or anonymous contributions.) - -You can add the sign-off when creating the git commit via `git commit -s`. - -If you want this to be automatic you can set up some aliases: - -```bash -git config --add alias.amend "commit -s --amend" -git config --add alias.c "commit -s" -``` - -## Fixing DCO - -If your PR fails the DCO check, it's necessary to fix the entire commit history in the PR. Best -practice is to [squash](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) -the commit history to a single commit, append the DCO sign-off as described above, and [force -push](https://git-scm.com/docs/git-push#git-push---force). For example, if you have 2 commits in -your history: - -```bash -git rebase -i HEAD^^ -(interactive squash + DCO append) -git push origin -f -``` - -Note, that in general rewriting history in this way is a hindrance to the review process and this -should only be done to correct a DCO mistake. diff --git a/site/content/en/v1.0.1/contributions/DEVELOP.md b/site/content/en/v1.0.1/contributions/DEVELOP.md deleted file mode 100644 index a73fae4e7ba..00000000000 --- a/site/content/en/v1.0.1/contributions/DEVELOP.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: "Developer Guide" -description: "This section tells how to develop Envoy Gateway." -weight: 2 ---- - -Envoy Gateway is built using a [make][]-based build system. Our CI is based on [Github Actions][] using [workflows][]. - -## Prerequisites - -### go - -* Version: 1.20 -* Installation Guide: https://go.dev/doc/install - -### make - -* Recommended Version: 4.0 or later -* Installation Guide: https://www.gnu.org/software/make - -### docker - -* Optional when you want to build a Docker image or run `make` inside Docker. -* Recommended Version: 20.10.16 -* Installation Guide: https://docs.docker.com/engine/install - -### python3 - -* Need a `python3` program -* Must have a functioning `venv` module; this is part of the standard - library, but some distributions (such as Debian and Ubuntu) replace - it with a stub and require you to install a `python3-venv` package - separately. - -## Quickstart - -* Run `make help` to see all the available targets to build, test and run Envoy Gateway. - -### Building - -* Run `make build` to build all the binaries. -* Run `make build BINS="envoy-gateway"` to build the Envoy Gateway binary. -* Run `make build BINS="egctl"` to build the egctl binary. - -__Note:__ The binaries get generated in the `bin/$OS/$ARCH` directory, for example, `bin/linux/amd64/`. - -### Testing - -* Run `make test` to run the golang tests. - -* Run `make testdata` to generate the golden YAML testdata files. - -### Running Linters - -* Run `make lint` to make sure your code passes all the linter checks. -__Note:__ The `golangci-lint` configuration resides [here](https://github.com/envoyproxy/gateway/blob/main/tools/linter/golangci-lint/.golangci.yml). - -### Building and Pushing the Image - -* Run `IMAGE=docker.io/you/gateway-dev make image` to build the docker image. -* Run `IMAGE=docker.io/you/gateway-dev make push-multiarch` to build and push the multi-arch docker image. - -__Note:__ Replace `IMAGE` with your registry's image name. - -### Deploying Envoy Gateway for Test/Dev - -* Run `make create-cluster` to create a [Kind][] cluster. - -#### Option 1: Use the Latest [gateway-dev][] Image - -* Run `TAG=latest make kube-deploy` to deploy Envoy Gateway in the Kind cluster using the latest image. Replace `latest` - to use a different image tag. - -#### Option 2: Use a Custom Image - -* Run `make kube-install-image` to build an image from the tip of your current branch and load it in the Kind cluster. -* Run `IMAGE_PULL_POLICY=IfNotPresent make kube-deploy` to install Envoy Gateway into the Kind cluster using your custom image. - -### Deploying Envoy Gateway in Kubernetes - -* Run `TAG=latest make kube-deploy` to deploy Envoy Gateway using the latest image into a Kubernetes cluster (linked to - the current kube context). Preface the command with `IMAGE` or replace `TAG` to use a different Envoy Gateway image or - tag. -* Run `make kube-undeploy` to uninstall Envoy Gateway from the cluster. - -__Note:__ Envoy Gateway is tested against Kubernetes v1.24.0. - -### Demo Setup - -* Run `make kube-demo` to deploy a demo backend service, gatewayclass, gateway and httproute resource -(similar to steps outlined in the [Quickstart][] docs) and test the configuration. -* Run `make kube-demo-undeploy` to delete the resources created by the `make kube-demo` command. - -### Run Gateway API Conformance Tests - -The commands below deploy Envoy Gateway to a Kubernetes cluster and run the Gateway API conformance tests. Refer to the -Gateway API [conformance homepage][] to learn more about the tests. If Envoy Gateway is already installed, run -`TAG=latest make run-conformance` to run the conformance tests. - -#### On a Linux Host - -* Run `TAG=latest make conformance` to create a Kind cluster, install Envoy Gateway using the latest [gateway-dev][] - image, and run Gateway API conformance tests. - -#### On a Mac Host - -Since Mac doesn't support [directly exposing][] the Docker network to the Mac host, use one of the following -workarounds to run conformance tests: - -* Deploy your own Kubernetes cluster or use Docker Desktop with [Kubernetes support][] and then run - `TAG=latest make kube-deploy run-conformance`. This will install Envoy Gateway using the latest [gateway-dev][] image - to the Kubernetes cluster using the current kubectl context and run the conformance tests. Use `make kube-undeploy` to - uninstall Envoy Gateway. -* Install and run [Docker Mac Net Connect][mac_connect] and then run `TAG=latest make conformance`. - -__Note:__ Preface commands with `IMAGE` or replace `TAG` to use a different Envoy Gateway image or tag. If `TAG` -is unspecified, the short SHA of your current branch is used. - -### Debugging the Envoy Config - -An easy way to view the envoy config that Envoy Gateway is using is to port-forward to the admin interface port -(currently `19000`) on the Envoy deployment that corresponds to a Gateway so that it can be accessed locally. - -Get the name of the Envoy deployment. The following example is for Gateway `eg` in the `default` namespace: - -```shell -export ENVOY_DEPLOYMENT=$(kubectl get deploy -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') -``` - -Port forward the admin interface port: - -```shell -kubectl port-forward deploy/${ENVOY_DEPLOYMENT} -n envoy-gateway-system 19000:19000 -``` - -Now you are able to view the running Envoy configuration by navigating to `127.0.0.1:19000/config_dump`. - -There are many other endpoints on the [Envoy admin interface][] that may be helpful when debugging. - -### JWT Testing - -An example [JSON Web Token (JWT)][jwt] and [JSON Web Key Set (JWKS)][jwks] are used for the [request authentication][] -user guide. The JWT was created by the [JWT Debugger][], using the `RS256` algorithm. The public key from the JWTs -verify signature was copied to [JWK Creator][] for generating the JWK. The JWK Creator was configured with matching -settings, i.e. `Signing` public key use and the `RS256` algorithm. The generated JWK was wrapped in a JWKS structure -and is hosted in the repo. - -[Quickstart]: https://github.com/envoyproxy/gateway/blob/main/docs/latest/user/quickstart.md -[make]: https://www.gnu.org/software/make/ -[Github Actions]: https://docs.github.com/en/actions -[workflows]: https://github.com/envoyproxy/gateway/tree/main/.github/workflows -[Kind]: https://kind.sigs.k8s.io/ -[conformance homepage]: https://gateway-api.sigs.k8s.io/concepts/conformance/ -[directly exposing]: https://kind.sigs.k8s.io/docs/user/loadbalancer/ -[Kubernetes support]: https://docs.docker.com/desktop/kubernetes/ -[gateway-dev]: https://hub.docker.com/r/envoyproxy/gateway-dev/tags -[mac_connect]: https://github.com/chipmk/docker-mac-net-connect -[Envoy admin interface]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface -[jwt]: https://tools.ietf.org/html/rfc7519 -[jwks]: https://tools.ietf.org/html/rfc7517 -[request authentication]: ../tasks/security/jwt-authentication -[JWT Debugger]: https://jwt.io/ -[JWK Creator]: https://russelldavies.github.io/jwk-creator/ diff --git a/site/content/en/v1.0.1/contributions/_index.md b/site/content/en/v1.0.1/contributions/_index.md deleted file mode 100644 index 1d3037e609e..00000000000 --- a/site/content/en/v1.0.1/contributions/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Get Involved -description: "This section includes contents related to Contributions" -weight: 100 ---- diff --git a/site/content/en/v1.0.1/contributions/design/_index.md b/site/content/en/v1.0.1/contributions/design/_index.md deleted file mode 100644 index 5cacb86df70..00000000000 --- a/site/content/en/v1.0.1/contributions/design/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Design" -weight: -100 -description: This section includes Designs of Envoy Gateway. ---- diff --git a/site/content/en/v1.0.1/contributions/design/accesslog.md b/site/content/en/v1.0.1/contributions/design/accesslog.md deleted file mode 100644 index a229d5f6eff..00000000000 --- a/site/content/en/v1.0.1/contributions/design/accesslog.md +++ /dev/null @@ -1,243 +0,0 @@ ---- -title: "Observability: Accesslog" ---- - -## Overview - -Envoy supports extensible accesslog to different sinks, File, gRPC etc. Envoy supports customizable access log formats using predefined fields as well as arbitrary HTTP request and response headers. Envoy supports several built-in access log filters and extension filters that are registered at runtime. - -Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementers such as Envoy Gateway to expose features. Since accesslog is not covered by `Core` or `Extended` APIs, EG should provide an easy to config access log formats and sinks per `EnvoyProxy`. - -## Goals - -- Support send accesslog to `File` or `OpenTelemetry` backend -- TODO: Support access log filters base on [CEL][] expression - -## Non-Goals - -- Support non-CEL filters, e.g. `status_code_filter`, `response_flag_filter` -- Support [HttpGrpcAccessLogConfig][] or [TcpGrpcAccessLogConfig][] - -## Use-Cases - -- Configure accesslog for a `EnvoyProxy` to `File` -- Configure accesslog for a `EnvoyProxy` to `OpenTelemetry` backend -- Configure multi accesslog providers for a `EnvoyProxy` - -### ProxyAccessLog API Type - -```golang mdox-exec="sed '1,7d' api/config/v1alpha1/accesslogging_types.go" -type ProxyAccessLog struct { - // Disable disables access logging for managed proxies if set to true. - Disable bool `json:"disable,omitempty"` - // Settings defines accesslog settings for managed proxies. - // If unspecified, will send default format to stdout. - // +optional - Settings []ProxyAccessLogSetting `json:"settings,omitempty"` -} - -type ProxyAccessLogSetting struct { - // Format defines the format of accesslog. - Format ProxyAccessLogFormat `json:"format"` - // Sinks defines the sinks of accesslog. - // +kubebuilder:validation:MinItems=1 - Sinks []ProxyAccessLogSink `json:"sinks"` -} - -type ProxyAccessLogFormatType string - -const ( - // ProxyAccessLogFormatTypeText defines the text accesslog format. - ProxyAccessLogFormatTypeText ProxyAccessLogFormatType = "Text" - // ProxyAccessLogFormatTypeJSON defines the JSON accesslog format. - ProxyAccessLogFormatTypeJSON ProxyAccessLogFormatType = "JSON" - // TODO: support format type "mix" in the future. -) - -// ProxyAccessLogFormat defines the format of accesslog. -// +union -type ProxyAccessLogFormat struct { - // Type defines the type of accesslog format. - // +kubebuilder:validation:Enum=Text;JSON - // +unionDiscriminator - Type ProxyAccessLogFormatType `json:"type,omitempty"` - // Text defines the text accesslog format, following Envoy accesslog formatting, - // empty value results in proxy's default access log format. - // It's required when the format type is "Text". - // Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the format. - // The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information. - // +optional - Text *string `json:"text,omitempty"` - // JSON is additional attributes that describe the specific event occurrence. - // Structured format for the envoy access logs. Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) - // can be used as values for fields within the Struct. - // It's required when the format type is "JSON". - // +optional - JSON map[string]string `json:"json,omitempty"` -} - -type ProxyAccessLogSinkType string - -const ( - // ProxyAccessLogSinkTypeFile defines the file accesslog sink. - ProxyAccessLogSinkTypeFile ProxyAccessLogSinkType = "File" - // ProxyAccessLogSinkTypeOpenTelemetry defines the OpenTelemetry accesslog sink. - ProxyAccessLogSinkTypeOpenTelemetry ProxyAccessLogSinkType = "OpenTelemetry" -) - -type ProxyAccessLogSink struct { - // Type defines the type of accesslog sink. - // +kubebuilder:validation:Enum=File;OpenTelemetry - Type ProxyAccessLogSinkType `json:"type,omitempty"` - // File defines the file accesslog sink. - // +optional - File *FileEnvoyProxyAccessLog `json:"file,omitempty"` - // OpenTelemetry defines the OpenTelemetry accesslog sink. - // +optional - OpenTelemetry *OpenTelemetryEnvoyProxyAccessLog `json:"openTelemetry,omitempty"` -} - -type FileEnvoyProxyAccessLog struct { - // Path defines the file path used to expose envoy access log(e.g. /dev/stdout). - // Empty value disables accesslog. - Path string `json:"path,omitempty"` -} - -// TODO: consider reuse ExtensionService? -type OpenTelemetryEnvoyProxyAccessLog struct { - // Host define the extension service hostname. - Host string `json:"host"` - // Port defines the port the extension service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` - // Resources is a set of labels that describe the source of a log entry, including envoy node info. - // It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). - // +optional - Resources map[string]string `json:"resources,omitempty"` - - // TODO: support more OpenTelemetry accesslog options(e.g. TLS, auth etc.) in the future. -} -``` - -### Example - -- The following is an example to disable access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/disable-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: disable-accesslog - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - disable: true -``` - -- The following is an example with text format access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/text-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: text-access-logging - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: Text - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - sinks: - - type: File - file: - path: /dev/stdout -``` - -- The following is an example with json format access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/json-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: json-access-logging - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: JSON - json: - status: "%RESPONSE_CODE%" - message: "%LOCAL_REPLY_BODY%" - sinks: - - type: File - file: - path: /dev/stdout -``` - -- The following is an example with OpenTelemetry format access log. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/otel-accesslog.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: otel-access-logging - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: Text - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - resources: - k8s.cluster.name: "cluster-1" -``` - -- The following is an example of sending same format to different sinks. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/accesslog/multi-sinks.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: multi-sinks - namespace: envoy-gateway-system -spec: - telemetry: - accessLog: - settings: - - format: - type: Text - text: | - [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" - sinks: - - type: File - file: - path: /dev/stdout - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - resources: - k8s.cluster.name: "cluster-1" -``` - -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels -[CEL]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/access_loggers/filters/cel/v3/cel.proto#extension-envoy-access-loggers-extension-filters-cel -[HttpGrpcAccessLogConfig]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/access_loggers/grpc/v3/als.proto#extensions-access-loggers-grpc-v3-httpgrpcaccesslogconfig -[TcpGrpcAccessLogConfig]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/access_loggers/grpc/v3/als.proto#extensions-access-loggers-grpc-v3-tcpgrpcaccesslogconfig diff --git a/site/content/en/v1.0.1/contributions/design/backend-traffic-policy.md b/site/content/en/v1.0.1/contributions/design/backend-traffic-policy.md deleted file mode 100644 index 9411ef20978..00000000000 --- a/site/content/en/v1.0.1/contributions/design/backend-traffic-policy.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: "BackendTrafficPolicy" ---- - -## Overview - -This design document introduces the `BackendTrafficPolicy` API allowing users to configure -the behavior for how the Envoy Proxy server communicates with upstream backend services/endpoints. - -## Goals - -- Add an API definition to hold settings for configuring behavior of the connection between the backend services -and Envoy Proxy listener. - -## Non Goals - -- Define the API configuration fields in this API. - -## Implementation - -`BackendTrafficPolicy` is an implied hierarchy type API that can be used to extend [Gateway API][]. -It can target either a `Gateway`, or an xRoute (`HTTPRoute`/`GRPCRoute`/etc.). When targeting a `Gateway`, -it will apply the configured settings within ght `BackendTrafficPolicy` to all children xRoute resources of that `Gateway`. -If a `BackendTrafficPolicy` targets an xRoute and a different `BackendTrafficPolicy` targets the `Gateway` that route belongs to, -then the configuration from the policy that is targeting the xRoute resource will win in a conflict. - -### Example - -Here is an example highlighting how a user can configure this API. - -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: eg -spec: - controllerName: gateway.envoyproxy.io/gatewayclass-controller ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: eg - namespace: default -spec: - gatewayClassName: eg - listeners: - - name: http - protocol: HTTP - port: 80 ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: ipv4-route - namespace: default -spec: - parentRefs: - - name: eg - hostnames: - - "www.foo.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: ipv4-service - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: / ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: ipv6-route - namespace: default -spec: - parentRefs: - - name: eg - hostnames: - - "www.bar.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: ipv6-service - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: / ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: default-ipv-policy - namespace: default -spec: - protocols: - enableIPv6: false - targetRef: - group: gateway.networking.k8s.io - kind: Gateway - name: eg - namespace: default ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ipv6-support-policy - namespace: default -spec: - protocols: - enableIPv6: true - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: ipv6-route - namespace: default -``` - -## Features / API Fields - -Here is a list of some features that can be included in this API. Note that this list is not exhaustive. - -- Protocol configuration -- Circuit breaking -- Retries -- Keep alive probes -- Health checking -- Load balancing -- Rate limit - -## Design Decisions - -- This API will only support a single `targetRef` and can bind to only a `Gateway` or xRoute (`HTTPRoute`/`GRPCRoute`/etc.) resource. -- This API resource MUST be part of same namespace as the resource it targets. -- There can be only be ONE policy resource attached to a specific `Listener` (section) within a `Gateway` -- If the policy targets a resource but cannot attach to it, this information should be reflected -in the Policy Status field using the `Conflicted=True` condition. -- If multiple polices target the same resource, the oldest resource (based on creation timestamp) will -attach to the Gateway Listeners, the others will not. -- If Policy A has a `targetRef` that includes a `sectionName` i.e. -it targets a specific Listener within a `Gateway` and Policy B has a `targetRef` that targets the same -entire Gateway then - - Policy A will be applied/attached to the specific Listener defined in the `targetRef.SectionName` - - Policy B will be applied to the remaining Listeners within the Gateway. Policy B will have an additional - status condition `Overridden=True`. - -## Alternatives - -- The project can indefintely wait for these configuration parameters to be part of the [Gateway API][]. - -[Gateway API]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/v1.0.1/contributions/design/bootstrap.md b/site/content/en/v1.0.1/contributions/design/bootstrap.md deleted file mode 100644 index c0581347a24..00000000000 --- a/site/content/en/v1.0.1/contributions/design/bootstrap.md +++ /dev/null @@ -1,381 +0,0 @@ ---- -title: "Bootstrap Design" ---- - -## Overview - -[Issue 31][] specifies the need for allowing advanced users to specify their custom -Envoy Bootstrap configuration rather than using the default Bootstrap configuration -defined in Envoy Gateway. This allows advanced users to extend Envoy Gateway and -support their custom use cases such setting up tracing and stats configuration -that is not supported by Envoy Gateway. - -## Goals - -* Define an API field to allow a user to specify a custom Bootstrap -* Provide tooling to allow the user to generate the default Bootstrap configuration - as well as validate their custom Bootstrap. - -## Non Goals - -* Allow user to configure only a section of the Bootstrap - -## API - -Leverage the existing [EnvoyProxy][] resource which can be attached to the [GatewayClass][] using -the [parametersRef][] field, and define a `Bootstrap` field within the resource. If this field is set, -the value is used as the Bootstrap configuration for all managed Envoy Proxies created by Envoy Gateway. - -```go -// EnvoyProxySpec defines the desired state of EnvoyProxy. -type EnvoyProxySpec struct { - ...... - // Bootstrap defines the Envoy Bootstrap as a YAML string. - // Visit https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-msg-config-bootstrap-v3-bootstrap - // to learn more about the syntax. - // If set, this is the Bootstrap configuration used for the managed Envoy Proxy fleet instead of the default Bootstrap configuration - // set by Envoy Gateway. - // Some fields within the Bootstrap that are required to communicate with the xDS Server (Envoy Gateway) and receive xDS resources - // from it are not configurable and will result in the `EnvoyProxy` resource being rejected. - // Backward compatibility across minor versions is not guaranteed. - // We strongly recommend using `egctl x translate` to generate a `EnvoyProxy` resource with the `Bootstrap` field set to the default - // Bootstrap configuration used. You can edit this configuration, and rerun `egctl x translate` to ensure there are no validation errors. - // - // +optional - Bootstrap *string `json:"bootstrap,omitempty"` -} -``` - -## Tooling - -A CLI tool `egctl x translate` will be provided to the user to help generate a working Bootstrap configuration. -Here is an example where a user inputs a `GatewayClass` and the CLI generates the `EnvoyProxy` resource with the `Bootstrap` field populated. - -``` -cat < /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -provider: - type: Kubernetes - kubernetes: {} -EOF -``` - -This configuration will cause Envoy Gateway to use the Kubernetes provider with default configuration parameters. - -The Kubernetes provider can be configured using the `provider` field. For example, the `foo` field can be set to "bar": - -```yaml -$ cat << EOF > /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -provider: - type: Kubernetes - kubernetes: - foo: bar -EOF -``` - -__Note:__ The Provider API from the Kubernetes package is currently undefined and `foo: bar` is provided for -illustration purposes only. - -The same API structure is followed for each supported provider. The following example causes Envoy Gateway to use the -File provider: - -```yaml -$ cat << EOF > /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -provider: - type: File - file: - foo: bar -EOF -``` - -__Note:__ The Provider API from the File package is currently undefined and `foo: bar` is provided for illustration -purposes only. - -Gateway API-related configuration is expressed through the `gateway` field. If unspecified, Envoy Gateway will use -default configuration parameters for `gateway`. The following example causes the [GatewayClass][gc] controller to -manage GatewayClasses with controllerName `foo` instead of the default `gateway.envoyproxy.io/gatewayclass-controller`: - -```yaml -$ cat << EOF > /etc/envoy-gateway/config.yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: foo -EOF -``` - -With any of the above configuration examples, Envoy Gateway can be started without any additional arguments: - -```shell -$ ./envoy-gateway -``` - -## Data Plane API - -The data plane is configured dynamically through Kubernetes resources, primarily [Gateway API][gw_api] objects. -Optionally, the data plane infrastructure can be configured by referencing a [custom resource (CR)][cr] through -`spec.parametersRef` of the managed GatewayClass. The `EnvoyProxy` API defines the data plane infrastructure -configuration and is represented as the CR referenced by the managed GatewayClass. Key points of this API are: - -* If unreferenced by `gatewayclass.spec.parametersRef`, default parameters will be used to configure the data plane - infrastructure, e.g. expose Envoy network endpoints using a LoadBalancer service. -* Envoy Gateway will follow Gateway API [recommendations][gc] regarding updates to the EnvoyProxy CR: - > It is recommended that this resource be used as a template for Gateways. This means that a Gateway is based on the - > state of the GatewayClass at the time it was created and changes to the GatewayClass or associated parameters are - > not propagated down to existing Gateways. - -The initial `EnvoyProxy` API: - -```go -// gateway/api/config/v1alpha1/envoyproxy.go - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EnvoyProxy is the Schema for the envoyproxies API. -type EnvoyProxy struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec EnvoyProxySpec `json:"spec,omitempty"` - Status EnvoyProxyStatus `json:"status,omitempty"` -} - -// EnvoyProxySpec defines the desired state of Envoy Proxy infrastructure -// configuration. -type EnvoyProxySpec struct { - // Undefined by this design spec. -} - -// EnvoyProxyStatus defines the observed state of EnvoyProxy. -type EnvoyProxyStatus struct { - // Undefined by this design spec. -} -``` - -The EnvoyProxySpec and EnvoyProxyStatus fields will be defined in the future as proxy infrastructure configuration use -cases are better understood. - -### Data Plane Configuration - -GatewayClass and Gateway resources define the data plane infrastructure. Note that all examples assume Envoy Gateway is -running with the Kubernetes provider. - -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: example-class -spec: - controllerName: gateway.envoyproxy.io/gatewayclass-controller ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: example-gateway -spec: - gatewayClassName: example-class - listeners: - - name: http - protocol: HTTP - port: 80 -``` - -Since the GatewayClass does not define `spec.parametersRef`, the data plane is provisioned using default configuration -parameters. The Envoy proxies will be configured with a http listener and a Kubernetes LoadBalancer service listening -on port 80. - -The following example will configure the data plane to use a ClusterIP service instead of the default LoadBalancer -service: - -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: example-class -spec: - controllerName: gateway.envoyproxy.io/gatewayclass-controller - parametersRef: - name: example-config - group: gateway.envoyproxy.io - kind: EnvoyProxy ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: example-gateway -spec: - gatewayClassName: example-class - listeners: - - name: http - protocol: HTTP - port: 80 ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: example-config -spec: - networkPublishing: - type: ClusterIPService -``` - -__Note:__ The NetworkPublishing API is currently undefined and is provided here for illustration purposes only. - -[issue_51]: https://github.com/envoyproxy/gateway/issues/51 -[design_doc]: ../system-design/ -[gw_api]: https://gateway-api.sigs.k8s.io/ -[gc]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass -[cr]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ -[union]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#unions diff --git a/site/content/en/v1.0.1/contributions/design/eg-metrics.md b/site/content/en/v1.0.1/contributions/design/eg-metrics.md deleted file mode 100644 index 0ca0e7229ec..00000000000 --- a/site/content/en/v1.0.1/contributions/design/eg-metrics.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -date: 2023-10-10 -title: "Control Plane Observability: Metrics" ---- - -This document aims to cover all aspects of envoy gateway control plane metrics observability. - -{{% alert title="Note" color="secondary" %}} -**Data plane** observability (while important) is outside of scope for this document. For dataplane observability, refer to [here](../metrics). -{{% /alert %}} - -## Current State - -At present, the Envoy Gateway control plane provides logs and controller-runtime metrics, without traces. Logs are managed through our proprietary library (`internal/logging`, a shim to `zap`) and are written to `/dev/stdout`. - -## Goals - -Our objectives include: - -+ Supporting **PULL** mode for Prometheus metrics and exposing these metrics on the admin address. -+ Supporting **PUSH** mode for Prometheus metrics, thereby sending metrics to the Open Telemetry Stats sink via gRPC or HTTP. - -## Non-Goals - -Our non-goals include: - -+ Supporting other stats sinks. - -## Use-Cases - -The use-cases include: - -+ Exposing Prometheus metrics in the Envoy Gateway Control Plane. -+ Pushing Envoy Gateway Control Plane metrics via the Open Telemetry Sink. - -## Design - -### Standards - -Our metrics, will be built upon the [OpenTelemetry][] standards. All metrics will be configured via the [OpenTelemetry SDK][], which offers neutral libraries that can be connected to various backends. - -This approach allows the Envoy Gateway code to concentrate on the crucial aspect - generating the metrics - and delegate all other tasks to systems designed for telemetry ingestion. - -### Attributes - -OpenTelemetry defines a set of [Semantic Conventions][], including [Kubernetes specific ones][]. - -These attributes can be expressed in logs (as keys of structured logs), traces (as attributes), and metrics (as labels). - -We aim to use attributes consistently where applicable. Where possible, these should adhere to codified Semantic Conventions; when not possible, they should maintain consistency across the project. - -### Extensibility - -Envoy Gateway supports both **PULL/PUSH** mode metrics, with Metrics exported via Prometheus by default. - -Additionally, Envoy Gateway can export metrics using both the [OTEL gRPC metrics exporter][] and [OTEL HTTP metrics exporter][], which pushes metrics by grpc/http to a remote OTEL collector. - -Users can extend these in two ways: - -#### Downstream Collection - -Based on the exported data, other tools can collect, process, and export telemetry as needed. Some examples include: - -+ Metrics in **PULL** mode: The OTEL collector can scrape Prometheus and export to X. -+ Metrics in **PUSH** mode: The OTEL collector can receive OTEL gRPC/HTTP exporter metrics and export to X. - -While the examples above involve OTEL collectors, there are numerous other systems available. - -#### Vendor extensions - -The OTEL libraries allow for the registration of Providers/Handlers. While we will offer the default ones (PULL via Prometheus, PUSH via OTEL HTTP metrics exporter) mentioned in Envoy Gateway's extensibility, we can easily allow custom builds of Envoy Gateway to plug in alternatives if the default options don't meet their needs. - -For instance, users may prefer to write metrics over the OTLP gRPC metrics exporter instead of the HTTP metrics exporter. This is perfectly acceptable -- and almost impossible to prevent. The OTEL has ways to register their providers/exporters, and Envoy Gateway can ensure its usage is such that it's not overly difficult to swap out a different provider/exporter. - -### Stability - -Observability is, in essence, a user-facing API. Its primary purpose is to be consumed - by both humans and tooling. Therefore, having well-defined guarantees around their formats is crucial. - -Please note that this refers only to the contents of the telemetry - what we emit, the names of things, semantics, etc. Other settings like Prometheus vs OTLP, JSON vs plaintext, logging levels, etc., are not considered. - -I propose the following: - -#### Metrics - -Metrics offer the greatest potential for providing guarantees. They often directly influence alerts and dashboards, making changes highly impactful. This contrasts with traces and logs, which are often used for ad-hoc analysis, where minor changes to information can be easily understood by a human. - -Moreover, there is precedent for this: [Kubernetes Metrics Lifecycle][] has well-defined processes, and Envoy Gateway's dataplane (Envoy Proxy) metrics are de facto stable. - -Currently, all Envoy Gateway metrics lack defined stability. I suggest we categorize all existing metrics as either: - -+ ***Deprecated***: a metric that is intended to be phased out. -+ ***Experimental***: a metric that is off by default. -+ ***Alpha***: a metric that is on by default. - -We should aim to promote a core set of metrics to **Stable** within a few releases. - -## Envoy Gateway API Types - -New APIs will be added to Envoy Gateway config, which are used to manage Control Plane Telemetry bootstrap configs. - -### EnvoyGatewayTelemetry - -``` go -// EnvoyGatewayTelemetry defines telemetry configurations for envoy gateway control plane. -// Control plane will focus on metrics observability telemetry and tracing telemetry later. -type EnvoyGatewayTelemetry struct { - // Metrics defines metrics configuration for envoy gateway. - Metrics *EnvoyGatewayMetrics `json:"metrics,omitempty"` -} -``` - -### EnvoyGatewayMetrics - -> Prometheus will be exposed on 0.0.0.0:19001, which is not supported to be configured yet. - -``` go -// EnvoyGatewayMetrics defines control plane push/pull metrics configurations. -type EnvoyGatewayMetrics struct { - // Sinks defines the metric sinks where metrics are sent to. - Sinks []EnvoyGatewayMetricSink `json:"sinks,omitempty"` - // Prometheus defines the configuration for prometheus endpoint. - Prometheus *EnvoyGatewayPrometheusProvider `json:"prometheus,omitempty"` -} - -// EnvoyGatewayMetricSink defines control plane -// metric sinks where metrics are sent to. -type EnvoyGatewayMetricSink struct { - // Type defines the metric sink type. - // EG control plane currently supports OpenTelemetry. - // +kubebuilder:validation:Enum=OpenTelemetry - // +kubebuilder:default=OpenTelemetry - Type MetricSinkType `json:"type"` - // OpenTelemetry defines the configuration for OpenTelemetry sink. - // It's required if the sink type is OpenTelemetry. - OpenTelemetry *EnvoyGatewayOpenTelemetrySink `json:"openTelemetry,omitempty"` -} - -type EnvoyGatewayOpenTelemetrySink struct { - // Host define the sink service hostname. - Host string `json:"host"` - // Protocol define the sink service protocol. - // +kubebuilder:validation:Enum=grpc;http - Protocol string `json:"protocol"` - // Port defines the port the sink service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` -} - -// EnvoyGatewayPrometheusProvider will expose prometheus endpoint in pull mode. -type EnvoyGatewayPrometheusProvider struct { - // Disable defines if disables the prometheus metrics in pull mode. - // - Disable bool `json:"disable,omitempty"` -} - -``` - -#### Example - -+ The following is an example to disable prometheus metric. - -``` yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: gateway.envoyproxy.io/gatewayclass-controller -logging: - level: null - default: info -provider: - type: Kubernetes -telemetry: - metrics: - prometheus: - disable: true -``` - -+ The following is an example to send metric via Open Telemetry sink to OTEL gRPC Collector. - -``` yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: gateway.envoyproxy.io/gatewayclass-controller -logging: - level: null - default: info -provider: - type: Kubernetes -telemetry: - metrics: - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - protocol: grpc -``` - -+ The following is an example to disable prometheus metric and send metric via Open Telemetry sink to OTEL HTTP Collector at the same time. - -``` yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyGateway -gateway: - controllerName: gateway.envoyproxy.io/gatewayclass-controller -logging: - level: null - default: info -provider: - type: Kubernetes -telemetry: - metrics: - prometheus: - disable: false - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4318 - protocol: http -``` - -[OpenTelemetry]: https://opentelemetry.io/ -[OpenTelemetry SDK]: https://opentelemetry.io/docs/specs/otel/metrics/sdk/ -[Semantic Conventions]: https://opentelemetry.io/docs/concepts/semantic-conventions/ -[Kubernetes specific ones]: https://opentelemetry.io/docs/specs/otel/resource/semantic_conventions/k8s/ -[OTEL gRPC metrics exporter]: https://opentelemetry.io/docs/specs/otel/metrics/sdk_exporters/otlp/#general -[OTEL HTTP metrics exporter]: https://opentelemetry.io/docs/specs/otel/metrics/sdk_exporters/otlp/#general -[Kubernetes Metrics Lifecycle]: https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/#metric-lifecycle diff --git a/site/content/en/v1.0.1/contributions/design/egctl.md b/site/content/en/v1.0.1/contributions/design/egctl.md deleted file mode 100644 index 4bc8876092d..00000000000 --- a/site/content/en/v1.0.1/contributions/design/egctl.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "egctl Design" ---- - -## Motivation - -EG should provide a command line tool with following capabilities: - -- Collect configuration from envoy proxy and gateway -- Analyse system configuration to diagnose any issues in envoy gateway - -This tool is named `egctl`. - -## Syntax - -Use the following syntax to run `egctl` commands from your terminal window: - -```console -egctl [command] [entity] [name] [flags] -``` - -where `command`, `name`, and `flags` are: - -* `command`: Specifies the operation that you want to perform on one or more resources, - for example `config`, `version`. - -* `entity`: Specifies the entity the operation is being performed on such as `envoy-proxy` or `envoy-gateway`. - -* `name`: Specifies the name of the specified instance. - -* `flags`: Specifies optional flags. For example, you can use the `-c` or `--config` flags to specify the values for installing. - -If you need help, run `egctl help` from the terminal window. - -## Operation - -The following table includes short descriptions and the general syntax for all the `egctl` operations: - -| Operation | Syntax | Description | -| --------------| -------------------------------- | -------------------------------------------------------------------------------------| -| `version` | `egctl version` | Prints out build version information. | -| `config` | `egctl config ENTITY` | Retrieve information about proxy configuration from envoy proxy and gateway | -| `analyze` | `egctl analyze` | Analyze EG configuration and print validation messages | -| `experimental`| `egctl experimental` | Subcommand for experimental features. These do not guarantee backwards compatibility | - -## Examples - -Use the following set of examples to help you familiarize yourself with running the commonly used `egctl` operations: - -```console -# Retrieve all information about proxy configuration from envoy -egctl config envoy-proxy all - -# Retrieve listener information about proxy configuration from envoy -egctl config envoy-proxy listener - -# Retrieve the relevant rate limit configuration from the Rate Limit instance -egctl config envoy-ratelimit -``` diff --git a/site/content/en/v1.0.1/contributions/design/envoy-patch-policy.md b/site/content/en/v1.0.1/contributions/design/envoy-patch-policy.md deleted file mode 100644 index 343e6bab1e4..00000000000 --- a/site/content/en/v1.0.1/contributions/design/envoy-patch-policy.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: "EnvoyPatchPolicy" ---- - -## Overview - -This design introduces the `EnvoyPatchPolicy` API allowing users to modify the generated Envoy xDS Configuration -that Envoy Gateway generates before sending it to Envoy Proxy. - -Envoy Gateway allows users to configure networking and security intent using the -upstream [Gateway API][] as well as implementation specific [Extension APIs][] defined in this project -to provide a more batteries included experience for application developers. -* These APIs are an abstracted version of the underlying Envoy xDS API to provide a better user experience for the application developer, exposing and setting only a subset of the fields for a specific feature, sometimes in a opinionated way (e.g [RateLimit][]) -* These APIs do not expose all the features capabilities that Envoy has either because these features are desired but the API -is not defined yet or the project cannot support such an extensive list of features. -To alleviate this problem, and provide an interim solution for a small section of advanced users who are well versed in -Envoy xDS API and its capabilities, this API is being introduced. - -## Goals -* Add an API allowing users to modify the generated xDS Configuration - -## Non Goals -* Support multiple patch mechanisims - -## Implementation -`EnvoyPatchPolicy` is a [Direct Policy Attachment][] type API that can be used to extend [Gateway API][] -Modifications to the generated xDS configuration can be provided as a JSON Patch which is defined in -[RFC 6902][]. This patching mechanism has been adopted in [Kubernetes][] as well as [Kustomize][] to update -resource objects. - -### Example -Here is an example highlighting how a user can configure global ratelimiting using an external rate limit service using this API. - -``` -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: eg -spec: - controllerName: gateway.envoyproxy.io/gatewayclass-controller ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: eg - namespace: default -spec: - gatewayClassName: eg - listeners: - - name: http - protocol: HTTP - port: 80 ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: backend - namespace: default -spec: - parentRefs: - - name: eg - hostnames: - - "www.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: backend - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: / ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyPatchPolicy -metadata: - name: ratelimit-patch-policy - namespace: default -spec: - targetRef: - group: gateway.networking.k8s.io - kind: Gateway - name: eg - namespace: default - type: JSONPatch - jsonPatches: - - type: "type.googleapis.com/envoy.config.listener.v3.Listener" - # The listener name is of the form // - name: default/eg/http - operation: - op: add - path: "/default_filter_chain/filters/0/typed_config/http_filters/0" - value: - name: "envoy.filters.http.ratelimit" - typed_config: - "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit" - domain: "eag-ratelimit" - failure_mode_deny: true - timeout: 1s - rate_limit_service: - grpc_service: - envoy_grpc: - cluster_name: rate-limit-cluster - transport_api_version: V3 - - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration" - # The route name is of the form // - name: default/eg/http - operation: - op: add - path: "/virtual_hosts/0/rate_limits" - value: - - actions: - - remote_address: {} - - type: "type.googleapis.com/envoy.config.cluster.v3.Cluster" - name: rate-limit-cluster - operation: - op: add - path: "" - value: - name: rate-limit-cluster - type: STRICT_DNS - connect_timeout: 10s - lb_policy: ROUND_ROBIN - http2_protocol_options: {} - load_assignment: - cluster_name: rate-limit-cluster - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: ratelimit.svc.cluster.local - port_value: 8081 -``` - - -## Verification -* Offline - Leverage [egctl x translate][] to ensure that the `EnvoyPatchPolicy` can be successfully applied and the desired -output xDS is created. -* Runtime - Use the `Status` field within `EnvoyPatchPolicy` to highlight whether the patch was applied successfully or not. - -## State of the World -* Istio - Supports the [EnvoyFilter][] API which allows users to customize the output xDS using patches and proto based merge -semantics. - -## Design Decisions -* This API will only support a single `targetRef` and can bind to only a `Gateway` or `GatewayClass` resource. This simplifies reasoning of how -patches will work. -* This API will always be an experimental API and cannot be graduated into a stable API because Envoy Gateway cannot garuntee - * that the naming scheme for the generated resources names will not change across releases - * that the underlying Envoy Proxy API will not change across releases -* This API needs to be explicitly enabled using the [EnvoyGateway][] API - -## Open Questions -* Should the value only support JSON or YAML as well (which is a JSON superset) ? - -## Alternatives -* Users can customize the Envoy [Bootstrap configuration using EnvoyProxy API][] and provide static xDS configuration. -* Users can extend functionality by [Extending the Control Plane][] and adding gRPC hooks to modify the generated xDS configuration. - - - -[Direct Policy Attachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment/#direct-policy-attachment -[RFC 6902]: https://datatracker.ietf.org/doc/html/rfc6902 -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[Kubernetes]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ -[Kustomize]: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/jsonpatch.md -[Extension APIs]: ../../api/extension_types/ -[RateLimit]: ./rate-limit -[EnvoyGateway]: ../../api/extension_types#envoygateway -[Extending the Control Plane]: ./extending-envoy-gateway -[EnvoyFilter]: https://istio.io/latest/docs/reference/config/networking/envoy-filter -[egctl x translate]: ../../tasks/operations/egctl#egctl-experimental-translate -[Bootstrap configuration using EnvoyProxy API]: ../../tasks/operations/customize-envoyproxy#customize-envoyproxy-bootstrap-config diff --git a/site/content/en/v1.0.1/contributions/design/gatewayapi-translator.md b/site/content/en/v1.0.1/contributions/design/gatewayapi-translator.md deleted file mode 100644 index a086b80bfee..00000000000 --- a/site/content/en/v1.0.1/contributions/design/gatewayapi-translator.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -title: "Gateway API Translator Design" -weight: 4 ---- - -The Gateway API translates external resources, e.g. GatewayClass, from the configured Provider to the Intermediate -Representation (IR). - -## Assumptions - -Initially target core conformance features only, to be followed by extended conformance features. - -## Inputs and Outputs - -The main inputs to the Gateway API translator are: - -- GatewayClass, Gateway, HTTPRoute, TLSRoute, Service, ReferenceGrant, Namespace, and Secret resources. - -__Note:__ ReferenceGrant is not fully implemented as of v0.2. - -The outputs of the Gateway API translator are: - -- Xds and Infra Internal Representations (IRs). -- Status updates for GatewayClass, Gateways, HTTPRoutes - -## Listener Compatibility - -Envoy Gateway follows Gateway API listener compatibility spec: -> Each listener in a Gateway must have a unique combination of Hostname, Port, and Protocol. An implementation MAY group -> Listeners by Port and then collapse each group of Listeners into a single Listener if the implementation determines -> that the Listeners in the group are “compatible”. - -__Note:__ Envoy Gateway does not collapse listeners across multiple Gateways. - -### Listener Compatibility Examples - -#### Example 1: Gateway with compatible Listeners (same port & protocol, different hostnames) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: "*.envoygateway.io" - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: whales.envoygateway.io -``` - -#### Example 2: Gateway with compatible Listeners (same port & protocol, one hostname specified, one not) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: "*.envoygateway.io" - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All -``` - -#### Example 3: Gateway with incompatible Listeners (same port, protocol and hostname) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: whales.envoygateway.io - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - hostname: whales.envoygateway.io -``` - -#### Example 4: Gateway with incompatible Listeners (neither specify a hostname) - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: gateway-1 - namespace: envoy-gateway -spec: - gatewayClassName: envoy-gateway - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: All -``` - -## Computing Status - -Gateway API specifies a rich set of status fields & conditions for each resource. To achieve conformance, Envoy Gateway -must compute the appropriate status fields and conditions for managed resources. - -Status is computed and set for: - -- The managed GatewayClass (`gatewayclass.status.conditions`). -- Each managed Gateway, based on its Listeners' status (`gateway.status.conditions`). For the Kubernetes provider, the - Envoy Deployment and Service status are also included to calculate Gateway status. -- Listeners for each Gateway (`gateway.status.listeners`). -- The ParentRef for each Route (`route.status.parents`). - -The Gateway API translator is responsible for calculating status conditions while translating Gateway API resources to -the IR and publishing status over the [message bus][]. The Status Manager subscribes to these status messages and -updates the resource status using the configured provider. For example, the Status Manager uses a Kubernetes client to -update resource status on the Kubernetes API server. - -## Outline - -The following roughly outlines the translation process. Each step may produce (1) IR; and (2) status updates on Gateway -API resources. - -1. Process Gateway Listeners - - Validate unique hostnames, ports, and protocols. - - Validate and compute supported kinds. - - Validate allowed namespaces (validate selector if specified). - - Validate TLS fields if specified, including resolving referenced Secrets. - -2. Process HTTPRoutes - - foreach route rule: - - compute matches - - [core] path exact, path prefix - - [core] header exact - - [extended] query param exact - - [extended] HTTP method - - compute filters - - [core] request header modifier (set/add/remove) - - [core] request redirect (hostname, statuscode) - - [extended] request mirror - - compute backends - - [core] Kubernetes services - - foreach route parent ref: - - get matching listeners (check Gateway, section name, listener validation status, listener allowed routes, hostname intersection) - - foreach matching listener: - - foreach hostname intersection with route: - - add each computed route rule to host - -## Context Structs - -To help store, access and manipulate information as it's processed during the translation process, a set of context -structs are used. These structs wrap a given Gateway API type, and add additional fields and methods to support -processing. - -`GatewayContext` wraps a Gateway and provides helper methods for setting conditions, accessing Listeners, etc. - -```go -type GatewayContext struct { - // The managed Gateway - *v1beta1.Gateway - - // A list of Gateway ListenerContexts. - listeners []*ListenerContext -} -``` - -`ListenerContext` wraps a Listener and provides helper methods for setting conditions and other status information on -the associated Gateway. - -```go -type ListenerContext struct { - // The Gateway listener. - *v1beta1.Listener - - // The Gateway this Listener belongs to. - gateway *v1beta1.Gateway - - // An index used for managing this listener in the list of Gateway listeners. - listenerStatusIdx int - - // Only Routes in namespaces selected by the selector may be attached - // to the Gateway this listener belongs to. - namespaceSelector labels.Selector - - // The TLS Secret for this Listener, if applicable. - tlsSecret *v1.Secret -} -``` - -`RouteContext` represents a generic Route object (HTTPRoute, TLSRoute, etc.) that can reference Gateway objects. - -```go -type RouteContext interface { - client.Object - - // GetRouteType returns the Kind of the Route object, HTTPRoute, - // TLSRoute, TCPRoute, UDPRoute etc. - GetRouteType() string - - // GetHostnames returns the hosts targeted by the Route object. - GetHostnames() []string - - // GetParentReferences returns the ParentReference of the Route object. - GetParentReferences() []v1beta1.ParentReference - - // GetRouteParentContext returns RouteParentContext by using the Route - // objects' ParentReference. - GetRouteParentContext(forParentRef v1beta1.ParentReference) *RouteParentContext -} -``` - -[message bus]: ../watching/ diff --git a/site/content/en/v1.0.1/contributions/design/goals.md b/site/content/en/v1.0.1/contributions/design/goals.md deleted file mode 100644 index fd38b2004c6..00000000000 --- a/site/content/en/v1.0.1/contributions/design/goals.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Goals" -weight: 1 ---- - -The high-level goal of the Envoy Gateway project is to attract more users to Envoy by lowering barriers to adoption -through expressive, extensible, role-oriented APIs that support a multitude of ingress and L7/L4 traffic routing -use cases; and provide a common foundation for vendors to build value-added products without having to re-engineer -fundamental interactions. - -## Objectives - -### Expressive API - -The Envoy Gateway project will expose a simple and expressive API, with defaults set for many capabilities. - -The API will be the Kubernetes-native [Gateway API][], plus Envoy-specific extensions and extension points. This -expressive and familiar API will make Envoy accessible to more users, especially application developers, and make Envoy -a stronger option for "getting started" as compared to other proxies. Application developers will use the API out of -the box without needing to understand in-depth concepts of Envoy Proxy or use OSS wrappers. The API will use familiar -nouns that [users](#personas) understand. - -The core full-featured Envoy xDS APIs will remain available for those who need more capability and for those who -add functionality on top of Envoy Gateway, such as commercial API gateway products. - -This expressive API will not be implemented by Envoy Proxy, but rather an officially supported translation layer -on top. - -### Batteries included - -Envoy Gateway will simplify how Envoy is deployed and managed, allowing application developers to focus on -delivering core business value. - -The project plans to include additional infrastructure components required by users to fulfill their Ingress and API -gateway needs: It will handle Envoy infrastructure provisioning (e.g. Kubernetes Service, Deployment, et cetera), and -possibly infrastructure provisioning of related sidecar services. It will include sensible defaults with the ability to -override. It will include channels for improving ops by exposing status through API conditions and Kubernetes status -sub-resources. - -Making an application accessible needs to be a trivial task for any developer. Similarly, infrastructure administrators -will enjoy a simplified management model that doesn't require extensive knowledge of the solution's architecture to -operate. - -### All environments - -Envoy Gateway will support running natively in Kubernetes environments as well as non-Kubernetes deployments. - -Initially, Kubernetes will receive the most focus, with the aim of having Envoy Gateway become the de facto -standard for Kubernetes ingress supporting the [Gateway API][]. -Additional goals include multi-cluster support and various runtime environments. - -### Extensibility - -Vendors will have the ability to provide value-added products built on the Envoy Gateway foundation. - -It will remain easy for end-users to leverage common Envoy Proxy extension points such as providing an implementation -for authentication methods and rate-limiting. For advanced use cases, users will have the ability to use the full power -of xDS. - -Since a general-purpose API cannot address all use cases, Envoy Gateway will provide additional extension points -for flexibility. As such, Envoy Gateway will form the base of vendor-provided managed control plane solutions, -allowing vendors to shift to a higher management plane layer. - -## Non-objectives - -### Cannibalize vendor models - -Vendors need to have the ability to drive commercial value, so the goal is not to cannibalize any existing vendor -monetization model, though some vendors may be affected by it. - -### Disrupt current Envoy usage patterns - -Envoy Gateway is purely an additive convenience layer and is not meant to disrupt any usage pattern of any user -with Envoy Proxy, xDS, or go-control-plane. - -## Personas - -_In order of priority_ - -### 1. Application developer - -The application developer spends the majority of their time developing business logic code. They require the ability to -manage access to their application. - -### 2. Infrastructure administrators - -The infrastructure administrators are responsible for the installation, maintenance, and operation of -API gateways appliances in infrastructure, such as CRDs, roles, service accounts, certificates, etc. -Infrastructure administrators support the needs of application developers by managing instances of Envoy Gateway. - -[Gateway API]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/v1.0.1/contributions/design/local-envoy-gateway.md b/site/content/en/v1.0.1/contributions/design/local-envoy-gateway.md deleted file mode 100644 index aad0dc5f6f2..00000000000 --- a/site/content/en/v1.0.1/contributions/design/local-envoy-gateway.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Running Envoy Gateway locally" ---- - -## Overview - -Today, Envoy Gateway runs only on Kubernetes. This is an ideal solution -when the applications are running in Kubernetes. -However there might be cases when the applications are running on the host which would -require Envoy Gateway to run locally. - -## Goals - -* Define an API to allow Envoy Gateway to retrieve configuration while running locally. -* Define an API to allow Envoy Gateway to deploy the managed Envoy Proxy fleet on the host -machine. - -## Non Goals - -* Support multiple ways to retrieve configuration while running locally. -* Support multiple ways to deploy the Envoy Proxy fleet locally on the host. - -## API - -* The `provider` field within the `EnvoyGateway` configuration only supports -`Kubernetes` today which provides two features - the ability to retrieve -resources from the Kubernetes API Server as well as deploy the managed -Envoy Proxy fleet on Kubernetes. -* This document proposes adding a new top level `provider` type called `Custom` -with two fields called `resource` and `infrastructure` to allow the user to configure -the sub providers for providing resource configuration and an infrastructure to deploy -the Envoy Proxy data plane in. -* A `File` resource provider will be introduced to enable retrieveing configuration locally -by reading from the configuration from a file. -* A `Host` infrastructure provider will be introduced to allow Envoy Gateway to spawn a -Envoy Proxy child process on the host. - -Here is an example configuration - -``` -provider: - type: Custom - custom: - resource: - type: File - file: - paths: - - "config.yaml" - infrastructure: - type: Host - host: {} -``` diff --git a/site/content/en/v1.0.1/contributions/design/metrics.md b/site/content/en/v1.0.1/contributions/design/metrics.md deleted file mode 100644 index 78b05eea98e..00000000000 --- a/site/content/en/v1.0.1/contributions/design/metrics.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: "Observability: Metrics" ---- - -## Overview - -Envoy provide robust platform for metrics, Envoy support three different kinds of stats: counter, gauges, histograms. - -Envoy enables prometheus format output via the `/stats/prometheus` [admin endpoint][]. - -Envoy support different kinds of sinks, but EG will only support [Open Telemetry sink][]. - -Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementers such as Envoy Gateway to expose features. Since metrics is not covered by `Core` or `Extended` APIs, EG should provide an easy to config metrics per `EnvoyProxy`. - -## Goals - -- Support expose metrics in prometheus way(reuse probe port). -- Support Open Telemetry stats sink. - -## Non-Goals - -- Support other stats sink. - -## Use-Cases - -- Enable prometheus metric by default -- Disable prometheus metric -- Push metrics via Open Telemetry Sink -- TODO: Customize histogram buckets of target metric -- TODO: Support stats matcher - -### ProxyMetric API Type - -```golang mdox-exec="sed '1,7d' api/v1alpha1/metric_types.go" -type ProxyMetrics struct { - // Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. - Prometheus *PrometheusProvider `json:"prometheus,omitempty"` - // Sinks defines the metric sinks where metrics are sent to. - Sinks []MetricSink `json:"sinks,omitempty"` -} - -type MetricSinkType string - -const ( - MetricSinkTypeOpenTelemetry MetricSinkType = "OpenTelemetry" -) - -type MetricSink struct { - // Type defines the metric sink type. - // EG currently only supports OpenTelemetry. - // +kubebuilder:validation:Enum=OpenTelemetry - // +kubebuilder:default=OpenTelemetry - Type MetricSinkType `json:"type"` - // OpenTelemetry defines the configuration for OpenTelemetry sink. - // It's required if the sink type is OpenTelemetry. - OpenTelemetry *OpenTelemetrySink `json:"openTelemetry,omitempty"` -} - -type OpenTelemetrySink struct { - // Host define the service hostname. - Host string `json:"host"` - // Port defines the port the service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:validation:Maximum=65535 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` - - // TODO: add support for customizing OpenTelemetry sink in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto#envoy-v3-api-msg-extensions-stat-sinks-open-telemetry-v3-sinkconfig -} - -type PrometheusProvider struct { - // Disable the Prometheus endpoint. - Disable bool `json:"disable,omitempty"` -} -``` - -### Example - -- The following is an example to disable prometheus metric. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/metric/disable-prometheus.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: prometheus - namespace: envoy-gateway-system -spec: - telemetry: - metrics: - prometheus: - disable: true -``` - -- The following is an example to send metric via Open Telemetry sink. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/metric/otel-sink.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: otel-sink - namespace: envoy-gateway-system -spec: - telemetry: - metrics: - sinks: - - type: OpenTelemetry - openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 -``` - -[admin endpoint]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin -[Open Telemetry sink]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels diff --git a/site/content/en/v1.0.1/contributions/design/pprof.md b/site/content/en/v1.0.1/contributions/design/pprof.md deleted file mode 100644 index 40d75ea8f83..00000000000 --- a/site/content/en/v1.0.1/contributions/design/pprof.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: "Debug support in Envoy Gateway" ---- - -## Overview - -Envoy Gateway exposes endpoints at `localhost:19000/debug/pprof` to run Golang profiles to aid in live debugging. - -The endpoints are equivalent to those found in the http/pprof package. `/debug/pprof/` returns an HTML page listing the available profiles. - -## Goals - -* Add admin server to Envoy Gateway control plane, separated with admin server. -* Add pprof support to Envoy Gateway control plane. -* Define an API to allow Envoy Gateway to custom admin server configuration. -* Define an API to allow Envoy Gateway to open envoy gateway config dump in logs. - -The following are the different types of profiles end-user can run: - -PROFILE | FUNCTION --- | -- -/debug/pprof/allocs | Returns a sampling of all past memory allocations. -/debug/pprof/block | Returns stack traces of goroutines that led to blocking on synchronization primitives. -/debug/pprof/cmdline | Returns the command line that was invoked by the current program. -/debug/pprof/goroutine | Returns stack traces of all current goroutines. -/debug/pprof/heap | Returns a sampling of memory allocations of live objects. -/debug/pprof/mutex | Returns stack traces of goroutines holding contended mutexes. -/debug/pprof/profile | Returns pprof-formatted cpu profile. You can specify the duration using the seconds GET parameter. The default duration is 30 seconds. -/debug/pprof/symbol | Returns the program counters listed in the request. -/debug/pprof/threadcreate | Returns stack traces that led to creation of new OS threads. -/debug/pprof/trace | Returns the execution trace in binary form. You can specify the duration using the seconds GET parameter. The default duration is 1 second. - -## Non Goals - -## API - -* Add `admin` field in EnvoyGateway config. -* Add `address` field under `admin` field. -* Add `port` and `host` under `address` field. -* Add `enableDumpConfig` field under `admin field. -* Add `enablePprof` field under `admin field. - -Here is an example configuration to open admin server and enable Pprof: - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -gateway: - controllerName: "gateway.envoyproxy.io/gatewayclass-controller" -kind: EnvoyGateway -provider: - type: "Kubernetes" -admin: - enablePprof: true - address: - host: 127.0.0.1 - port: 19000 -``` - -Here is an example configuration to open envoy gateway config dump in logs: - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -gateway: - controllerName: "gateway.envoyproxy.io/gatewayclass-controller" -kind: EnvoyGateway -provider: - type: "Kubernetes" -admin: - enableDumpConfig: true -``` diff --git a/site/content/en/v1.0.1/contributions/design/rate-limit.md b/site/content/en/v1.0.1/contributions/design/rate-limit.md deleted file mode 100644 index 8dfda7680e8..00000000000 --- a/site/content/en/v1.0.1/contributions/design/rate-limit.md +++ /dev/null @@ -1,447 +0,0 @@ ---- -title: "Rate Limit Design" ---- - -## Overview - -Rate limit is a feature that allows the user to limit the number of incoming requests -to a predefined value based on attributes within the traffic flow. - -Here are some reasons why a user may want to implement Rate limits - -* To prevent malicious activity such as DDoS attacks. -* To prevent applications and its resources (such as a database) from getting overloaded. -* To create API limits based on user entitlements. - -## Scope Types - -The rate limit type here describes the scope of rate limits. - -* Global - In this case, the rate limit is common across all the instances of Envoy proxies -where its applied i.e. if the data plane has 2 replicas of Envoy running, and the rate limit is -10 requests/second, this limit is common and will be hit if 5 requests pass through the first replica -and 5 requests pass through the second replica within the same second. - -* Local - In this case, the rate limits are specific to each instance/replica of Envoy running. -Note - This is not part of the initial design and will be added as a future enhancement. - -## Match Types - -### Rate limit a specific traffic flow - -* Here is an example of a ratelimit implemented by the application developer to limit a specific user -by matching on a custom `x-user-id` header with a value set to `one` - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-specific-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - name: x-user-id - value: one - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-specific-user - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit all traffic flows - -* Here is an example of a rate limit implemented by the application developer that limits the total requests made -to a specific route to safeguard health of internal application components. In this case, no specific `headers` match -is specified, and the rate limit is applied to all traffic flows accepted by this `HTTPRoute`. - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-all-requests -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - limit: - requests: 1000 - unit: Second ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-all-requests - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit per distinct value - -* Here is an example of a rate limit implemented by the application developer to limit any unique user -by matching on a custom `x-user-id` header. Here, user A (recognised from the traffic flow using the header -`x-user-id` and value `a`) will be rate limited at 10 requests/hour and so will user B -(recognised from the traffic flow using the header `x-user-id` and value `b`). - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-per-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - type: Distinct - name: x-user-id - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-per-user - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit per source IP - -* Here is an example of a rate limit implemented by the application developer that limits the total requests made -to a specific route by matching on source IP. In this case, requests from `x.x.x.x` will be rate limited at 10 requests/hour. - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-per-ip -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - sourceIP: x.x.x.x/32 - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-per-user - backendRefs: - - name: backend - port: 3000 -``` - -### Rate limit based on JWT claims - -* Here is an example of rate limit implemented by the application developer that limits the total requests made -to a specific route by matching on the jwt claim. In this case, requests with jwt claim information of `{"name":"John Doe"}` -will be rate limited at 10 requests/hour. - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: SecurityPolicy -metadata: - name: jwt-example -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - jwt: - providers: - - name: example - remoteJWKS: - uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json - claimToHeaders: - - claim: name - header: custom-request-header ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-specific-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - name: custom-request-header - value: John Doe - limit: - requests: 10 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - "www.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: backend - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: /foo -``` - - -## Multiple RateLimitFilters, rules and clientSelectors -* Users can create multiple `RateLimitFilter`s and apply it to the same `HTTPRoute`. In such a case each -`RateLimitFilter` will be applied to the route and matched (and limited) in a mutually exclusive way, independent of each other. -* Rate limits are applied for each `RateLimitFilter` `rule` when ALL the conditions under `clientSelectors` hold true. - -Here's an example highlighting this - - -```yaml -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-all-safeguard-app -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - limit: - requests: 100 - unit: Hour ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: BackendTrafficPolicy -metadata: - name: ratelimit-per-user -spec: - targetRef: - group: gateway.networking.k8s.io - kind: HTTPRoute - name: example - rateLimit: - type: Global - global: - rules: - - clientSelectors: - - headers: - - type: Distinct - name: x-user-id - limit: - requests: 100 - unit: Hour ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-per-user - - type: ExtensionRef - extensionRef: - group: gateway.envoyproxy.io - kind: RateLimitFilter - name: ratelimit-all-safeguard-app - backendRefs: - - name: backend - port: 3000 -``` - -* The user has created two `RateLimitFilter`s and has attached it to a `HTTPRoute` - one(`ratelimit-all-safeguard-app`) to -ensure that the backend does not get overwhelmed with requests, any excess requests are rate limited irrespective of -the attributes within the traffic flow, and another(`ratelimit-per-user`) to rate limit each distinct user client -who can be differentiated using the `x-user-id` header, to ensure that each client does not make exessive requests to the backend. -* If user `baz` (identified with the header and value of `x-user-id: baz`) sends 90 requests within the first second, and -user `bar` sends 11 more requests during that same interval of 1 second, and user `bar` sends the 101th request within that second, -the rule defined in `ratelimit-all-safeguard-app` gets activated and Envoy Gateway will ratelimit the request sent by `bar` (and any other -request sent within that 1 second). After 1 second, the rate limit counter associated with the `ratelimit-all-safeguard-app` rule -is reset and again evaluated. -* If user `bar` also ends up sending 90 more requests within the hour, summing up `bar`'s total request count to 101, the rate limit rule -defined within `ratelimit-per-user` will get activated, and `bar`'s requests will be rate limited again until the hour interval ends. -* Within the same above hour, if `baz` sends 991 more requests, summing up `baz`'s total request count to 1001, the rate limit rule defined -within `ratelimit-per-user` will get activated for `baz`, and `baz`'s requests will also be rate limited until the hour interval ends. - -## Design Decisions - -* The initial design uses an Extension filter to apply the Rate Limit functionality on a specific [HTTPRoute][]. -This was preferred over the [PolicyAttachment][] extension mechanism, because it is unclear whether Rate Limit -will be required to be enforced or overridden by the platform administrator or not. -* The RateLimitFilter can only be applied as a filter to a [HTTPRouteRule][], applying it across all backends within a [HTTPRoute][] -and cannot be applied a filter within a [HTTPBackendRef][] for a specific backend. -* The [HTTPRoute][] API has a [matches][] field within each [rule][] to select a specific traffic flow to be routed to -the destination backend. The RateLimitFilter API that can be attached to an HTTPRoute via an [extensionRef][] filter, -also has a `clientSelectors` field within each `rule` to select attributes within the traffic flow to rate limit specific clients. -The two levels of selectors/matches allow for flexibility and aim to hold match information specific to its use, allowing the author/owner -of each configuration to be different. It also allows the `clientSelectors` field within the RateLimitFilter to be enhanced with other matchable -attribute such as [IP subnet][] in the future that are not relevant in the [HTTPRoute][] API. - -## Implementation Details - -### Global Rate limiting - -* [Global rate limiting][] in Envoy Proxy can be achieved using the following - - * [Actions][] can be configured per [xDS Route][]. - * If the match criteria defined within these actions is met for a specific HTTP Request, a set of key value pairs called [descriptors][] - defined within the above actions is sent to a remote [rate limit service][], whose configuration (such as the URL for the rate limit service) is defined - using a [rate limit filter][]. - * Based on information received by the rate limit service and its programmed configuration, a decision is computed, whether to rate limit - the HTTP Request or not, and is sent back to Envoy, which enforces this decision on the data plane. -* Envoy Gateway will leverage this Envoy Proxy feature by - - * Translating the user facing RateLimitFilter API into Rate limit [Actions][] as well as Rate limit service configuration to implement - the desired API intent. - * Envoy Gateway will use the existing [reference implementation][] of the rate limit service. - * The Infrastructure administrator will need to enable the rate limit service using new settings that will be defined in the [EnvoyGateway][] config API. - * The xDS IR will be enhanced to hold the user facing rate limit intent. - * The xDS Translator will be enhanced to translate the rate limit field within the xDS IR into Rate limit [Actions][] as well as instantiate the [rate limit filter][]. - * A new runner called `rate-limit` will be added that subscribes to the xDS IR messages and translates it into a new Rate Limit Infra IR which contains - the [rate limit service configuration][] as well as other information needed to deploy the rate limit service. - * The infrastructure service will be enhanced to subscribe to the Rate Limit Infra IR and deploy a provider specific rate limit service runnable entity. - * A Status field within the RateLimitFilter API will be added to reflect whether the specific configuration was programmed correctly in these multiple locations or not. - -[PolicyAttachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment/ -[HTTPRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute -[HTTPRouteRule]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteRule -[HTTPBackendRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPBackendRef -[matches]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteMatch -[rule]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteMatch -[extensionRef]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilterType -[IP subnet]: https://en.wikipedia.org/wiki/Subnetwork -[Actions]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-ratelimit-action -[descriptors]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter.html?highlight=descriptor#example-1 -[Global rate limiting]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting -[xDS Route]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-routeaction -[rate limit filter]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ratelimit/v3/rate_limit.proto#envoy-v3-api-msg-extensions-filters-http-ratelimit-v3-ratelimit -[rate limit service]: https://www.envoyproxy.io/docs/envoy/latest/configuration/other_features/rate_limit#config-rate-limit-service -[reference implementation]: https://github.com/envoyproxy/ratelimit -[EnvoyGateway]: https://github.com/envoyproxy/gateway/blob/main/api/v1alpha1/envoygateway_types.go -[rate limit service configuration]: https://github.com/envoyproxy/ratelimit#configuration diff --git a/site/content/en/v1.0.1/contributions/design/security-policy.md b/site/content/en/v1.0.1/contributions/design/security-policy.md deleted file mode 100644 index b39165feb03..00000000000 --- a/site/content/en/v1.0.1/contributions/design/security-policy.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: "SecurityPolicy " ---- - -## Overview - -This design document introduces the `SecurityPolicy` API allowing system administrators to configure -authentication and authorization policies to the traffic entering the gateway. - -## Goals -* Add an API definition to hold settings for configuring authentication and authorization rules -on the traffic entering the gateway. - -## Non Goals -* Define the API configuration fields in this API. - -## Implementation -`SecurityPolicy` is a [Policy Attachment][] type API that can be used to extend [Gateway API][] -to define authentication and authorization rules. - -### Example -Here is an example highlighting how a user can configure this API. - -``` -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: eg -spec: - controllerName: gateway.envoyproxy.io/gatewayclass-controller ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: eg - namespace: default -spec: - gatewayClassName: eg - listeners: - - name: https - protocol: HTTPS - port: 443 ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: backend - namespace: default -spec: - parentRefs: - - name: eg - hostnames: - - "www.example.com" - rules: - - backendRefs: - - group: "" - kind: Service - name: backend - port: 3000 - weight: 1 - matches: - - path: - type: PathPrefix - value: / ---- -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: SecurityPolicy -metadata: - name: jwt-authn-policy - namespace: default -spec: - jwt: - providers: - - name: example - remoteJWKS: - uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json - targetRef: - group: gateway.networking.k8s.io - kind: Gateway - name: eg - namespace: default -``` - -## Features / API Fields -Here is a list of features that can be included in this API -* JWT based authentication -* OIDC Authentication -* External Authorization -* Basic Auth -* API Key Auth -* CORS - -## Design Decisions -* This API will only support a single `targetRef` and can bind to a `Gateway` resource or a `HTTPRoute` or `GRPCRoute`. -* This API resource MUST be part of same namespace as the targetRef resource -* There can be only be ONE policy resource attached to a specific targetRef e.g. a `Listener` (section) within a `Gateway` -* If the policy targets a resource but cannot attach to it, this information should be reflected -in the Policy Status field using the `Conflicted=True` condition. -* If multiple polices target the same resource, the oldest resource (based on creation timestamp) will -attach to the Gateway Listeners, the others will not. -* If Policy A has a `targetRef` that includes a `sectionName` i.e. -it targets a specific Listener within a `Gateway` and Policy B has a `targetRef` that targets the same -entire Gateway then - * Policy A will be applied/attached to the specific Listener defined in the `targetRef.SectionName` - * Policy B will be applied to the remaining Listeners within the Gateway. Policy B will have an additional - status condition `Overridden=True`. -* A Policy targeting the most specific scope wins over a policy targeting a lesser specific scope. - i.e. A Policy targeting a xRoute (`HTTPRoute` or `GRPCRoute`) overrides a Policy targeting a Listener that is -this route's parentRef which in turn overrides a Policy targeting the Gateway the listener/section is a part of. - -## Alternatives -* The project can indefinitely wait for these configuration parameters to be part of the [Gateway API][]. - -[Policy Attachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment -[Gateway API]: https://gateway-api.sigs.k8s.io/ diff --git a/site/content/en/v1.0.1/contributions/design/system-design.md b/site/content/en/v1.0.1/contributions/design/system-design.md deleted file mode 100644 index fe24f628f9d..00000000000 --- a/site/content/en/v1.0.1/contributions/design/system-design.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -title: "System Design" -weight: 2 ---- - -## Goals - -* Define the system components needed to satisfy the requirements of Envoy Gateway. - -## Non-Goals - -* Create a detailed design and interface specification for each system component. - -## Terminology - -* Control Plane- A collection of inter-related software components for providing application gateway and routing - functionality. The control plane is implemented by Envoy Gateway and provides services for managing the data plane. - These services are detailed in the [components](#components) section. -* Data Plane- Provides intelligent application-level traffic routing and is implemented as one or more Envoy proxies. - -## Architecture - -![Architecture](/img/architecture.png) - -## Configuration - -Envoy Gateway is configured statically at startup and the managed data plane is configured dynamically through -Kubernetes resources, primarily [Gateway API][gw_api] objects. - -### Static Configuration - -Static configuration is used to configure Envoy Gateway at startup, i.e. change the GatewayClass controllerName, -configure a Provider, etc. Currently, Envoy Gateway only supports configuration through a configuration file. If the -configuration file is not provided, Envoy Gateway starts-up with default configuration parameters. - -### Dynamic Configuration - -Dynamic configuration is based on the concept of a declaring the desired state of the data plane and using -reconciliation loops to drive the actual state toward the desired state. The desired state of the data plane is -defined as Kubernetes resources that provide the following services: - -* Infrastructure Management- Manage the data plane infrastructure, i.e. deploy, upgrade, etc. This configuration is - expressed through [GatewayClass][gc] and [Gateway][gw] resources. The `EnvoyProxy` [Custom Resource][cr] can be - referenced by `gatewayclass.spec.parametersRef` to modify data plane infrastructure default parameters, - e.g. expose Envoy network endpoints using a `ClusterIP` service instead of a `LoadBalancer` service. -* Traffic Routing- Define how to handle application-level requests to backend services. For example, route all HTTP - requests for "www.example.com" to a backend service running a web server. This configuration is expressed through - [HTTPRoute][hroute] and [TLSRoute][troute] resources that match, filter, and route traffic to a [backend][be]. - Although a backend can be any valid Kubernetes Group/Kind resource, Envoy Gateway only supports a [Service][svc] - reference. - -## Components - -Envoy Gateway is made up of several components that communicate in-process; how this communication happens is described -in the [Watching Components Design][wcd]. - -### Provider - -A Provider is an infrastructure component that Envoy Gateway calls to establish its runtime configuration, resolve -services, persist data, etc. As of v0.2, Kubernetes is the only implemented provider. A file provider is on the roadmap -via [Issue #37][]. Other providers can be added in the future as Envoy Gateway use cases are better understood. A -provider is configured at start up through Envoy Gateway's [static configuration](#static-configuration). - -#### Kubernetes Provider - -* Uses Kubernetes-style controllers to reconcile Kubernetes resources that comprise the - [dynamic configuration](#dynamic-configuration). -* Manages the data plane through Kubernetes API CRUD operations. -* Uses Kubernetes for Service discovery. -* Uses etcd (via Kubernetes API) to persist data. - -#### File Provider - -* Uses a file watcher to watch files in a directory that define the data plane configuration. -* Manages the data plane by calling internal APIs, e.g. `CreateDataPlane()`. -* Uses the host's DNS for Service discovery. -* If needed, the local filesystem is used to persist data. - -### Resource Watcher - -The Resource Watcher watches resources used to establish and maintain Envoy Gateway's dynamic configuration. The -mechanics for watching resources is provider-specific, e.g. informers, caches, etc. are used for the Kubernetes -provider. The Resource Watcher uses the configured provider for input and provides resources to the Resource Translator -as output. - -### Resource Translator - -The Resource Translator translates external resources, e.g. GatewayClass, from the Resource Watcher to the Intermediate -Representation (IR). It is responsible for: - -* Translating infrastructure-specific resources/fields from the Resource Watcher to the Infra IR. -* Translating proxy configuration resources/fields from the Resource Watcher to the xDS IR. - -__Note:__ The Resource Translator is implemented as the `Translator` API type in the `gatewayapi` package. - -### Intermediate Representation (IR) - -The Intermediate Representation defines internal data models that external resources are translated into. This allows -Envoy Gateway to be decoupled from the external resources used for dynamic configuration. The IR consists of an Infra IR -used as input for the Infra Manager and an xDS IR used as input for the xDS Translator. - -* Infra IR- Used as the internal definition of the managed data plane infrastructure. -* xDS IR- Used as the internal definition of the managed data plane xDS configuration. - -### xDS Translator - -The xDS Translator translates the xDS IR into xDS Resources that are consumed by the xDS server. - -### xDS Server - -The xDS Server is a xDS gRPC Server based on [Go Control Plane][go_cp]. Go Control Plane implements the Delta xDS Server -Protocol and is responsible for using xDS to configure the data plane. - -### Infra Manager - -The Infra Manager is a provider-specific component responsible for managing the following infrastructure: - -* Data Plane - Manages all the infrastructure required to run the managed Envoy proxies. For example, CRUD Deployment, - Service, etc. resources to run Envoy in a Kubernetes cluster. -* Auxiliary Control Planes - Optional infrastructure needed to implement application Gateway features that require - external integrations with the managed Envoy proxies. For example, [Global Rate Limiting][grl] requires provisioning - and configuring the [Envoy Rate Limit Service][rls] and the [Rate Limit filter][rlf]. Such features are exposed to - users through the [Custom Route Filters][crf] extension. - -The Infra Manager consumes the Infra IR as input to manage the data plane infrastructure. - -## Design Decisions - -* Envoy Gateway can consume multiple [GatewayClass][gc] by comparing its configured controller name with - `spec.controllerName` of a GatewayClass. - `gatewayclass.spec.parametersRef` refers to the `EnvoyProxy` custom resource for configuring the managed proxy - infrastructure. If unspecified, default configuration parameters are used for the managed proxy infrastructure. -* Envoy Gateway manages [Gateways][gw] that reference its GatewayClass. - * A Gateway resource causes Envoy Gateway to provision managed Envoy proxy infrastructure. - * Envoy Gateway groups Listeners by Port and collapses each group of Listeners into a single Listener if the Listeners - in the group are compatible. Envoy Gateway considers Listeners to be compatible if all the following conditions are - met: - * Either each Listener within the group specifies the “HTTP” Protocol or each Listener within the group specifies - either the “HTTPS” or “TLS” Protocol. - * Each Listener within the group specifies a unique "Hostname". - * As a special case, one Listener within a group may omit "Hostname", in which case this Listener matches when no - other Listener matches. - * Envoy Gateway does __not__ merge listeners across multiple Gateways. -* Envoy Gateway follows Gateway API [guidelines][gwapi_conflicts] to resolve any conflicts. - * A Gateway `listener` corresponds to an Envoy proxy [Listener][listener]. -* An [HTTPRoute][hroute] resource corresponds to an Envoy proxy [Route][route]. - * Each [backendRef][be_ref] corresponds to an Envoy proxy [Cluster][cluster]. -* The goal is to make Envoy Gateway components extensible in the future. See the [roadmap][] for additional details. - -The draft for this document is [here][draft_design]. - -[gw_api]: https://gateway-api.sigs.k8s.io -[gc]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#gatewayclass -[gw]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#gateway -[hroute]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#httproute -[troute]: https://gateway-api.sigs.k8s.io/concepts/api-overview/#tlsroute -[go_cp]: https://github.com/envoyproxy/go-control-plane -[grl]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/global_rate_limiting -[rls]: https://github.com/envoyproxy/ratelimit -[rlf]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ratelimit/v3/rate_limit.proto#envoy-v3-api-msg-extensions-filters-http-ratelimit-v3-ratelimit -[crf]: https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional -[gwapi_conflicts]: https://gateway-api.sigs.k8s.io/concepts/guidelines/#conflicts -[listener]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/listeners#config-listeners -[route]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-route -[be_ref]: https://gateway-api.sigs.k8s.io/api-types/httproute/#backendrefs-optional -[cluster]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster -[draft_design]: https://docs.google.com/document/d/1riyTPPYuvNzIhBdrAX8dpfxTmcobWZDSYTTB5NeybuY/edit -[cr]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ -[be]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.BackendObjectReference -[svc]: https://kubernetes.io/docs/concepts/services-networking/service/ -[wcd]: ../watching -[Issue #37]: https://github.com/envoyproxy/gateway/issues/37 -[roadmap]: ../../contributions/roadmap/ diff --git a/site/content/en/v1.0.1/contributions/design/tcp-udp-design.md b/site/content/en/v1.0.1/contributions/design/tcp-udp-design.md deleted file mode 100644 index 8dc29830164..00000000000 --- a/site/content/en/v1.0.1/contributions/design/tcp-udp-design.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "TCP and UDP Proxy Design " ---- - -Even though most of the use cases for Envoy Gateway are at Layer-7, Envoy Gateway can also work at Layer-4 to proxy TCP -and UDP traffic. This document will explore the options we have when operating Envoy Gateway at Layer-4 and explain the -design decision. - -Envoy can work as a non-transparent proxy or a transparent proxy for both [TCP][] - and [UDP][] -, so ideally, Envoy Gateway should also be able to work in these two modes: - -## Non-transparent Proxy Mode -For TCP, Envoy terminates the downstream connection, connects the upstream with its own IP address, and proxies the -TCP traffic from the downstream to the upstream. - -For UDP, Envoy receives UDP datagrams from the downstream, and uses its own IP address as the sender IP address when -proxying the UDP datagrams to the upstream. - -In this mode, the upstream will see Envoy's IP address and port. - -## Transparent Proxy Mode -For TCP, Envoy terminates the downstream connection, connects the upstream with the downstream IP address, and proxies -the TCP traffic from the downstream to the upstream. - -For UDP, Envoy receives UDP datagrams from the downstream, and uses the downstream IP address as the sender IP address -when proxying the UDP datagrams to the upstream. - -In this mode, the upstream will see the original downstream IP address and Envoy's mac address. - -Note: Even in transparent mode, the upstream can't see the port number of the downstream because Envoy doesn't forward -the port number. - -## The Implications of Transparent Proxy Mode - -### Escalated Privilege -Envoy needs to bind to the downstream IP when connecting to the upstream, which means Envoy requires escalated -CAP_NET_ADMIN privileges. This is often considered as a bad security practice and not allowed in some sensitive deployments. - -### Routing -The upstream can see the original source IP, but the original port number won't be passed, so the return -traffic from the upstream must be routed back to Envoy because only Envoy knows how to send the return traffic back -to the right port number of the downstream, which requires routing at the upstream side to be set up. -In a Kubernetes cluster, Envoy Gateway will have to carefully cooperate with CNI plugins to get the routing right. - -## The Design Decision (For Now) - -The implementation will only support proxying in non-transparent mode i.e. the backend will see the source IP and -port of the deployed Envoy instance instead of the client. - -[TCP]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_features/ip_transparency#arch-overview-ip-transparency-original-src-listener -[UDP]: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto#envoy-v3-api-msg-extensions-filters-udp-udp-proxy-v3-udpproxyconfig diff --git a/site/content/en/v1.0.1/contributions/design/tracing.md b/site/content/en/v1.0.1/contributions/design/tracing.md deleted file mode 100644 index a2790690fa6..00000000000 --- a/site/content/en/v1.0.1/contributions/design/tracing.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: "Observability: Tracing" ---- - -## Overview - -Envoy supports extensible tracing to different sinks, Zipkin, OpenTelemetry etc. Overview of Envoy tracing can be found [here][tracing]. - -Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementers such as Envoy Gateway to expose features. Since tracing is not covered by `Core` or `Extended` APIs, EG should provide an easy to config tracing per `EnvoyProxy`. - -Only OpenTelemetry sink can be configured currently, you can use [OpenTelemetry Collector][] to export to other tracing backends. - -## Goals - -- Support send tracing to `OpenTelemetry` backend -- Support configurable sampling rate -- Support propagate tag from `Literal`, `Environment` and `Request Header` - -## Non-Goals - -- Support other tracing backend, e.g. `Zipkin`, `Jaeger` - -## Use-Cases - -- Configure accesslog for a `EnvoyProxy` to `File` - -### ProxyAccessLog API Type - -```golang mdox-exec="sed '1,7d' api/config/v1alpha1/tracing_types.go" -type ProxyTracing struct { - // SamplingRate controls the rate at which traffic will be - // selected for tracing if no prior sampling decision has been made. - // Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:validation:Maximum=100 - // +kubebuilder:default=100 - // +optional - SamplingRate *uint32 `json:"samplingRate,omitempty"` - // CustomTags defines the custom tags to add to each span. - // If provider is kubernetes, pod name and namespace are added by default. - CustomTags map[string]CustomTag `json:"customTags,omitempty"` - // Provider defines the tracing provider. - // Only OpenTelemetry is supported currently. - Provider TracingProvider `json:"provider"` -} - -type TracingProviderType string - -const ( - TracingProviderTypeOpenTelemetry TracingProviderType = "OpenTelemetry" -) - -type TracingProvider struct { - // Type defines the tracing provider type. - // EG currently only supports OpenTelemetry. - // +kubebuilder:validation:Enum=OpenTelemetry - // +kubebuilder:default=OpenTelemetry - Type TracingProviderType `json:"type"` - // Host define the provider service hostname. - Host string `json:"host"` - // Port defines the port the provider service is exposed on. - // - // +optional - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:default=4317 - Port int32 `json:"port,omitempty"` -} - -type CustomTagType string - -const ( - // CustomTagTypeLiteral adds hard-coded value to each span. - CustomTagTypeLiteral CustomTagType = "Literal" - // CustomTagTypeEnvironment adds value from environment variable to each span. - CustomTagTypeEnvironment CustomTagType = "Environment" - // CustomTagTypeRequestHeader adds value from request header to each span. - CustomTagTypeRequestHeader CustomTagType = "RequestHeader" -) - -type CustomTag struct { - // Type defines the type of custom tag. - // +kubebuilder:validation:Enum=Literal;Environment;RequestHeader - // +unionDiscriminator - // +kubebuilder:default=Literal - Type CustomTagType `json:"type"` - // Literal adds hard-coded value to each span. - // It's required when the type is "Literal". - Literal *LiteralCustomTag `json:"literal,omitempty"` - // Environment adds value from environment variable to each span. - // It's required when the type is "Environment". - Environment *EnvironmentCustomTag `json:"environment,omitempty"` - // RequestHeader adds value from request header to each span. - // It's required when the type is "RequestHeader". - RequestHeader *RequestHeaderCustomTag `json:"requestHeader,omitempty"` - - // TODO: add support for Metadata tags in the future. - // EG currently doesn't support metadata for route or cluster. -} - -// LiteralCustomTag adds hard-coded value to each span. -type LiteralCustomTag struct { - // Value defines the hard-coded value to add to each span. - Value string `json:"value"` -} - -// EnvironmentCustomTag adds value from environment variable to each span. -type EnvironmentCustomTag struct { - // Name defines the name of the environment variable which to extract the value from. - Name string `json:"name"` - // DefaultValue defines the default value to use if the environment variable is not set. - // +optional - DefaultValue *string `json:"defaultValue,omitempty"` -} - -// RequestHeaderCustomTag adds value from request header to each span. -type RequestHeaderCustomTag struct { - // Name defines the name of the request header which to extract the value from. - Name string `json:"name"` - // DefaultValue defines the default value to use if the request header is not set. - // +optional - DefaultValue *string `json:"defaultValue,omitempty"` -} -``` - -### Example - -1. The following is an example to config tracing. - -```yaml mdox-exec="sed '1,12d' examples/kubernetes/tracing/default.yaml" -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: EnvoyProxy -metadata: - name: tracing - namespace: envoy-gateway-system -spec: - telemetry: - tracing: - # sample 100% of requests - samplingRate: 100 - provider: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 - customTags: - # This is an example of using a literal as a tag value - key1: - type: Literal - literal: - value: "val1" - # This is an example of using an environment variable as a tag value - env1: - type: Environment - environment: - name: ENV1 - defaultValue: "-" - # This is an example of using a header value as a tag value - header1: - type: RequestHeader - requestHeader: - name: X-Header-1 - defaultValue: "-" -``` - -[tracing]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/tracing -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels -[OpenTelemetry Collector]: https://opentelemetry.io/docs/collector/ diff --git a/site/content/en/v1.0.1/contributions/design/watching.md b/site/content/en/v1.0.1/contributions/design/watching.md deleted file mode 100644 index 5eabad7b3f9..00000000000 --- a/site/content/en/v1.0.1/contributions/design/watching.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "Watching Components Design" -weight: 3 ---- - -Envoy Gateway is made up of several components that communicate in-process. Some of them (namely Providers) watch -external resources, and "publish" what they see for other components to consume; others watch what another publishes and -act on it (such as the resource translator watches what the providers publish, and then publishes its own results that -are watched by another component). Some of these internally published results are consumed by multiple components. - -To facilitate this communication use the [watchable][] library. The `watchable.Map` type is very similar to the -standard library's `sync.Map` type, but supports a `.Subscribe` (and `.SubscribeSubset`) method that promotes a pub/sub -pattern. - -## Pub - -Many of the things we communicate around are naturally named, either by a bare "name" string or by a "name"/"namespace" -tuple. And because `watchable.Map` is typed, it makes sense to have one map for each type of thing (very similar to if -we were using native Go `map`s). For example, a struct that might be written to by the Kubernetes provider, and read by -the IR translator: - - ```go - type ResourceTable struct { - // gateway classes are cluster-scoped; no namespace - GatewayClasses watchable.Map[string, *gwapiv1.GatewayClass] - - // gateways are namespace-scoped, so use a k8s.io/apimachinery/pkg/types.NamespacedName as the map key. - Gateways watchable.Map[types.NamespacedName, *gwapiv1.Gateway] - - HTTPRoutes watchable.Map[types.NamespacedName, *gwapiv1.HTTPRoute] - } - ``` - -The Kubernetes provider updates the table by calling `table.Thing.Store(name, val)` and `table.Thing.Delete(name)`; -updating a map key with a value that is deep-equal (usually `reflect.DeepEqual`, but you can implement your own `.Equal` -method) the current value is a no-op; it won't trigger an event for subscribers. This is handy so that the publisher -doesn't have as much state to keep track of; it doesn't need to know "did I already publish this thing", it can just -`.Store` its data and `watchable` will do the right thing. - -## Sub - -Meanwhile, the translator and other interested components subscribe to it with `table.Thing.Subscribe` (or -`table.Thing.SubscribeSubset` if they only care about a few "Thing"s). So the translator goroutine might look like: - - ```go - func(ctx context.Context) error { - for snapshot := range k8sTable.HTTPRoutes.Subscribe(ctx) { - fullState := irInput{ - GatewayClasses: k8sTable.GatewayClasses.LoadAll(), - Gateways: k8sTable.Gateways.LoadAll(), - HTTPRoutes: snapshot.State, - } - translate(irInput) - } - } - ``` - -Or, to watch multiple maps in the same loop: - - ```go - func worker(ctx context.Context) error { - classCh := k8sTable.GatewayClasses.Subscribe(ctx) - gwCh := k8sTable.Gateways.Subscribe(ctx) - routeCh := k8sTable.HTTPRoutes.Subscribe(ctx) - for ctx.Err() == nil { - var arg irInput - select { - case snapshot := <-classCh: - arg.GatewayClasses = snapshot.State - case snapshot := <-gwCh: - arg.Gateways = snapshot.State - case snapshot := <-routeCh: - arg.Routes = snapshot.State - } - if arg.GateWayClasses == nil { - arg.GatewayClasses = k8sTable.GateWayClasses.LoadAll() - } - if arg.GateWays == nil { - arg.Gateways = k8sTable.GateWays.LoadAll() - } - if arg.HTTPRoutes == nil { - arg.HTTPRoutes = k8sTable.HTTPRoutes.LoadAll() - } - translate(irInput) - } - } - ``` - -From the updates it gets from `.Subscribe`, it can get a full view of the map being subscribed to via `snapshot.State`; -but it must read the other maps explicitly. Like `sync.Map`, `watchable.Map`s are thread-safe; while `.Subscribe` is a -handy way to know when to run, `.Load` and friends can be used without subscribing. - -There can be any number of subscribers. For that matter, there can be any number of publishers `.Store`ing things, but -it's probably wise to just have one publisher for each map. - -The channel returned from `.Subscribe` **is immediately readable** with a snapshot of the map as it existed when -`.Subscribe` was called; and becomes readable again whenever `.Store` or `.Delete` mutates the map. If multiple -mutations happen between reads (or if mutations happen between `.Subscribe` and the first read), they are coalesced in -to one snapshot to be read; the `snapshot.State` is the most-recent full state, and `snapshot.Updates` is a listing of -each of the mutations that cause this snapshot to be different than the last-read one. This way subscribers don't need -to worry about a backlog accumulating if they can't keep up with the rate of changes from the publisher. - -If the map contains anything before `.Subscribe` is called, that very first read won't include `snapshot.Updates` -entries for those pre-existing items; if you are working with `snapshot.Update` instead of `snapshot.State`, then you -must add special handling for your first read. We have a utility function `./internal/message.HandleSubscription` to -help with this. - -## Other Notes - -The common pattern will likely be that the entrypoint that launches the goroutines for each component instantiates the -map, and passes them to the appropriate publishers and subscribers; same as if they were communicating via a dumb -`chan`. - -A limitation of `watchable.Map` is that in order to ensure safety between goroutines, it does require that value types -be deep-copiable; either by having a `DeepCopy` method, being a `proto.Message`, or by containing no reference types and -so can be deep-copied by naive assignment. Fortunately, we're using `controller-gen` anyway, and `controller-gen` can -generate `DeepCopy` methods for us: just stick a `// +k8s:deepcopy-gen=true` on the types that you want it to generate -methods for. - -[watchable]: https://pkg.go.dev/github.com/telepresenceio/watchable diff --git a/site/content/en/v1.0.1/contributions/roadmap.md b/site/content/en/v1.0.1/contributions/roadmap.md deleted file mode 100644 index 955af2a9623..00000000000 --- a/site/content/en/v1.0.1/contributions/roadmap.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Roadmap" -weight: -1 -description: "This section records the roadmap of Envoy Gateway." ---- - -This document serves as a high-level reference for Envoy Gateway users and contributors to understand the direction of -the project. - -## Contributing to the Roadmap - -- To add a feature to the roadmap, create an [issue][issue] or join a [community meeting][meeting] to discuss your use - case. If your feature is accepted, a maintainer will assign your issue to a [release milestone][milestones] and update - this document accordingly. -- To help with an existing roadmap item, comment on or assign yourself to the associated issue. -- If a roadmap item doesn't have an issue, create one, assign yourself to the issue, and reference this document. A - maintainer will submit a [pull request][PR] to add the feature to the roadmap. __Note:__ The feature should be - discussed in an issue or a community meeting before implementing it. - -If you don't know where to start contributing, help is needed to reduce technical, automation, and documentation debt. -Look for issues with the `help wanted` label to get started. - -## Details - -Roadmap features and timelines may change based on feedback, community contributions, etc. If you depend on a specific -roadmap item, you're encouraged to attend a community meeting to discuss the details, or help us deliver the feature by -contributing to the project. - -`Last Updated: April 2023` - -### [v0.2.0][v0.2.0]: Establish a Solid Foundation - -- Complete the core Envoy Gateway implementation- [Issue #60][60]. -- Establish initial testing, e2e, integration, etc- [Issue #64][64]. -- Establish user and developer project documentation- [Issue #17][17]. -- Achieve Gateway API conformance (e.g. routing, LB, Header transformation, etc.)- [Issue #65][65]. -- Setup a CI/CD pipeline- [Issue #63][63]. - -### [v0.3.0][v0.3.0]: Drive Advanced Features through Extension Mechanisms - -- Support extended Gateway API fields [Issue #707][707]. -- Support experimental Gateway APIs such as TCPRoute [Issue #643][643], UDPRoute [Issue #641][641] and GRPCRoute [Issue #642][642]. -- Establish guidelines for leveragaing Gateway API extensions [Issue #675][675]. -- Rate Limiting [Issue #670][670]. -- Authentication [Issue #336][336]. - -### [v0.4.0][v0.4.0]: Customizing Envoy Gateway - -- Extending Envoy Gateway control plane [Issue #20][20] -- Helm based installation for Envoy Gateway [Issue #650][650] -- Customizing managed Envoy Proxy Kubernetes resource fields [Issue #648][648] -- Configuring xDS Bootstrap [Issue #31][31] - -### [v0.5.0][v0.5.0]: Observability and Scale - -- Observability for data plane [Issue #699][699]. -- Allow users to configure xDS Resources [Issue #24][24]. - -### [v0.6.0][v0.6.0]: Preparation for GA - -- Observability for control plane [Issue #700][700]. -- Compute and document Envoy Gateway performance [Issue #1365][1365]. -- Add TrafficPolicy APIs for advanced features [Issue #1492][1492]. -- Envoy Gateway meets readiness criteria [Issue #1160][1160]. - -[issue]: https://github.com/envoyproxy/gateway/issues -[meeting]: https://docs.google.com/document/d/1leqwsHX8N-XxNEyTflYjRur462ukFxd19Rnk3Uzy55I/edit?usp=sharing -[pr]: https://github.com/envoyproxy/gateway/compare -[milestones]: https://github.com/envoyproxy/gateway/milestones -[v0.2.0]: https://github.com/envoyproxy/gateway/milestone/1 -[v0.3.0]: https://github.com/envoyproxy/gateway/milestone/7 -[v0.4.0]: https://github.com/envoyproxy/gateway/milestone/12 -[v0.5.0]: https://github.com/envoyproxy/gateway/milestone/13 -[v0.6.0]: https://github.com/envoyproxy/gateway/milestone/15 -[17]: https://github.com/envoyproxy/gateway/issues/17 -[20]: https://github.com/envoyproxy/gateway/issues/20 -[24]: https://github.com/envoyproxy/gateway/issues/24 -[31]: https://github.com/envoyproxy/gateway/issues/31 -[60]: https://github.com/envoyproxy/gateway/issues/60 -[63]: https://github.com/envoyproxy/gateway/issues/63 -[64]: https://github.com/envoyproxy/gateway/issues/64 -[65]: https://github.com/envoyproxy/gateway/issues/65 -[336]: https://github.com/envoyproxy/gateway/issues/336 -[641]: https://github.com/envoyproxy/gateway/issues/641 -[642]: https://github.com/envoyproxy/gateway/issues/642 -[648]: https://github.com/envoyproxy/gateway/issues/648 -[650]: https://github.com/envoyproxy/gateway/issues/650 -[643]: https://github.com/envoyproxy/gateway/issues/643 -[670]: https://github.com/envoyproxy/gateway/issues/670 -[675]: https://github.com/envoyproxy/gateway/issues/675 -[699]: https://github.com/envoyproxy/gateway/issues/699 -[700]: https://github.com/envoyproxy/gateway/issues/700 -[707]: https://github.com/envoyproxy/gateway/issues/707 -[1160]: https://github.com/envoyproxy/gateway/issues/1160 -[1365]: https://github.com/envoyproxy/gateway/issues/1365 -[1492]: https://github.com/envoyproxy/gateway/issues/1492 diff --git a/site/content/en/v1.0.1/install/install-helm.md b/site/content/en/v1.0.1/install/install-helm.md index 908eaf3eb8f..bb26969b722 100644 --- a/site/content/en/v1.0.1/install/install-helm.md +++ b/site/content/en/v1.0.1/install/install-helm.md @@ -28,7 +28,7 @@ You can visit [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gat Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} Install the Gateway API CRDs and Envoy Gateway: diff --git a/site/content/en/v1.0.1/install/install-yaml.md b/site/content/en/v1.0.1/install/install-yaml.md index 177ede14889..e00107fbe2e 100644 --- a/site/content/en/v1.0.1/install/install-yaml.md +++ b/site/content/en/v1.0.1/install/install-yaml.md @@ -25,7 +25,7 @@ Refer to the [Version Compatibility Matrix](./matrix) to learn more. Envoy Gateway is typically deployed to Kubernetes from the command line. If you don't have Kubernetes, you should use `kind` to create one. {{% alert title="Developer Guide" color="primary" %}} -Refer to the [Developer Guide](/latest/contributions/develop) to learn more. +Refer to the [Developer Guide](../../contributions/develop) to learn more. {{% /alert %}} 1. In your terminal, run the following command: diff --git a/site/content/en/v1.0.1/tasks/extensibility/envoy-patch-policy.md b/site/content/en/v1.0.1/tasks/extensibility/envoy-patch-policy.md index 5f24f448969..83b95065a82 100644 --- a/site/content/en/v1.0.1/tasks/extensibility/envoy-patch-policy.md +++ b/site/content/en/v1.0.1/tasks/extensibility/envoy-patch-policy.md @@ -2,7 +2,7 @@ title: "Envoy Patch Policy" --- -This guide explains the usage of the [EnvoyPatchPolicy][] API. +This task explains the usage of the [EnvoyPatchPolicy][] API. __Note:__ This API is meant for users extremely familiar with Envoy [xDS][] semantics. Also before considering this API for production use cases, please be aware that this API is unstable and the outcome may change across versions. Use at your own risk. @@ -22,7 +22,7 @@ not exposed by Envoy Gateway APIs today. ### Prerequisites -* Follow the steps from the [Quickstart](../../quickstart) guide to install Envoy Gateway and the example manifest. +* Follow the steps from the [Quickstart](../../quickstart) task to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP. ### Enable EnvoyPatchPolicy @@ -63,10 +63,10 @@ kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system ### Customize Response -* Lets use EnvoyProxy's [Local Reply Modification][] feature to return a custom response back to the client when +* Use EnvoyProxy's [Local Reply Modification][] feature to return a custom response back to the client when the status code is `404` -* Lets apply the configuration +* Apply the configuration ```shell cat <}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Customize EnvoyProxy Deployment Replicas You can customize the EnvoyProxy Deployment Replicas via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After you apply the config, you should see the replicas of envoyproxy changes to 2. And also you can dynamically change the value. @@ -62,6 +112,9 @@ kubectl get deployment -l gateway.envoyproxy.io/owning-gateway-name=eg -n envoy- You can customize the EnvoyProxy Image via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the deployment image, and see it has changed. ## Customize EnvoyProxy Pod Annotations You can customize the EnvoyProxy Pod Annotations via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the envoyproxy pods, and see new annotations has been added. ## Customize EnvoyProxy Deployment Resources You can customize the EnvoyProxy Deployment Resources via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + ## Customize EnvoyProxy Deployment Env You can customize the EnvoyProxy Deployment Env via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + > Envoy Gateway has provided two initial `env` `ENVOY_GATEWAY_NAMESPACE` and `ENVOY_POD_NAME` for envoyproxy container. After applying the config, you can get the envoyproxy deployment, and see resources has been changed. @@ -166,6 +332,9 @@ After applying the config, you can get the envoyproxy deployment, and see resour You can customize the EnvoyProxy Deployment Volumes or VolumeMounts via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the envoyproxy deployment, and see resources has been changed. ## Customize EnvoyProxy Service Annotations You can customize the EnvoyProxy Service Annotations via EnvoyProxy Config like: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, you can get the envoyproxy service, and see annotations has been added. ## Customize EnvoyProxy Bootstrap Config @@ -226,6 +452,9 @@ There are two ways to customize it: * Replace: the whole bootstrap config will be replaced by the config you provided. * Merge: the config you provided will be merged into the default bootstrap config. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + You can use [egctl translate][] to get the default xDS Bootstrap configuration used by Envoy Gateway. @@ -323,6 +642,9 @@ You can enable [Horizontal Pod Autoscaler](https://github.com/envoyproxy/gateway Once confirmed, you can apply it via EnvoyProxy Config as shown below: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + After applying the config, the EnvoyProxy HPA (Horizontal Pod Autoscaler) is generated. However, upon activating the EnvoyProxy's HPA, the Envoy Gateway will no longer reference the `replicas` field specified in the `envoyDeployment`, as outlined [here](#customize-envoyproxy-deployment-replicas). ## Customize EnvoyProxy Command line options @@ -354,6 +706,9 @@ After applying the config, the EnvoyProxy HPA (Horizontal Pod Autoscaler) is gen You can customize the EnvoyProxy Command line options via `spec.extraArgs` in EnvoyProxy Config. For example, the following configuration will add `--disable-extensions` arg in order to disable `envoy.access_loggers/envoy.access_loggers.wasm` extension: +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + +## Customize EnvoyProxy with Patches + +You can customize the EnvoyProxy using patches. + +For example, the following configuration will add resource limits to the `envoy` and the `shutdown-manager` containers in the `envoyproxy` deployment: + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +After applying the configuration, you will see the change in both containers in the `envoyproxy` deployment. + [Gateway API documentation]: https://gateway-api.sigs.k8s.io/ [EnvoyProxy]: ../../../api/extension_types#envoyproxy [egctl translate]: ../egctl/#validating-gateway-api-configuration + diff --git a/site/content/en/v1.0.1/tasks/quickstart.md b/site/content/en/v1.0.1/tasks/quickstart.md index 7bc01e4c7c3..fd62b772818 100644 --- a/site/content/en/v1.0.1/tasks/quickstart.md +++ b/site/content/en/v1.0.1/tasks/quickstart.md @@ -83,6 +83,23 @@ Curl the example app through Envoy proxy: curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get ``` +## What to explore next? + +In this quickstart, you have: +- Installed Envoy Gateway +- Deployed a backend service, and a gateway +- Configured the gateway using Kubernetes Gateway API resources [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway/) and [HttpRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/) to direct incoming requests over HTTP to the backend service. + +Here is a suggested list of follow-on tasks to guide you in your exploration of Envoy Gateway: + +- [HTTP Routing](traffic/http-routing) +- [Traffic Splitting](traffic/http-traffic-splitting) +- [Secure Gateways](security/secure-gateways/) +- [Global Rate Limit](traffic/global-rate-limit/) +- [gRPC Routing](traffic/grpc-routing/) + +Review the [Tasks](./) section for the scenario matching your use case. The Envoy Gateway tasks are organized by category: traffic management, security, extensibility, observability, and operations. + ## Clean-Up Use the steps in this section to uninstall everything from the quickstart. @@ -101,4 +118,4 @@ helm uninstall eg -n envoy-gateway-system ## Next Steps -Checkout the [Developer Guide](../contributions/develop) to get involved in the project. +Checkout the [Developer Guide](../../contributions/develop) to get involved in the project. diff --git a/site/content/en/v1.0.1/tasks/security/backend-tls.md b/site/content/en/v1.0.1/tasks/security/backend-tls.md index df7edb558c3..9eadf4dd9d8 100644 --- a/site/content/en/v1.0.1/tasks/security/backend-tls.md +++ b/site/content/en/v1.0.1/tasks/security/backend-tls.md @@ -2,8 +2,8 @@ title: "Backend TLS: Gateway to Backend" --- -This guide demonstrates how TLS can be achieved between the Gateway and a backend. The guide uses a self-signed CA, so it should be used for -testing and demonstration purposes only. +This task demonstrates how TLS can be achieved between the Gateway and a backend. +This task uses a self-signed CA, so it should be used for testing and demonstration purposes only. Envoy Gateway supports the Gateway-API defined [BackendTLSPolicy][]. @@ -29,7 +29,7 @@ Create a certificate and a private key for `www.example.com`: ```shell openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" -openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt +openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt ``` Store the cert/key in a Secret: @@ -49,56 +49,34 @@ kubectl create configmap example-ca --from-file=ca.crt Patch the existing quickstart backend to enable TLS. The patch will mount the TLS certificate secret into the backend as volume. ```shell -kubectl patch deployment backend --type=json --patch '[ - { - "op": "add", - "path": "/spec/template/spec/containers/0/volumeMounts", - "value": [ - { - "name": "secret-volume", - "mountPath": "/etc/secret-volume" - } - ] - }, - { - "op": "add", - "path": "/spec/template/spec/volumes", - "value": [ - { - "name": "secret-volume", - "secret": { - "secretName": "example-cert", - "items": [ - { - "key": "tls.crt", - "path": "crt" - }, - { - "key": "tls.key", - "path": "key" - } - ] - } - } - ] - }, - { - "op": "add", - "path": "/spec/template/spec/containers/0/env/-", - "value": { - "name": "TLS_SERVER_CERT", - "value": "/etc/secret-volume/crt" - } - }, - { - "op": "add", - "path": "/spec/template/spec/containers/0/env/-", - "value": { - "name": "TLS_SERVER_PRIVKEY", - "value": "/etc/secret-volume/key" - } - } -]' +kubectl patch deployment backend --type=json --patch ' + - op: add + path: /spec/template/spec/containers/0/volumeMounts + value: + - name: secret-volume + mountPath: /etc/secret-volume + - op: add + path: /spec/template/spec/volumes + value: + - name: secret-volume + secret: + secretName: example-cert + items: + - key: tls.crt + path: crt + - key: tls.key + path: key + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: TLS_SERVER_CERT + value: /etc/secret-volume/crt + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: TLS_SERVER_PRIVKEY + value: /etc/secret-volume/key + ' ``` Create a service that exposes port 443 on the backend service. @@ -141,9 +119,9 @@ spec: sectionName: "443" tls: caCertRefs: - - name: example-ca - group: '' - kind: ConfigMap + - name: example-ca + group: '' + kind: ConfigMap hostname: www.example.com EOF ``` @@ -151,18 +129,14 @@ EOF Patch the HTTPRoute's backend reference, so that it refers to the new TLS-enabled service: ```shell -kubectl patch HTTPRoute backend --type=json --patch '[ - { - "op": "replace", - "path": "/spec/rules/0/backendRefs/0/port", - "value": 443 - }, - { - "op": "replace", - "path": "/spec/rules/0/backendRefs/0/name", - "value": "tls-backend" - } -]' +kubectl patch HTTPRoute backend --type=json --patch ' + - op: replace + path: /spec/rules/0/backendRefs/0/port + value: 443 + - op: replace + path: /spec/rules/0/backendRefs/0/name + value: tls-backend + ' ``` Verify the HTTPRoute status: diff --git a/site/content/en/v1.0.1/tasks/security/basic-auth.md b/site/content/en/v1.0.1/tasks/security/basic-auth.md index a969cb1470a..e162e4f9879 100644 --- a/site/content/en/v1.0.1/tasks/security/basic-auth.md +++ b/site/content/en/v1.0.1/tasks/security/basic-auth.md @@ -2,7 +2,7 @@ title: "Basic Authentication" --- -This guide provides instructions for configuring [HTTP Basic authentication][http Basic authentication]. +This task provides instructions for configuring [HTTP Basic authentication][http Basic authentication]. HTTP Basic authentication checks if an incoming request has a valid username and password before routing the request to a backend service. @@ -12,7 +12,7 @@ This instantiated resource can be linked to a [Gateway][Gateway], [HTTPRoute][HT ## Prerequisites -Follow the steps from the [Quickstart](../../quickstart) guide to install Envoy Gateway and the example manifest. +Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP. ## Configuration @@ -49,23 +49,20 @@ Update the Gateway from the Quickstart to include an HTTPS listener that listens `example-cert` Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https", - "protocol": "HTTPS", - "port": 443, - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "example-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: example-cert + ' ``` ### Create a .htpasswd file @@ -128,7 +125,7 @@ kubectl get securitypolicy/basic-auth-example -o yaml ## Testing -Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) guide is set. If not, follow the +Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the Quickstart instructions to set the variable. ```shell @@ -176,7 +173,7 @@ The request should be allowed and you should see the response from the backend s ## Clean-Up -Follow the steps from the [Quickstart](../../quickstart) guide to uninstall Envoy Gateway and the example manifest. +Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest. Delete the SecurityPolicy and the secret @@ -188,9 +185,9 @@ kubectl delete secret/example-cert ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [http Basic authentication]: https://tools.ietf.org/html/rfc2617 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/cors.md b/site/content/en/v1.0.1/tasks/security/cors.md index dea4f04361d..b66077d5e28 100644 --- a/site/content/en/v1.0.1/tasks/security/cors.md +++ b/site/content/en/v1.0.1/tasks/security/cors.md @@ -132,9 +132,9 @@ kubectl delete securitypolicy/cors-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/ext-auth.md b/site/content/en/v1.0.1/tasks/security/ext-auth.md index efcd8b62467..5cc55964853 100644 --- a/site/content/en/v1.0.1/tasks/security/ext-auth.md +++ b/site/content/en/v1.0.1/tasks/security/ext-auth.md @@ -304,8 +304,8 @@ kubectl delete backendtlspolicy/grpc-ext-auth-btls ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/jwt-authentication.md b/site/content/en/v1.0.1/tasks/security/jwt-authentication.md index a8204fdae5d..26caabf3ad7 100644 --- a/site/content/en/v1.0.1/tasks/security/jwt-authentication.md +++ b/site/content/en/v1.0.1/tasks/security/jwt-authentication.md @@ -160,9 +160,9 @@ kubectl delete securitypolicy/jwt-example ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../contributions/design/security-policy [jwt]: https://tools.ietf.org/html/rfc7519 [jwks]: https://tools.ietf.org/html/rfc7517 [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway diff --git a/site/content/en/v1.0.1/tasks/security/mutual-tls.md b/site/content/en/v1.0.1/tasks/security/mutual-tls.md index 50ffa2be1de..c57b6f8b2ba 100644 --- a/site/content/en/v1.0.1/tasks/security/mutual-tls.md +++ b/site/content/en/v1.0.1/tasks/security/mutual-tls.md @@ -2,8 +2,8 @@ title: "Mutual TLS: External Clients to the Gateway" --- -This guide demonstrates how mutual TLS can be achieved between external clients and the Gateway. The guide uses a self-signed CA, so it should be used for -testing and demonstration purposes only. +This task demonstrates how mutual TLS can be achieved between external clients and the Gateway. +This task uses a self-signed CA, so it should be used for testing and demonstration purposes only. ## Prerequisites @@ -54,23 +54,20 @@ Update the Gateway from the Quickstart to include an HTTPS listener that listens `example-cert` Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https", - "protocol": "HTTPS", - "port": 443, - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "example-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: example-cert + ' ``` Verify the Gateway status: diff --git a/site/content/en/v1.0.1/tasks/security/oidc.md b/site/content/en/v1.0.1/tasks/security/oidc.md index 392650640e7..c11a52bbfef 100644 --- a/site/content/en/v1.0.1/tasks/security/oidc.md +++ b/site/content/en/v1.0.1/tasks/security/oidc.md @@ -2,9 +2,9 @@ title: "OIDC Authentication" --- -This guide provides instructions for configuring [OpenID Connect (OIDC)][oidc] authentication. +This task provides instructions for configuring [OpenID Connect (OIDC)][oidc] authentication. OpenID Connect (OIDC) is an authentication standard built on top of OAuth 2.0. -It enables client applications to rely on authentication that is performed by an OpenID Connect Provider (OP) +It enables EG to rely on authentication that is performed by an OpenID Connect Provider (OP) to verify the identity of a user. Envoy Gateway introduces a new CRD called [SecurityPolicy][SecurityPolicy] that allows the user to configure OIDC @@ -13,22 +13,23 @@ This instantiated resource can be linked to a [Gateway][Gateway] and [HTTPRoute] ## Prerequisites -Follow the steps from the [Quickstart](../../quickstart) guide to install Envoy Gateway and the example manifest. +Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP. +EG OIDC authentication requires the redirect URL to be HTTPS. Follow the [Secure Gateways](../secure-gateways) guide +to generate the TLS certificates and update the Gateway configuration to add an HTTPS listener. + Verify the Gateway status: ```shell kubectl get gateway/eg -o yaml ``` -OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with -the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations. - -This guide demonstrates the configuration of OIDC at the HTTPRoute level. - Let's create an HTTPRoute that represents an application protected by OIDC. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the HTTPRoute status: ```shell kubectl get httproute/myapp -o yaml ``` -## Configuration +## OIDC Authentication for a HTTPRoute -This guide uses Google as the OIDC provider to demonstrate the configuration of OIDC. However, EG works with any OIDC -providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA, etc. +OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with +the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations. + +This section demonstrates how to configure OIDC authentication for a specific HTTPRoute. ### Register an OIDC application +This task uses Google as the OIDC provider to demonstrate the configuration of OIDC. However, EG works with any OIDC +providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA, etc. + Follow the steps in the [Google OIDC documentation][google-oidc] to register an OIDC application. Please make sure the redirect URL is set to the one you configured in the SecurityPolicy that you will create in the step below. In this example, -the redirect URL is `http://www.example.com:8080/myapp/oauth2/callback`. +the redirect URL is `http://www.example.com:8443/myapp/oauth2/callback`. After registering the application, you should have the following information: * Client ID: The client ID of the OIDC application. @@ -79,20 +112,22 @@ and the Client Secret must be stored in the key "client-secret". Note: please replace the ${CLIENT_SECRET} with the actual Client Secret that you got from the previous step. ```shell -$ kubectl create secret generic my-app-client-secret --from-literal=client-secret=${CLIENT_SECRET} -secret "my-app-client-secret" created +kubectl create secret generic my-app-client-secret --from-literal=client-secret=${CLIENT_SECRET} ``` ### Create a SecurityPolicy -Please notice that the `redirectURL` and `logoutPath` must match the target HTTPRoute. In this example, the target -HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed -with `http://www.example.com:8080/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication -will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed +**Please notice that the `redirectURL` and `logoutPath` must match the target HTTPRoute.** In this example, the target +HTTPRoute is configured to match the host `www.example.com` and the path `/myapp`, so the `redirectURL` must be prefixed +with `https://www.example.com:8443/myapp`, and `logoutPath` must be prefixed with`/myapp`, otherwise the OIDC authentication +will fail because the redirect and logout requests will not match the target HTTPRoute and therefore can't be processed by the OAuth2 filter on that HTTPRoute. Note: please replace the ${CLIENT_ID} in the below yaml snippet with the actual Client ID that you got from the OIDC provider. +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + ```shell cat <}} + Verify the SecurityPolicy configuration: ```shell kubectl get securitypolicy/oidc-example -o yaml ``` -## Testing +### Testing Port forward gateway port to localhost: ```shell export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') -kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8080:80 +kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8443:443 ``` Put www.example.com in the /etc/hosts file in your test machine, so we can use this host name to access the gateway from a browser: @@ -138,12 +201,107 @@ Put www.example.com in the /etc/hosts file in your test machine, so we can use t 127.0.0.1 www.example.com ``` -Open a browser and navigate to the `http://www.example.com:8080/myapp` address. You should be redirected to the Google +Open a browser and navigate to the `https://www.example.com:8443/myapp` address. You should be redirected to the Google login page. After you successfully login, you should see the response from the backend service. +Clean the cookies in the browser and try to access `https://www.example.com:8443/foo` address. You should be able to see +this page since the path `/foo` is not protected by the OIDC policy. + +## OIDC Authentication for a Gateway + +OIDC can be configured at the Gateway level to authenticate all the HTTPRoutes that are associated with the Gateway with +the same OIDC configuration, or at the HTTPRoute level to authenticate each HTTPRoute with different OIDC configurations. + +This section demonstrates how to configure OIDC authentication for a Gateway. + +### Register an OIDC application + +If you haven't registered an OIDC application, follow the steps in the previous section to register an OIDC application. + +### Create a kubernetes secret + +If you haven't created a kubernetes secret, follow the steps in the previous section to create a kubernetes secret. + +### Create a SecurityPolicy + +Create or update the SecurityPolicy to target the Gateway instead of the HTTPRoute. **Please notice that the `redirectURL` +and `logoutPath` must match one of the HTTPRoutes associated with the Gateway.** In this example, the target Gateway has +two HTTPRoutes associated with it, one with the host `www.example.com` and the path `/myapp`, and the other with the host +`www.example.com` and the path `/`. Either one of the HTTPRoutes can be used to match the `redirectURL` and `logoutPath`. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +Verify the SecurityPolicy configuration: + +```shell +kubectl get securitypolicy/oidc-example -o yaml +``` + +### Testing + +If you haven't done so, follow the steps in the previous section to port forward gateway port to localhost and put +www.example.com in the /etc/hosts file in your test machine. + +Open a browser and navigate to the `https://www.example.com:8443/foo` address. You should be redirected to the Google +login page. After you successfully login, you should see the response from the backend service. + +You can also try to access `https://www.example.com:8443/myapp` address. You should be able to see this page since the +path `/myapp` is protected by the same OIDC policy. + ## Clean-Up -Follow the steps from the [Quickstart](../../quickstart) guide to uninstall Envoy Gateway and the example manifest. +Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest. Delete the SecurityPolicy, the secret and the HTTPRoute: @@ -155,10 +313,10 @@ kubectl delete httproute/myapp ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../../contributions/develop) to get involved in the project. [oidc]: https://openid.net/connect/ [google-oidc]: https://developers.google.com/identity/protocols/oauth2/openid-connect -[SecurityPolicy]: ../../contributions/design/security-policy/ +[SecurityPolicy]: ../../../../contributions/design/security-policy [Gateway]: https://gateway-api.sigs.k8s.io/api-types/gateway [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute diff --git a/site/content/en/v1.0.1/tasks/security/secure-gateways.md b/site/content/en/v1.0.1/tasks/security/secure-gateways.md index 9028de8b6b6..52bf8c9cb78 100644 --- a/site/content/en/v1.0.1/tasks/security/secure-gateways.md +++ b/site/content/en/v1.0.1/tasks/security/secure-gateways.md @@ -2,8 +2,8 @@ title: "Secure Gateways" --- -This guide will help you get started using secure Gateways. The guide uses a self-signed CA, so it should be used for -testing and demonstration purposes only. +This task will help you get started using secure Gateways. +This task uses a self-signed CA, so it should be used for testing and demonstration purposes only. ## Prerequisites @@ -11,7 +11,7 @@ testing and demonstration purposes only. ## Installation -Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest. +Follow the steps from the [Quickstart](../quickstart) to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP. ## TLS Certificates @@ -41,23 +41,20 @@ Update the Gateway from the Quickstart to include an HTTPS listener that listens `example-cert` Secret: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https", - "protocol": "HTTPS", - "port": 443, - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "example-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: example-cert + ' ``` Verify the Gateway status: @@ -122,34 +119,31 @@ kubectl create secret tls foo-cert --key=foo.example.com.key --cert=foo.example. Create another HTTPS listener on the example Gateway: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "https-foo", - "protocol": "HTTPS", - "port": 443, - "hostname": "foo.example.com", - "tls": { - "mode": "Terminate", - "certificateRefs": [{ - "kind": "Secret", - "group": "", - "name": "foo-cert", - }], - }, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: https-foo + protocol: HTTPS + port: 443 + hostname: foo.example.com + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: foo-cert + ' ``` Update the HTTPRoute to route traffic for hostname `foo.example.com` to the example backend service: ```shell -kubectl patch httproute backend --type=json --patch '[{ - "op": "add", - "path": "/spec/hostnames/-", - "value": "foo.example.com", -}]' +kubectl patch httproute backend --type=json --patch ' + - op: add + path: /spec/hostnames/- + value: foo.example.com + ' ``` Verify the Gateway status: @@ -171,9 +165,9 @@ Before proceeding, ensure you can query the HTTPS backend service from the [Test To demonstrate cross namespace certificate references, create a ReferenceGrant that allows Gateways from the "default" namespace to reference Secrets in the "envoy-gateway-system" namespace: -```console -$ cat <
| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart guide demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) guide shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | -|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | -|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | -|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | -|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | -|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | -|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | -|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | -|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | -|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | -|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | -|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | +|ID|UID|Category|Risk|Threat|Priority| Recommendation | +|-|-|-|-|-|-|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|EGTM-001|EGTM-GW-001|Gateway API| Self-signed certificates (which do not comply with PKI best practices) could lead to unauthorised access to the private key associated with the certificate used for inbound TLS termination at Envoy Proxy, compromising the confidentiality and integrity of proxied traffic.

| Compromise of the private key associated with the certificate used for inbound TLS terminating at Envoy Proxy.

|High| The Envoy Gateway quickstart guide demonstrates how to set up a Secure Gateway using an example where a self-signed root certificate is created using openssl. As stated in the Envoy Gateway documentation, this is not a suitable configuration for Production usage. It is recommended that PKI best practices are followed, whereby certificates are signed by an Intermediary CA which sits underneath an organisational \'offline\' Root CA.

PKI best practices should also apply to the management of client certificates when using mTLS. The Envoy Gateway [mTLS](../security/mutual-tls) guide shows how to set up client certificates using self-signed certificates. In the same way as gateway certificates and, as mentioned in the documentation, this configuration should not be used in production environments. | +|EGTM-002|EGTM-CS-001|Container Security| There is a risk that a threat actor could compromise the Kubernetes secret containing the Envoy private key, allowing the attacker to decrypt Envoy Proxy traffic, compromising the confidentiality of proxied traffic.

| Kubernetes secret containing the Envoy private key is compromised and used to decrypt proxied traffic.

|High| Certificate management best practices mandate short-lived key material where practical, meaning that a mechanism for rotation of private keys and certificates is required, along with a way for certificates to be mounted into Envoy containers. If Kubernetes secrets are used, when a certificate expires, the associated secret must be updated, and Envoy containers must be redeployed. Instead of a manual configuration, it is recommended that [cert-manager](https://github.com/cert-manager/cert-manager) is used. | +|EGTM-004|EGTM-K8-002|Container Security| There is a risk that a threat actor could abuse misconfigured RBAC to access the Envoy Gateway ClusterRole (envoy-gateway-role) and use it to expose all secrets across the cluster, thus compromising the confidentiality and integrity of tenant data.

| Compromised Envoy Gateway or misconfigured ClusterRoleBinding (envoy-gateway-rolebinding) to Envoy Gateway ClusterRole (envoy-gateway-role), provides access to resources and secrets in different namespaces.

|High| Users should be aware that Envoy Gateway uses a ClusterRole (envoy-gateway-role) when deployed via the Helm chart, to allow management of Envoy Proxies across different namespaces. This ClusterRole is powerful and includes the ability to read secrets in namespaces which may not be within the purview of Envoy Gateway.

Kubernetes best-practices involve restriction of ClusterRoleBindings, with the use of RoleBindings where possible to limit access per namespace by specifying the namespace in metadata. Namespace isolation reduces the impact of compromise from cluster-scoped roles. Ideally, fine-grained K8s roles should be created per the principle of least privilege to ensure they have the minimum access necessary for role functions.

The pull request \#[1656](https://github.com/envoyproxy/gateway/pull/1656) introduced the use of Roles and RoleBindings in [namespaced mode](https://gateway.envoyproxy.io/latest/api/extension_types/#kuberneteswatchmode). This feature can be leveraged to reduce the amount of permissions required by the Envoy Gateway. | +|EGTM-007|EGTM-EG-002|Envoy Gateway| There is a risk that a threat actor could exploit misconfigured Kubernetes RBAC to create or modify Gateway API resources with no business need, potentially leading to the compromise of the confidentiality, integrity, and availability of resources and traffic within the cluster.

| Unauthorised creation or misconfiguration of Gateway API resources by a threat actor with cluster-scoped access.

|High| Configure the apiGroup and resource fields in RBAC policies to restrict access to [Gateway](https://gateway-api.sigs.k8s.io/) and [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resources. Enable namespace isolation by using the namespace field, preventing unauthorised access to gateways in other namespaces. | +|EGTM-009|EGTM-GW-002|Gateway API| There is a risk that a co-tenant misconfigures Gateway or Route resources, compromising the confidentiality, integrity, and availability of routed traffic through Envoy Gateway.

| Malicious or accidental co-tenant misconfiguration of Gateways and Routes associated with other application teams.

|High| Dedicated Envoy Gateways should be provided to each tenant within their respective namespace. A one-to-one relationship should be established between GatewayClass and Gateway resources, meaning that each tenant namespace should have their own GatewayClass watched by a unique Envoy Gateway Controller as defined here in the [Deployment Mode](../operations/deployment-mode) documentation.

Application Admins should have write permissions on the Gateway resource, but only in their specific namespaces, and Application Developers should only hold write permissions on Route resources. To enact this access control schema, follow the [Write Permissions for Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model) described in the Kubernetes Gateway API security model. Examples of secured gateway-route topologies can be found [here](https://gateway-api.sigs.k8s.io/concepts/api-overview/#attaching-routes-to-gateways) within the Kubernetes Gateway API docs.

Optionally, consider a GitOps model, where only the GitOps operator has the permission to deploy or modify custom resources in production. | +|EGTM-014|EGTM-CS-006|Container Security| There is a risk that a supply chain attack on Envoy Gateway results in an arbitrary compromise of the confidentiality, integrity or availability of tenant data.

| Supply chain threat actor introduces malicious code into Envoy Gateway or Proxy.

|High| The Envoy Gateway project should continue to work towards conformance with supply-chain security best practices throughout the project lifecycle (for example, as set out in the [CNCF Software Supply Chain Best Practices Whitepaper](https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf). Adherence to [Supply-chain Levels for Software Artefacts](https://slsa.dev/) (SLSA) standards is crucial for maintaining the security of the system. Employ version control systems to monitor the source and build platforms and assign responsibility to a specific stakeholder.

Integrate a supply chain security tool such as Sigstore, which provides native capabilities for signing and verifying container images and software artefacts. [Software Bill of Materials](https://www.cisa.gov/sbom) (SBOM), [Vulnerability Exploitability eXchange](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf) (VEX), and signed artefacts should also be incorporated into the security protocol. | +|EGTM-020|EGTM-CS-009|Container Security| There is a risk that a threat actor exploits an Envoy Proxy vulnerability to remote code execution (RCE) due to out of date or misconfigured Envoy Proxy pod deployment, compromising the confidentiality and integrity of Envoy Proxy along with the availability of the proxy service.

| Deployment of an Envoy Proxy or Gateway image containing exploitable CVEs.

|High| Always use the latest version of the Envoy Proxy image. Regularly check for updates and patch the system as soon as updates become available. Implement a CI/CD pipeline that includes security checks for images and prevents deployment of insecure configurations. A tool such as Snyk can be used to provide container vulnerability scanning to mitigate the risk of known vulnerabilities.

Utilise the [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) controller to enforce [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and configure the [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) to limit its capabilities per the principle of least privilege. | +|EGTM-022|EGTM-CS-010|Container Security| There is a risk that the OIDC client secret (for OIDC authentication) and user password hashes (for basic authentication) get leaked due to misconfigured RBAC permissions.

| Unauthorised access to the application due to credential leakage.

|High| Ensure that only authorised users and service accounts are able to access secrets. This is especially important in namespaces where SecurityPolicy objects are configured, since those namespaces are the ones to store secrets containing the client secret (in OIDC scenarios) and user password hashes (in basic authentication scenarios).

To do so, minimise the use of ClusterRoles and Roles allowing listing and getting secrets. Perform periodic audits of RBAC permissions. | +|EGTM-023|EGTM-EG-007|Envoy Gateway| There is a risk of unauthorised access due to the use of basic authentication, which does not enforce any password restriction in terms of complexity and length. In addition, password hashes are stored in SHA1 format, which is a deprecated hashing function.

| Unauthorised access to the application due to weak authentication mechanisms.

|High| It is recommended to make use of stronger authentication mechanisms (i.e. JWT authentication and OIDC authentication) instead of basic authentication. These authentication mechanisms have many advantages, such as the use of short-lived credentials and a central management of security policies through the identity provider. | +|EGTM-008|EGTM-EG-003|Envoy Gateway| There is a risk of a threat actor misconfiguring static config and compromising the integrity of Envoy Gateway, ultimately leading to the compromised confidentiality, integrity, or availability of tenant data and cluster resources.

| Accidental or deliberate misconfiguration of static configuration leads to a misconfigured deployment of Envoy Gateway, for example logging parameters could be modified or global rate limiting configuration misconfigured.

|Medium| Implement a GitOps model, utilising Kubernetes\' Role-Based Access Control (RBAC) and adhering to the principle of least privilege to minimise human intervention on the cluster. For instance, tools like [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) can be used for declarative GitOps deployments, ensuring all changes are tracked and reviewed. Additionally, configure your source control management (SCM) system to include mandatory pull request (PR) reviews, commit signing, and protected branches to ensure only authorised changes can be committed to the start-up configuration. | +|EGTM-010|EGTM-CS-005|Container Security| There is a risk that a threat actor exploits a weak pod security context, compromising the CIA of a node and the resources / services which run on it.

| Threat Actor who has compromised a pod exploits weak security context to escape to a node, potentially leading to the compromise of Envoy Proxy or Gateway running on the same node.

|Medium| To mitigate this risk, apply [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) at a minimum of [Baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline) level to all namespaces, especially those containing Envoy Gateway and Proxy Pods. Pod security standards are implemented through K8s [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) to provide [admission control modes](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces) (enforce, audit, and warn) for namespaces. Pod security standards can be enforced by namespace labels as shown [here](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/), to enforce a baseline level of pod security to specific namespaces.

Further enhance the security by implementing a sandboxing solution such as [gVisor](https://gvisor.dev/) for Envoy Gateway and Proxy Pods to isolate the application from the host kernel. This can be set within the runtimeClassName of the Pod specification. | +|EGTM-012|EGTM-GW-004|Gateway API| There is a risk that a threat actor could abuse excessive RBAC privileges to create ReferenceGrant resources. These resources could then be used to create cross-namespace communication, leading to unauthorised access to the application. This could compromise the confidentiality and integrity of resources and configuration in the affected namespaces and potentially disrupt the availability of services that rely on these object references.

| A ReferenceGrant is created, which validates traffic to cross namespace trust boundaries without a valid business reason, such as a route in one tenant\'s namespace referencing a backend in another.

|Medium| Ensure that the ability to create ReferenceGrant resources is restricted to the minimum number of people. Pay special attention to ClusterRoles that allow that action. | |EGTM-018|EGTM-GW-006|Gateway API| There is a risk that malicious requests could lead to a Denial of Service (DoS) attack, thereby reducing API gateway availability due to misconfigurations in rate-limiting or load balancing controls, or a lack of route timeout enforcement.

| Reduced API gateway availability due to an attacker\'s maliciously crafted request (e.g., QoD) potentially inducing a Denial of Service (DoS) attack.

|Medium| To ensure high availability and to mitigate potential security threats, adhere to the Envoy Gateway documentation for the configuration of a [rate-limiting](https://gateway.envoyproxy.io/v0.6.0/user/rate-limit/) filter and load balancing.

Further, adhere to best practices for configuring Envoy Proxy as an edge proxy documented [here](https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#configuring-envoy-as-an-edge-proxy) within the EnvoyProxy docs. This involves configuring TCP and HTTP proxies with specific settings, including restricting access to the admin endpoint, setting the [overload manager](https://www.envoyproxy.io/docs/envoy/latest/configuration/operations/overload_manager/overload_manager#config-overload-manager) and [listener](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-per-connection-buffer-limit-bytes) / [cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-per-connection-buffer-limit-bytes) buffer limits, enabling [use_remote_address](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-use-remote-address), setting [connection and stream timeouts](https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/timeouts#faq-configuration-timeouts), limiting [maximum concurrent streams](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-max-concurrent-streams), setting [initial stream window size limit](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size), and configuring action on [headers_with_underscores](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-headers-with-underscores-action).

[Path normalisation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-normalize-path) should be enabled to minimise path confusion vulnerabilities. These measures help protect against volumetric threats such as Denial of Service (DoS)nattacks. Utilise custom resources to implement policy attachment, thereby exposing request limit configuration for route types. | -|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | -|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | -|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | -|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | -|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | -|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | -|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | -|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | -|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | -|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | -|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | -|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | +|EGTM-019|EGTM-DP-004|Container Security| There is a risk that replay attacks using stolen or reused JSON Web Tokens (JWTs) can compromise transmission integrity, thereby undermining the confidentiality and integrity of the data plane.

| Transmission integrity is compromised due to replay attacks using stolen or reused JSON Web Tokens (JWTs).

|Medium| Comply with JWT best practices for enhanced security, paying special attention to the use of short-lived tokens, which reduce the window of opportunity for a replay attack. The [exp](https://datatracker.ietf.org/doc/html/rfc7519#page-9) claim can be used to set token expiration times. | +|EGTM-024|EGTM-EG-008|Envoy Gateway| There is a risk of developers getting more privileges than required due to the use of SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy and BackendTrafficPolicy. These resources can be attached to a Gateway resource. Therefore, a developer with permission to deploy them would be able to modify a Gateway configuration by targeting the gateway in the policy manifest. This conflicts with the [Advanced 4 Tier Model](https://gateway-api.sigs.k8s.io/concepts/security-model/#write-permissions-for-advanced-4-tier-model), where developers do not have write permissions on Gateways.

| Excessive developer permissions lead to a misconfiguration and/or unauthorised access.

|Medium| Considering the Tenant C scenario (represented in the Architecture Diagram), if a developer can create SecurityPolicy, ClientTrafficPolicy, EnvoyPatchPolicy or BackendTrafficPolicy objects in namespace C, they would be able to modify a Gateway configuration by attaching the policy to the gateway. In such scenarios, it is recommended to either:

a. Create a separate namespace, where developers have no permissions, > to host tenant C\'s gateway. Note that, due to design decisions, > the > SecurityPolicy/EnvoyPatchPolicy/ClientTrafficPolicy/BackendTrafficPolicy > object can only target resources deployed in the same namespace. > Therefore, having a separate namespace for the gateway would > prevent developers from attaching the policy to the gateway.

b. Forbid the creation of these policies for developers in namespace C.

On the other hand, in scenarios similar to tenants A and B, where a shared gateway namespace is in place, this issue is more limited. Note that in this scenario, developers don\'t have access to the shared gateway namespace.

In addition, it is important to mention that EnvoyPatchPolicy resources can also be attached to GatewayClass resources. This means that, in order to comply with the Advanced 4 Tier model, individuals with the Application Administrator role should not have access to this resource either. | +|EGTM-003|EGTM-EG-001|Envoy Gateway| There is a risk that a threat actor could downgrade the security of proxied connections by configuring a weak set of cipher suites, compromising the confidentiality and integrity of proxied traffic.

| Exploit weak cipher suite configuration to downgrade security of proxied connections.

|Low| Users operating in highly regulated environments may need to tightly control the TLS protocol and associated cipher suites, blocking non-conforming incoming connections to the gateway.

EnvoyProxy bootstrap config can be customised as per the [customise EnvoyProxy](../operations/customize-envoyproxy) documentation. In addition, from v.1.0.0, it is possible to configure common TLS properties for a Gateway or XRoute through the [ClientTrafficPolicy](https://gateway.envoyproxy.io/latest/api/extension_types/#clienttrafficpolicy) object. | +|EGTM-005|EGTM-CP-002|Container Security| Threat actor who has obtained access to Envoy Gateway pod could exploit the lack of AppArmor and Seccomp profiles in the Envoy Gateway deployment to attempt a container breakout, given the presence of an exploitable vulnerability, potentially impacting the confidentiality and integrity of namespace resources.

| Unauthorised syscalls and malicious code running in the Envoy Gateway pod.

|Low| Implement [AppArmor](https://kubernetes.io/docs/tutorials/security/apparmor/) policies by setting \: \ within container.apparmor.security.beta.kubernetes.io (note, this config is set *per container*). Well-defined AppArmor policies may provide greater protection from unknown threats.

Enforce [Seccomp](https://kubernetes.io/docs/tutorials/security/seccomp/) profiles by setting the seccompProfile under securityContext. Ideally, a [fine-grained](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-with-a-seccomp-profile-that-only-allows-necessary-syscalls) profile should be used to restrict access to only necessary syscalls, however the \--seccomp-default flag can be set to resort to [RuntimeDefault](https://kubernetes.io/docs/tutorials/security/seccomp/#create-pod-that-uses-the-container-runtime-default-seccomp-profile) which provides a container runtime specific. Example seccomp profiles can be found [here](https://kubernetes.io/docs/tutorials/security/seccomp/#download-profiles).

To further enhance pod security, consider implementing [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) via seLinuxOptions for additional syscall attack surface reduction. Setting readOnlyRootFilesystem == true enforces an immutable root filesystem, preventing the addition of malicious binaries to the PATH and increasing the attack cost. Together, these configuration items improve the pods [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | +|EGTM-006|EGTM-CS-004|Container Security| There is a risk that a threat actor exploits a vulnerability in Envoy Proxy to expose a reverse shell, enabling them to compromise the confidentiality, integrity and availability of tenant data via a secondary attack.

| If an external attacker managed to exploit a vulnerability in Envoy, the presence of a shell would be greatly helpful for the attacker in terms of potentially pivoting, escalating, or establishing some form of persistence.

|Low| By default, Envoy uses a [distroless](https://github.com/GoogleContainerTools/distroless) image since v.0.6.0, which does not ship a shell. Therefore, ensure EnvoyProxy image is up-to-date and patched with the latest stable version.

If using private EnvoyProxy images, use a lightweight EnvoyProxy image without a shell or debugging tool(s) which may be useful for an attacker.

An [AuditPolicy](https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#audit-policy) (audit.k8s.io/v1beta1) can be configured to record API calls made within your cluster, allowing for identification of malicious traffic and enabling incident response. Requests are recorded based on stages which delineate between the lifecycle stage of the request made (e.g., RequestReceived, ResponseStarted, & ResponseComplete). | +|EGTM-011|EGTM-GW-003|Gateway API| There is a risk that a gateway owner (or someone with the ability to set namespace labels) maliciously or accidentally binds routes across namespace boundaries, potentially compromising the confidentiality and integrity of traffic in a multitenant scenario.

| If a Route Binding within a Gateway Listener is configured based on a custom label, it could allow a malicious internal actor with the ability to label namespaces to change the set of namespaces supported by the Gateway

|Low| Consider the use of custom admission control to restrict what labels can be set on namespaces through tooling such as [Kubewarden](https://kyverno.io/policies/pod-security/), [Kyverno](https://github.com/kubewarden), and [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Route binding should follow the Kubernetes Gateway API security model, as shown [here](https://gateway-api.sigs.k8s.io/concepts/security-model/#1-route-binding), to connect gateways in different namespaces. | +|EGTM-013|EGTM-GW-005|Gateway API| There is a risk that an unauthorised actor deploys an unauthorised GatewayClass due to GatewayClass namespace validation not being configured, leading to non-compliance with business and security requirements.

| Unauthorised deployment of Gateway resource via GatewayClass template which crosses namespace trust boundaries.

|Low| Leverage GatewayClass namespace validation to limit the namespaces where GatewayClasses can be run through a tool such as using [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper). Reference pull request \#[24](https://github.com/open-policy-agent/gatekeeper-library/pull/24) within gatekeeper-library which outlines how to add GatewayClass namespace validation through a GatewayClassNamespaces API resource kind within the constraints.gatekeeper.sh/v1beta1 apiGroup. | +|EGTM-015|EGTM-CS-007|Container Security| There is a risk that threat actors could exploit ServiceAccount tokens for illegitimate authentication, thereby leading to privilege escalation and the undermining of gateway API resources\' integrity, confidentiality, and availability.

| The threat arises from threat actors impersonating the envoy-gateway ServiceAccount through the replay of ServiceAccount tokens, thereby achieving escalated privileges and gaining unauthorised access to Kubernetes resources.

|Low| Limit the creation of ServiceAccounts to only when necessary, specifically refraining from using default service account tokens, especially for high-privilege service accounts. For legacy clusters running Kubernetes version 1.21 or earlier, note that ServiceAccount tokens are long-lived by default. To disable the automatic mounting of the service account token, set automountServiceAccountToken: false in the PodSpec. | +|EGTM-016|EGTM-EG-004|Envoy Gateway| There is a risk that threat actors establish persistence and move laterally through the cluster unnoticed due to limited visibility into access and application-level activity.

| Threat actors establish persistence and move laterally through the cluster unnoticed.

|Low| Configure [access logging](../../../contributions/design/accesslog) in the EnvoyProxy. Use [ProxyAccessLogFormatType](../../api/extension_types#proxyaccesslogformattype) (Text or JSON) to specify the log format and ensure that the logs are sent to the desired sink types by setting the [ProxyAccessLogSinkType](https://gateway.envoyproxy.io/latest/api/extension_types/#proxyaccesslogsinktype). Make use of [FileEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#fileenvoyproxyaccesslog) or [OpenTelemetryEnvoyProxyAccessLog](https://gateway.envoyproxy.io/latest/api/extension_types/#opentelemetryenvoyproxyaccesslog) to configure File and OpenTelemetry sinks, respectively. If the settings aren\'t defined, the default format is sent to stdout.

Additionally, consider leveraging a central logging mechanism such as [Fluentd](https://github.com/fluent/fluentd) to enhance visibility into access activity and enable effective incident response (IR). | +|EGTM-017|EGTM-EG-005|Envoy Gateway| There is a risk that an insider misconfigures an envoy gateway component and goes unnoticed due to a low-touch logging configuration (via default) which responsible stakeholders are not aptly aware of or have immediate access to.

| The threat emerges from an insider misconfiguring an Envoy Gateway component without detection.

|Low| Configure the logging level of the Envoy Gateway using the \'level\' field in [EnvoyGatewayLogging](https://gateway.envoyproxy.io/latest/api/extension_types/#envoygatewaylogging). Ensure the appropriate logging levels are set for relevant components such as \'gateway-api\', \'xds-translator\', or \'global-ratelimit\'. If left unspecified, the logging level defaults to \"info\", which may not provide sufficient detail for security monitoring.

Employ a centralised logging mechanism, like [Fluentd](https://github.com/fluent/fluentd), to enhance visibility into application-level activity and to enable efficient incident response. | +|EGTM-021|EGTM-EG-006|Envoy Gateway| There is a risk that the admin interface is exposed without valid business reason, increasing the attack surface.

| Exposed admin interfaces give internal attackers the option to affect production traffic in unauthorised ways, and the option to exploit any vulnerabilities which may be present in the admin interface (e.g. by orchestrating malicious GET requests to the admin interface through CSRF, compromising Envoy Proxy global configuration or shutting off the service entirely (e.g., /quitquitquit).

|Low| The Envoy Proxy admin interface is only exposed to localhost, meaning that it is secure by default. However, due to the risk of misconfiguration, this recommendation is included.

Due to the importance of the admin interface, it is recommended to ensure that Envoy Proxies have not been accidentally misconfigured to expose the admin interface to untrusted networks. | +|EGTM-025 | EGTM-CS-011 | Container Security | The presence of a vulnerability, be it in the kernel or another system component, when coupled with containers running as root, could enable a threat actor to escape the container, thereby compromising the confidentiality, integrity, or availability of cluster resources. | The Envoy Proxy container's root-user configuration can be leveraged by an attacker to escalate privileges, execute a container breakout, and traverse across trust boundaries. | Low | By default, Envoy Gateway deployments do not use root users. Nonetheless, in case a custom image or deployment manifest is to be used, make sure Envoy Proxy pods run as a non-root user with a high UID within the container. Set runAsUser and runAsGroup security context options to specific UIDs (e.g., runAsUser: 1000 & runAsGroup: 3000) to ensure the container operates with the stipulated non-root user and group ID. If using helm chart deployment, define the user and group ID in the values.yaml file or via the command line during helm install / upgrade. | ## Attack Trees diff --git a/site/content/en/v1.0.1/tasks/security/tls-passthrough.md b/site/content/en/v1.0.1/tasks/security/tls-passthrough.md index 63fefa94197..2683f568332 100644 --- a/site/content/en/v1.0.1/tasks/security/tls-passthrough.md +++ b/site/content/en/v1.0.1/tasks/security/tls-passthrough.md @@ -2,7 +2,7 @@ title: "TLS Passthrough" --- -This guide will walk through the steps required to configure TLS Passthrough via Envoy Gateway. Unlike configuring +This task will walk through the steps required to configure TLS Passthrough via Envoy Gateway. Unlike configuring Secure Gateways, where the Gateway terminates the client TLS connection, TLS Passthrough allows the application itself to terminate the TLS connection, while the Gateway routes the requests to the application based on SNI headers. @@ -53,17 +53,17 @@ Patch the Gateway from the Quickstart to include a TLS listener that listens on TLS mode Passthrough: ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/listeners/-", - "value": { - "name": "tls", - "protocol": "TLS", - "hostname": "passthrough.example.com", - "tls": {"mode": "Passthrough"}, - "port": 6443, - }, -}]' +kubectl patch gateway eg --type=json --patch ' + - op: add + path: /spec/listeners/- + value: + name: tls + protocol: TLS + hostname: passthrough.example.com + port: 6443 + tls: + mode: Passthrough + ' ``` ## Testing @@ -116,4 +116,4 @@ kubectl delete secret/server-certs ## Next Steps -Checkout the [Developer Guide](../../../contributions/develop/) to get involved in the project. +Checkout the [Developer Guide](../../../contributions/develop) to get involved in the project. diff --git a/site/content/en/v1.0.1/tasks/traffic/gateway-address.md b/site/content/en/v1.0.1/tasks/traffic/gateway-address.md index d211d315c1a..bd87726c139 100644 --- a/site/content/en/v1.0.1/tasks/traffic/gateway-address.md +++ b/site/content/en/v1.0.1/tasks/traffic/gateway-address.md @@ -21,21 +21,22 @@ The Envoy Gateway deploys Envoy Proxy Service as `LoadBalancer` by default, so you can set the address of the Gateway directly (the address settings here are for reference only): ```shell -kubectl patch gateway eg --type=json --patch '[{ - "op": "add", - "path": "/spec/addresses", - "value": [{ - "type": "IPAddress", - "value": "1.2.3.4" - }] -}]' +kubectl patch gateway eg --type=json --patch ' +- op: add + path: /spec/addresses + value: + - type: IPAddress + value: 1.2.3.4 +' ``` Verify the Gateway status: ```shell kubectl get gateway +``` +```console NAME CLASS ADDRESS PROGRAMMED AGE eg eg 1.2.3.4 True 14m ``` @@ -44,7 +45,9 @@ Verify the Envoy Proxy Service status: ```shell kubectl get service -n envoy-gateway-system +``` +```console NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE envoy-default-eg-64656661 LoadBalancer 10.96.236.219 1.2.3.4 80:31017/TCP 15m envoy-gateway ClusterIP 10.96.192.76 18000/TCP 15m diff --git a/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md b/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md index 778a9972d62..7ea0e91e54b 100644 --- a/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md +++ b/site/content/en/v1.0.1/tasks/traffic/gatewayapi-support.md @@ -94,7 +94,7 @@ these types of cross-namespace references. Envoy Gateway supports the following namespace. - Allowing a Gateway's [SecretObjectReference][] to reference a secret in a different namespace. -[system design]: ../../contributions/design/system-design/ +[system design]: ../../../contributions/design/system-design [Gateway API]: https://gateway-api.sigs.k8s.io/ [GatewayClass]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayClass [parameters reference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ParametersReference @@ -110,7 +110,7 @@ these types of cross-namespace references. Envoy Gateway supports the following [TLSRoute]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute [ReferenceGrant]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.ReferenceGrant [SecretObjectReference]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.SecretObjectReference -[rate limiting]: ../../contributions/design/rate-limit +[rate limiting]: ../../../contributions/design/rate-limit [request authentication]: ../security/jwt-authentication [EnvoyProxy]: ../../../api/extension_types#envoyproxy [resolving conflicts]: https://gateway-api.sigs.k8s.io/concepts/guidelines/?h=conflict#conflicts diff --git a/site/content/en/v1.0.1/tasks/traffic/global-rate-limit.md b/site/content/en/v1.0.1/tasks/traffic/global-rate-limit.md index a0734928bd7..d65d972678b 100644 --- a/site/content/en/v1.0.1/tasks/traffic/global-rate-limit.md +++ b/site/content/en/v1.0.1/tasks/traffic/global-rate-limit.md @@ -511,9 +511,9 @@ transfer-encoding: chunked Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on their IP address (also reflected in the `X-Forwarded-For` header). -Note: EG supports two kinds of rate limit for the IP address: exact and distinct. -* exact means that all IP addresses within the specified Source IP CIDR share the same rate limit bucket. -* distinct means that each IP address within the specified Source IP CIDR has its own rate limit bucket. +Note: EG supports two kinds of rate limit for the IP address: Exact and Distinct. +* Exact means that all IP addresses within the specified Source IP CIDR share the same rate limit bucket. +* Distinct means that each IP address within the specified Source IP CIDR has its own rate limit bucket. ```shell cat < 开始使用 - + 参与贡献

将 Envoy 代理作为独立或基于 Kubernetes 的 API 网关进行管理

@@ -66,8 +66,7 @@ title: Envoy Gateway {{% /blocks/feature %}} {{% blocks/feature icon="fab fa-github" title="欢迎贡献!" - url="/latest/contributions/" %}} -We do a [Pull Request](https://github.com/envoyproxy/gateway/pulls) contributions workflow on **GitHub**. + url="/contributions/" %}} 我们在 **GitHub** 通过 [Pull Request](https://github.com/envoyproxy/gateway/pulls) 开启贡献流程。 {{% /blocks/feature %}} diff --git a/site/content/zh/announcements/_index.md b/site/content/zh/announcements/_index.md index 9fd4dfc1d58..08f04069b5b 100644 --- a/site/content/zh/announcements/_index.md +++ b/site/content/zh/announcements/_index.md @@ -1,10 +1,56 @@ +++ title = "发布公告" description = "Envoy Gateway 发布公告" -linktitle = "Announcement" +linktitle = "公告" [[cascade]] type = "docs" +++ -中文内容正在建设中! +本文档提供了 Envoy Gateway 版本的详细信息。 +Envoy Gateway 遵循语义版本控制 [v2.0.0 规范][]进行发布版本控制。 +由于 Envoy Gateway 是一个新项目,因此次要版本是唯一被定义的版本。 +Envoy Gateway 维护人员在未来的某个日期将建立额外的发布详细信息,例如补丁版本。 + +## 稳定版本 {#stable-releases} + +Envoy Gateway 的稳定版本包括: + +* 次要版本 - 从 `main` 分支创建新的版本分支和相应的 Tag。 + 次要版本将在发布日期后的 6 个月内受到支持。 + 随着项目的成熟,Envoy Gateway 维护人员将重新评估支持时间范围。 + +次要版本每季度发布一次,并遵循以下时间表。 + +## 发布管理 {#release-management} + +次要版本由指定的 Envoy Gateway 维护人员处理。 +该维护者被视为该版本的发布经理。[发布指南][]中描述了创建发布的详细信息。 +发布经理负责协调整体发布。这包括确定版本中要解决的问题、与 Envoy Gateway 社区的沟通以及发布版本的机制。 + +| 季度 | 发布经理 | +|:-------:|:--------------------------------------------------------------:| +| 2022 Q4 | Daneyon Hansen ([danehans](https://github.com/danehans)) | +| 2023 Q1 | Xunzhuo Liu ([Xunzhuo](https://github.com/Xunzhuo)) | +| 2023 Q2 | Alice Wasko ([AliceProxy](https://github.com/AliceProxy)) | +| 2023 Q3 | Arko Dasgupta ([arkodg](https://github.com/arkodg)) | +| 2023 Q4 | Arko Dasgupta ([arkodg](https://github.com/arkodg)) | +| 2024 Q1 | Xunzhuo Liu ([Xunzhuo](https://github.com/Xunzhuo)) | + +## 发布时间表 {#release-schedule} + +为了与 Envoy Proxy [发布时间表][]保持一致, +Envoy Gateway 版本按固定时间表(每个季度的第 22 天)生成, +可接受的延迟最多为 2 周,硬性截止日期为 3 周。 + +| 版本 | 预期时间 | 实际时间 | 偏差 | 生命周期结束 | +|:-------:|:-----------:|:-----------:|:-----------:|:-----------:| +| 0.2.0 | 2022/10/22 | 2022/10/20 | -2 天 | 2023/4/20 | +| 0.3.0 | 2023/01/22 | 2023/02/09 | +17 天 | 2023/08/09 | +| 0.4.0 | 2023/04/22 | 2023/04/24 | +2 天 | 2023/10/24 | +| 0.5.0 | 2023/07/22 | 2023/08/02 | +10 天 | 2024/01/02 | +| 0.6.0 | 2023/10/22 | 2023/11/02 | +10 天 | 2024/05/02 | + +[v2.0.0 规范]: https://semver.org/lang/zh-CN/ +[发布指南]: ../contributions/releasing +[发布时间表]: https://github.com/envoyproxy/envoy/blob/main/RELEASES.md#major-release-schedule diff --git a/site/content/zh/contributions/CODEOWNERS.md b/site/content/zh/contributions/CODEOWNERS.md new file mode 100644 index 00000000000..74e885d852a --- /dev/null +++ b/site/content/zh/contributions/CODEOWNERS.md @@ -0,0 +1,21 @@ +--- +title: "维护者" +description: "本部分包括 Envoy Gateway 的维护者。" +--- + +## 以下是拥有所有权限的维护者(按字母顺序排列) {#the-following-maintainers-listed-in-alphabetical-order-own-everything} + +- @AliceProxy +- @arkodg +- @qicz +- @Xunzhuo +- @zirain +- @zhaohuabing + +## 荣誉退休维护者 {#emeritus-maintainers} + +- @alexgervais +- @danehans +- @LukeShu +- @skriss +- @youngnick diff --git a/site/content/zh/contributions/CODE_OF_CONDUCT.md b/site/content/zh/contributions/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..c717d1cccd8 --- /dev/null +++ b/site/content/zh/contributions/CODE_OF_CONDUCT.md @@ -0,0 +1,7 @@ +--- +title: "行为准则" +description: "本节包括 Envoy Gateway 的行为准则。" +--- + +Envoy Gateway 遵循 +[CNCF 行为准则](https://github.com/cncf/foundation/blob/main/code-of-conduct-languages/zh.md)。 diff --git a/site/content/zh/contributions/DOCS.md b/site/content/zh/contributions/DOCS.md new file mode 100644 index 00000000000..f05920705e8 --- /dev/null +++ b/site/content/zh/contributions/DOCS.md @@ -0,0 +1,66 @@ +--- +title: "参与 Envoy Gateway 文档工作" +description: "本节讲述 Envoy Gateway 文档的开发工作。" +--- + +{{% alert title="注意" color="warning" %}} +我们已将 Envoy Gateway 文档从 **Sphinx** 迁移到 **Hugo**。 + +阅读博客:[Welcome to new website!](/blog/2023/10/08/welcome-to-new-website/) +{{% /alert %}} + +Envoy Gateway 的文档位于 `site/content/en` 目录中(中文内容位于 `site/content/zh` 目录中)。 +任何单独的文档都可以使用 [Markdown] 编写。 + +## 文档结构 {#documentation-structure} + +我们现在支持版本化的文档,文档下的目录名代表了文档的版本。 +最新站点的根目录位于 `site/content/en/latest` 中。 +如果您想了解这些内容如何组合在一起,可以由此处开始。 + +请注意,新内容应被添加到 `site/content/en/latest` 中, +并将在下一个版本中被截断。`site/content/en/v0.5.0` 下的内容是自动生成的, +通常不需要对其进行更改,除非您发现当前发布页面有一些不正确的内容。 +如果是这样,您应该提交 PR 来一并更新 `site/content/en/latest` 和 `site/content/en/v0.5.0` 的内容。 + +您可以默认访问代表当前版本的网站内容, +也可以在[此处][latest-website]或页面的页脚处访问包含最新版本变更的网站。 + +## 文档工作流程 {#documentation-workflow} + +要参与文档工作,只需编辑 `site/content/en/latest` 中的 Markdown 文件,然后运行: + +```bash +make docs +``` + +这将使用被构建的 HTML 页面创建 `site/public`。您可以通过运行以下命令来预览它: + +```shell +make docs-serve +``` + +如果您想生成文档的新发布版本,例如 `v0.6.0`,请运行: + +```bash +make docs-release TAG=v0.6.0 +``` + +该操作将更新项目根目录下的 VERSION 文件,该文件记录当前发布的版本, +并将在页面版本上下文和二进制版本输出中被使用。此外,这将生成新的目录 `site/content/en/v0.6.0`, +其中包含 v0.6.0 的文档,如 `/api`、`/install` 等。 + +## 发布文档 {#publishing-docs} + +每当文档被推送到 `main` 分支时,CI 都会将构建的文档发布到 GitHub Pages。 +有关更多详细信息,请参阅 `.github/workflows/docs.yaml`。 + +## 参考 {#reference} + +前往 [Hugo](https://gohugo.io) 和 [Docsy](https://www.docsy.dev/docs) 了解更多信息。 + +如果您希望参与中文内容翻译或贡献,请先阅读[规范][docs-standard]以帮助您更好的参与内容贡献。 + +[Markdown]: https://daringfireball.net/projects/markdown/syntax +[latest-website]: /zh/latest +[docs-standard]: ../docs_standard diff --git a/site/content/zh/contributions/DOCS_STANDARD.md b/site/content/zh/contributions/DOCS_STANDARD.md new file mode 100644 index 00000000000..a60f18ab805 --- /dev/null +++ b/site/content/zh/contributions/DOCS_STANDARD.md @@ -0,0 +1,141 @@ +--- +title: "文档内容编写规范(中文)" +description: "本节讲述 Envoy Gateway 文档的编写或翻译规范,包括:格式,书写习惯建议等。" +--- + +中文内容的位置在 `site/content/zh` 目录中,具体内容和结构应与英文版本保持一致。 + +## 规范 {#standard} + +以下定义了一些编写规范,并提供示例和对应 Markdown 写法。 + +### 中英文混排 {#mixed-chinese-and-english} + +当内容中存在中文和英文混排的时候中英文间需要加一个空格, +中文与中文之间无需空格(即使某个中文是链路的一部分也不需要空格): + +**示例:** + +这里有中文和 English 混排。 +可以跳转到[规范](#standard)处重新阅读。 + +```md +这里有中文和 English 混排。 +可以跳转到[规范](#standard)处重新阅读。 +``` + +### 粗体 {#bold} + +在中文内容中建议一律使用两个星号表示粗体: + +**示例:** + +其中**非常重要**的内容是 + +```md +其中**非常重要**的内容是 +``` + +### 标点符号 {#punctuation} + +中文内容中遇到的标点符号都要用全角, +无论中英文内容与全角标点符号之间无需空格(即使某个中文是在加粗格式之中也不需要空格) + +**示例:** + +无法确认吗?确认无误(没有任何拼写错误)后,可以继续后面的步骤。 +安装 Envoy Gateway(通过命令)**结束后**,查看相关 Service。 + +```md +无法确认吗?确认无误(没有任何拼写错误)后,可以继续后面的步骤。 +安装 Envoy Gateway(通过命令)**结束后**,查看相关 Service。 +``` + +### 锚 {#anchor} + +标题要添加英文锚(anchor),用于在其他内容中保持引用定位的一致性: + +**示例:** + +#### 示例 {#example} + +```md +#### 示例 {#example} +``` + +### 无需翻译的情况 {#no-need-for-translation} + +如果内容中的英文是命令,特定专有名词,如 CRD 名称,协议名称等,请保持大小写与原本定义一致: + +**示例:** + +使用 curl 命令发起 HTTP 请求。 +在 kind 集群中添加 Gateway 资源,创建 Service 和 Deployment。 + +```md +使用 curl 命令发起 HTTP 请求。 +在 kind 集群中添加 Gateway 资源,创建 Service 和 Deployment。 +``` + +### 英文复数处理 {#english-plural} + +大部分情况遇到英文的复数形式请按需调整为单数: + +**示例:** + +英文:Delete all Services in Kubernetes. + +中文:删除所有 Kubernetes 中的 Service。 + +```md +英文:Delete all Services in Kubernetes. +中文:删除所有 Kubernetes 中的 Service。 +``` + +### 换行断句 {#line-break} + +如果一句话很长,尽量按照本身的句子进行断句换行,通常一行内容保持在 40-60 字符,方便 Review: + +**示例:** + +这是一个长句子,在网页中查看,它是一整段话, +不会由于在 Markdown 编写时换行而另起一段,而在 Markdown 编写时, +只要换行间隔不多于一个换行,他们始终将保持一个段落。 + +而这句话则会另起一段! + +```md +这是一个长句子,在网页中查看,它是一整段话, +不会由于在 Markdown 编写时换行而另起一段,而在 Markdown 编写时, +只要换行间隔不多于一个换行,他们始终将保持一个段落。 + +而这句话则会另起一段! +``` + +### 使用“您” {#second-person} + +第二人称代词统一使用“您”: + +**示例:** + +至此,您已经了解了中文文档内容编写规范! + +```md +至此,您已经了解了中文文档内容编写规范! +``` + +### 必要时意译 {#free-translation} + +翻译时有些情况需要使用意译代替直译: + +**示例:** + +英文原文:He is as cool as a cucumber. + +直译成中文:他像黄瓜一样冷静。 + +更好的翻译可能是:他泰然自若,从容不迫。 + +## 欢迎贡献 {#welcome-to-contribute} + +以上规范参考了一些开源社区中文内容贡献者日常贡献中的约定俗成的做法,如有不适合或需要改进的,欢迎提出您的建议! diff --git a/site/content/zh/contributions/RELEASING.md b/site/content/zh/contributions/RELEASING.md new file mode 100644 index 00000000000..e1412e4eb7c --- /dev/null +++ b/site/content/zh/contributions/RELEASING.md @@ -0,0 +1,256 @@ +--- +title: "发布流程" +description: "本文描述了 Envoy Gateway 的发布流程。" +--- + +本文档指导维护人员完成创建 Envoy Gateway 版本的过程。 + +- [候选版本](#release-candidate) + - [先决条件](#prerequisites) + - [设置 Cherry Picker Action](#setup-cherry-picker-action) +- [次要版本](#minor-release) + - [先决条件](#prerequisites-1) +- [公告发布](#announce-the-release) + +## 候选版本 {#release-candidate} + +应使用以下步骤创建候选版本。 + +### 先决条件 {#prerequisites} + +- 具备推送到 Envoy Gateway 仓库的权限。 + +设置环境变量以供后续步骤使用: + +```shell +export MAJOR_VERSION=0 +export MINOR_VERSION=3 +export RELEASE_CANDIDATE_NUMBER=1 +export GITHUB_REMOTE=origin +``` + +1. 克隆仓库,迁出 `main` 分支,确保它是最新的,并且您的本地分支是干净的。 +2. 创建一个主题分支,用于添加发布说明并使用发布版本更新 [VERSION][] 文件。 + 请参阅之前的[发布说明][]和 [VERSION][] 了解更多详细信息。 +3. 签名、提交更改并将其推送到您 Fork 的分支。 +4. 提交 [Pull Request][] 将更改合并到 `main` 分支中。 + 在您的 PR 合并并且[构建和测试][]成功完成之前,请勿继续。 +5. 从 `main` 创建一个新的发布分支。发布分支应命名为 + `release/v${MAJOR_VERSION}.${MINOR_VERSION}`,例如 `release/v0.3`。 + + ```shell + git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION} + ``` + +6. 将分支推送到 Envoy Gateway 仓库。 + + ```shell + git push ${GITHUB_REMOTE} release/v${MAJOR_VERSION}.${MINOR_VERSION} + ``` + +7. 创建主题分支,用于将 Envoy Proxy 镜像和 Envoy Ratelimit 镜像更新为版本支持的 Tag。 + 有关更新镜像 Tag 的更多详细信息,请参阅 [PR #2098][]。 +8. 签名、提交更改并将其推送到您 Fork 的分支。 +9. 提交 [Pull Request][] 将更改合并到 `release/v${MAJOR_VERSION}.${MINOR_VERSION}` 分支中。 + 在您的 PR 已合并到发布分支并且 PR 的[构建和测试][]已完成之前,请勿继续。 +10. 确保您的发布分支是最新的,并使用候选版本编号为发布分支的头部打 Tag。 + + ```shell + git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} Release Candidate' + ``` + +11. 将 Tag 推送到 Envoy Gateway 仓库。 + + ```shell + git push ${GITHUB_REMOTE} v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} + ``` + +12. 这将触发[发布 GitHub Action][] 并生成发布版本、发布制品等内容。 +13. 确认[发布工作流程][]已成功完成。 +14. 确认具有正确发布标签的 Envoy Gateway [镜像][]已发布到 Docker Hub。 +15. 确认[版本][]已被创建。 +16. 请注意,[快速入门][]参考资料并未针对候选版本进行更新。 + 但是,请通过手动更新链接来使用候选版本测试快速入门步骤。 +17. [生成][] GitHub 变更日志。 +18. 确保在编辑 GitHub 版本时选中 "这是一个 pre-release" 复选框。 +19. 如果您在此过程中发现任何错误,请创建 Issue。 + +### 设置 Cherry Picker Action {#setup-cherry-picker-action} + +在发布分支切分后,RM(发布经理)应添加 +[Cherrypick Action](https://github.com/envoyproxy/gateway/blob/main/.github/workflows/cherrypick.yaml) Job 以进行目标发布。 + +配置如下所示: + +```yaml + cherry_pick_release_v0_4: + runs-on: ubuntu-latest + name: Cherry pick into release-v0.4 + if: ${{ contains(github.event.pull_request.labels.*.name, 'cherrypick/release-v0.4') && github.event.pull_request.merged == true }} + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + fetch-depth: 0 + - name: Cherry pick into release/v0.4 + uses: carloscastrojumo/github-cherry-pick-action@a145da1b8142e752d3cbc11aaaa46a535690f0c5 # v1.0.9 + with: + branch: release/v0.4 + title: "[release/v0.4] {old_title}" + body: "Cherry picking #{old_pull_request_id} onto release/v0.4" + labels: | + cherrypick/release-v0.4 + # 将发布经理名字放在这里 + reviewers: | + AliceProxy +``` + +将 `v0.4` 替换为真实的分支名称,并将 `AliceProxy` 替换为 RM 的真实名称。 + +## 次要版本 {#minor-release} + +应使用以下步骤创建次要版本。 + +### 先决条件 {#prerequisites-1} + +- 具备推送到 Envoy Gateway 仓库的权限。 +- 版本分支是从相应候选版本中切分的。 + 有关切分候选版本的更多详细信息,请参阅[候选版本](#release-candidate)部分。 + +设置环境变量以供后续步骤使用: + +```shell +export MAJOR_VERSION=0 +export MINOR_VERSION=3 +export GITHUB_REMOTE=origin +``` + +1. 克隆仓库,迁出 `main` 分支,确保它是最新的,并且您的本地分支是干净的。 +2. 创建主题分支以添加发布说明、发布公告和具体版本的发布文档。 + + 1. 创建发布说明。请参阅之前的[发布说明][]以了解更多详细信息。 + **注意:**发布说明应该是候选版本发布说明以及自发布候选版以来的任何更改的累积。 + 2. 创建发布公告。请参阅 [PR #635] 作为发布公告示例。 + 3. 将版本包含在兼容性矩阵中。请参阅 [PR #1002] 作为示例。 + 4. 生成具体版本的发布文档: + + ``` shell + make docs-release TAG=v${MAJOR_VERSION}.${MINOR_VERSION}.0 + ``` + + 5. 更新 `site/content/en/_index.md` 中的 `Get Started` 和 `Contributing` 按钮引用链接: + + ```shell + + Get Started + + + Contributing + + ``` + + 6. 更新 `site/hugo.toml` 中菜单上的 `Documentation` 引用链接: + + ```shell + [[menu.main]] + name = "Documentation" + weight = -101 + pre = "" + url = "/v0.5.0" + ``` + +3. 签名、提交更改并将其推送到您 Fork 的分支。 +4. 提交 [Pull Request][] 将更改合并到 `main` 分支中。 + 在您的所有 PR 合并并且最终 PR 的[构建和测试][]完成之前,请勿继续。 + +5. 迁出发布分支。 + + ```shell + git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION} + ``` + +6. 如果发布分支的提示与 `main` 的提示不匹配,则执行以下操作: + + 1. 从发布分支创建主题分支。 + 2. 从 `main` 中 Cherry-pick 与发布分支不同的提交。 + 3. 在本地运行测试,例如 `make lint`。 + 4. 签名、提交主题分支并将其推送到您 Fork 的 Envoy Gateway 分支。 + 5. 提交 PR,将您的 Fork 分支中的主题合并到 Envoy Gateway 发布分支中。 + 6. 在 PR 合并以及该合并的 PR 的 CI 通过之前,不要继续。 + 7. 如果您仍在主题分支,请切换到发布分支: + + ```shell + git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION} + ``` + + 8. 确保您的本地发布分支是最新的: + + ```shell + git pull $GITHUB_REMOTE release/v${MAJOR_VERSION}.${MINOR_VERSION} + ``` + +7. 使用发布信息为发布分支的头部打 Tag。例如: + + ```shell + git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0 -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0 Release' + ``` + + **注意:**Tag 版本与发布分支的不同之处在于包含 `.0` 补丁版本。 + +8. 将标签推送到 Envoy Gateway 仓库。 + + ```shell + git push origin v${MAJOR_VERSION}.${MINOR_VERSION}.0 + ``` + +9. 这将触发[发布 GitHub Action][] 并生成发布版本、发布制品等内容。 +10. 确认[发布工作流程][]已成功完成。 +11. 确认具有正确发布标签的 Envoy Gateway [镜像][]已发布到 Docker Hub。 +12. 确认[版本][]已被创建。 +13. 确认[快速入门][]中的步骤按预期工作。 +14. [生成][] GitHub 变更日志并保持发布页面的开头包含以下文本: + + ```console + # Release Announcement + + Check out the [v${MAJOR_VERSION}.${MINOR_VERSION} release announcement] + (https://gateway.envoyproxy.io/releases/v${MAJOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release. + ``` + +如果您在此过程中发现任何错误,请创建 Issue。 + +## 公告发布 {#announce-the-release} + +让所有人都知道这次发布非常重要。使用以下步骤来公告发布。 + +1. 在 Envoy Gateway Slack 频道中设置发布信息。例如: + + ```shell + Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION} has been released: https://github.com/envoyproxy/gateway/releases/tag/v${MAJOR_VERSION}.${MINOR_VERSION}.0 + ``` + +2. 向 Envoy Gateway Slack 频道发送消息。例如: + + ```shell + On behalf of the entire Envoy Gateway community, I am pleased to announce the release of Envoy Gateway + v${MAJOR_VERSION}.${MINOR_VERSION}. A big thank you to all the contributors that made this release possible. + Refer to the official v${MAJOR_VERSION}.${MINOR_VERSION} announcement for release details and the project docs + to start using Envoy Gateway. + ... + ``` + + 链接到 GitHub 版本和突出显示该版本的版本公告页面。 + +[发布说明]: https://github.com/envoyproxy/gateway/tree/main/release-notes +[Pull Request]: https://github.com/envoyproxy/gateway/pulls +[快速入门]: https://github.com/envoyproxy/gateway/blob/main/docs/user/quickstart.md +[构建和测试]: https://github.com/envoyproxy/gateway/blob/main/.github/workflows/build_and_test.yaml +[发布 GitHub Action]: https://github.com/envoyproxy/gateway/blob/main/.github/workflows/release.yaml +[发布工作流程]: https://github.com/envoyproxy/gateway/actions/workflows/release.yaml +[镜像]: https://hub.docker.com/r/envoyproxy/gateway/tags +[版本]: https://github.com/envoyproxy/gateway/releases +[生成]: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes +[PR #635]: https://github.com/envoyproxy/gateway/pull/635 +[PR #2098]: https://github.com/envoyproxy/gateway/pull/2098 +[PR #1002]: https://github.com/envoyproxy/gateway/pull/1002 +[VERSION]: https://github.com/envoyproxy/gateway/blob/main/VERSION diff --git a/site/content/zh/contributions/_index.md b/site/content/zh/contributions/_index.md new file mode 100644 index 00000000000..b9719c4725f --- /dev/null +++ b/site/content/zh/contributions/_index.md @@ -0,0 +1,8 @@ ++++ +title = "参与其中" +description = "本节包含与贡献相关的内容" +linktitle = "参与其中" + +[[cascade]] +type = "docs" ++++ \ No newline at end of file diff --git a/site/content/zh/latest/contributions/DEVELOP.md b/site/content/zh/latest/contributions/DEVELOP.md new file mode 100644 index 00000000000..9d211dd6277 --- /dev/null +++ b/site/content/zh/latest/contributions/DEVELOP.md @@ -0,0 +1,158 @@ +--- +title: 开发者指南 +description: 本节告知开发者如何开发 Envoy Gateway。 +weight: 2 +--- + +Envoy Gateway 使用基于 [make][] 的构建系统构建。我们的 CI 基于 [Github Actions][],使用 [workflows][]。 + +## 前置条件 {#prerequisites} + +### go {#go} + +* 版本:1.22 +* 安装指南:https://go.dev/doc/install + +### make {#make} + +* 推荐版本:4.0 or later +* 安装指南:https://www.gnu.org/software/make + +### docker {#docker} + +* 如果您想构建一个 Docker 镜像或者在 Docker 内部运行 `make` +* 推荐版本:20.10.16 +* 安装指南:https://docs.docker.com/engine/install + +### python3 {#python3} + +* 需要 `python3` 程序 +* 一个可正常执行的 `venv` module 是必要的;这是标准的一部分, + 但某些发行版(例如 Debian 和 Ubuntu)使用 stub 来替代它,并要求您单独安装 `python3-venv` 包。 + +## 快速开始 {#quickstart} + +* 运行 `make help` 来查看所有可构建,可测试,可运行的的目标,并运行 Envoy Gateway。 + +### 构建 {#building} + +* 运行 `make build` 来构建所有的二进制文件。 +* 运行 `make build BINS="envoy-gateway"` 来构建 Envoy Gateway 库。 +* 运行 `make build BINS="egctl"` 来构建 egctl 库。 + +**注意:** 上述二进制文件会在 `bin/$OS/$ARCH` 目录下生成,例如, `bin/linux/amd64/`。 + +### 测试 {#testing} + +* 运行 `make test` 来运行 golang 测试。 + +* 运行 `make testdata` 来生成 golden YAML 测试数据文件。 + +### 运行代码检查器(Linters) {#running-linters} + +* 运行 `make lint` 来确保您的代码可以通过所有的代码检查工具检查。 + **注意:**`golangci-lint` 在[这里](https://github.com/envoyproxy/gateway/blob/main/tools/linter/golangci-lint/.golangci.yml)。 + +### 构建和推送镜像 {#building-and-pushing-the-image} + +* 运行 `IMAGE=docker.io/you/gateway-dev make image` 来构建 Docker 镜像。 +* 运行 `IMAGE=docker.io/you/gateway-dev make push-multiarch` 来构建和推送支持多架构的 Docker 镜像。 + +**注意:** 使用您注册的镜像名称来替代 `IMAGE`。 + +### 为测试或开发部署 Envoy Gateway {#deploying-envoy-gateway-for-test-dev} + +* 运行 `make create-cluster` 来创建一个 [Kind][] 集群。 + +#### 可选 1:使用最新的 [gateway-dev][] 镜像 {#use-the-latest-gateway-dev-image} + +* 运行 `TAG=latest make kube-deploy` 来使用最新的镜像在 Kind 集群中部署 Envoy Gateway。 + 替换 `latest` 来使用不同的镜像标签。 + +#### 可选 2:使用定制的镜像 {#use-a-custom-image} + +* 运行 `make kube-install-image` 来从当前分支来构建一个镜像,然后将镜像载入 Kind 集群中。 +* 运行 `IMAGE_PULL_POLICY=IfNotPresent make kube-deploy` 来使用定制化镜像将 Envoy Gateway 安装到 Kind 集群中。 + +### 在 Kubernetes 中部署 Envoy Gateway {#deploying-envoy-gateway-inkubernetes} + +* 运行 `TAG=latest make kube-deploy` 使用最新镜像将 Envoy Gateway 部署到 Kubernetes 集群中(当前 kube 上下文指向的集群)。 + 在命令前面加上 `IMAGE` 或替换 `TAG` 以使用不同的 Envoy Gateway 镜像或标签。 +* 运行 `make kube-undeploy` 在集群中卸载 Envoy Gateway。 + +**注意:** Envoy Gateway 针对 Kubernetes v1.24.0 进行了测试。 + +### 创建示例 {#demo-setup} + +* 运行 `make kube-demo` 来部署一个示例后端服务, + GatewayClass,Gateway 和 HTTPRoute 资源(类似于[快速开始][]文档中概述的步骤)并且测试配置。 +* 运行 `make kube-demo-undeploy` 来删除由 `make kube-demo` 命令创建的资源。 + +### 运行 Gateway API 一致性测试 {#run-gateway-api-conformance-tests} + +以下命令将 Envoy Gateway 部署到 Kubernetes 集群并运行 Gateway API 一致性测试。 +请参阅 Gateway API [一致性主页][]了解有关测试的更多信息。如果 Envoy Gateway 已安装, +请运行 `TAG=latest make run-conformance` 运行一致性测试。 + +#### 在 Linux 主机中 {#on-a-linux-host} + +* 运行 `TAG=latest make conformance` 来创建一个 Kind 集群, 使用最新的 [gateway-dev][] 镜像安装 Envoy Gateway, + 然后运行 Gateway API 一致性测试。 + +#### 在 Mac 主机中 {#on-a-machost} + +由于 Mac 不支持将 Docker 网络[直接暴露][]到 Mac 主机,因此请使用以下方法之一来运行一致性测试: + +* 在 [Kubernetes 支持][]下部署 Kubernetes 集群或使用 Docker Desktop 然后运行 + `TAG=latest make kube-deploy run-conformance`。 + 这将使用最新的 [gateway-dev][] 镜像安装 Envoy Gateway 到当前 kubectl 上下文连接到的 Kubernetes 集群中,并运行一致性测试。 + 使用 `make kube-undeploy` 来卸载 Envoy Gateway。 +* 安装并执行 [Docker Mac Net Connect][mac_connect] 然后运行 `TAG=latest make conformance`。 + +**注意:** 在命令前加上 `IMAGE` 或替换 `TAG` 以使用不同的 Envoy Gateway 镜像或标签。 +如果未指定 `TAG` ,则会默认使用当前分支的短 SHA。 + +### 调试 Envoy 配置 {#debugging-the-envoy-config} + +查看 Envoy Gateway 正在使用的 Envoy 配置的一种简单方法是将 Envoy 的管理端口(当前为 `19000`)转发到一个本地端口上,这样就可以直接在本地进行访问。 + +获取 Envoy 部署的名称。下面是 Gateway `eg` 在 `default` 命名空间中的例子: + +```shell +export ENVOY_DEPLOYMENT=$(kubectl get deploy -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') +``` + +对其管理端口进行端口转发: + +```shell +kubectl port-forward deploy/${ENVOY_DEPLOYMENT} -n envoy-gateway-system 19000:19000 +``` + +现在您可以访问 `127.0.0.1:19000/config_dump` 来查看 Envoy 正在使用的配置。 + + +[Envoy 管理接口][]上还有许多其他端点,这些端点在调试时可能会有所帮助。 + +### JWT 测试 {#jwt-testing} + +示例 [JSON Web Token(JWT)][jwt] 和 [JSON Web Key Set(JWKS)][jwks] 用于[请求认证][]任务。 +JWT 由 [JWT 调试器][]使用 `RS256` 算法创建。来自 JWT 的公钥验证签名已复制到 [JWK Creator][] 以生成 JWK。 +JWK Creator 配置了匹配的设置,即 `Signing` 公钥使用和 `RS256` 算法。 +生成的 JWK 包装在 JWKS 结构中并被托管在仓库中。 + +[快速开始]: ../../tasks/quickstart +[make]: https://www.gnu.org/software/make/ +[Github Actions]: https://docs.github.com/en/actions +[workflows]: https://github.com/envoyproxy/gateway/tree/main/.github/workflows +[Kind]: https://kind.sigs.k8s.io/ +[一致性主页]: https://gateway-api.sigs.k8s.io/concepts/conformance/ +[直接暴露]: https://kind.sigs.k8s.io/docs/user/loadbalancer/ +[Kubernetes 支持]: https://docs.docker.com/desktop/kubernetes/ +[gateway-dev]: https://hub.docker.com/r/envoyproxy/gateway-dev/tags +[mac_connect]: https://github.com/chipmk/docker-mac-net-connect +[Envoy 管理接口]: https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface +[jwt]: https://tools.ietf.org/html/rfc7519 +[jwks]: https://tools.ietf.org/html/rfc7517 +[请求认证]: https://gateway.envoyproxy.io/latest/tasks/security/jwt-authentication/ +[JWT 调试器]: https://jwt.io/ +[JWK Creator]: https://russelldavies.github.io/jwk-creator/ diff --git a/site/content/zh/latest/contributions/_index.md b/site/content/zh/latest/contributions/_index.md deleted file mode 100644 index 86f9164979d..00000000000 --- a/site/content/zh/latest/contributions/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 参与其中 -description: "本节包含与贡献相关的内容" -weight: 100 ---- diff --git a/site/content/zh/latest/install/_index.md b/site/content/zh/latest/install/_index.md new file mode 100644 index 00000000000..85e2d7fa5fa --- /dev/null +++ b/site/content/zh/latest/install/_index.md @@ -0,0 +1,5 @@ +--- +title: 安装 +description: 本节包含关于安装 Envoy Gateway 的内容。 +weight: 70 +--- diff --git a/site/content/zh/latest/install/matrix.md b/site/content/zh/latest/install/matrix.md new file mode 100644 index 00000000000..aa5a7e79cdd --- /dev/null +++ b/site/content/zh/latest/install/matrix.md @@ -0,0 +1,18 @@ +--- +title: 兼容性表格 +description: 本节包含关于 Envoy Gateway 的兼容性表格。 +--- + +Envoy Gateway 依赖于 Envoy Proxy 和 Gateway API,并在 Kubernetes 集群中运行。 +这些产品的所有版本并非都可以与 Envoy Gateway 一起运行。下面列出了支持的版本组合; +**粗体**类型表示实际编译到每个 Envoy Gateway 版本中的 Envoy Proxy 和 Gateway API 的版本。 + +| Envoy Gateway 版本 | Envoy Proxy 版本 | Rate Limit 版本 | Gateway API 版本 | Kubernetes 版本 | +|-----------------------|-----------------------------|--------------------|---------------------|----------------------------| +| v1.0.0 | **distroless-v1.29.2** | **19f2079f** | **v1.0.0** | v1.26, v1.27, v1.28, v1.29 | +| v0.6.0 | **distroless-v1.28-latest** | **b9796237** | **v1.0.0** | v1.26, v1.27, v1.28 | +| v0.5.0 | **v1.27-latest** | **e059638d** | **v0.7.1** | v1.25, v1.26, v1.27 | +| v0.4.0 | **v1.26-latest** | **542a6047** | **v0.6.2** | v1.25, v1.26, v1.27 | +| v0.3.0 | **v1.25-latest** | **f28024e3** | **v0.6.1** | v1.24, v1.25, v1.26 | +| v0.2.0 | **v1.23-latest** | | **v0.5.1** | v1.24 | +| latest | **dev-latest** | **master** | **v1.0.0** | v1.26, v1.27, v1.28, v1.29 | diff --git a/site/content/zh/latest/tasks/_index.md b/site/content/zh/latest/tasks/_index.md new file mode 100644 index 00000000000..08baa38daf1 --- /dev/null +++ b/site/content/zh/latest/tasks/_index.md @@ -0,0 +1,5 @@ +--- +title: "任务" +weight: 2 +description: 通过任务学习 Envoy Gateway 实践。 +--- diff --git a/site/content/zh/latest/tasks/quickstart.md b/site/content/zh/latest/tasks/quickstart.md new file mode 100644 index 00000000000..aa94962e71a --- /dev/null +++ b/site/content/zh/latest/tasks/quickstart.md @@ -0,0 +1,125 @@ +--- +title: "快速开始" +weight: 1 +description: 只需几个简单的步骤即可开始使用 Envoy Gateway。 +--- + +本指南将帮助您通过几个简单的步骤开始使用 Envoy Gateway。 + +## 前置条件 {#prerequisites} + +一个 Kubernetes 集群。 + +**注意:** 请参考[兼容性表格](../install/matrix)来查看所支持的 Kubernetes 版本。 + +**注意:** 如果您的 Kubernetes 集群没有负载均衡器实现,我们建议安装一个 +,以便 Gateway 资源能够关联一个地址。我们推荐使用 [MetalLB](https://metallb.universe.tf/installation/)。 + +## 安装 {#installation} + +安装 Gateway API CRD 和 Envoy Gateway: + +```shell +helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace +``` + +等待 Envoy Gateway 至可用后: + +```shell +kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available +``` + +安装 GatewayClass,Gateway,HTTPRoute 和示例应用: + +```shell +kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml -n default +``` + +**注意:**[`quickstart.yaml`] 定义了 Envoy Gateway 将侦听其全局可路由 IP 地址上端口 +80 上的流量,以便轻松使用浏览器测试 Envoy Gateway。当 Envoy Gateway 看到它的侦听器使用特权端口(<1024), +它将在内部映射到非特权端口,因此 Envoy Gateway 不需要额外的特权。 +了解此映射很重要,当您调试时您可能需要将其考虑在内。 + +[`quickstart.yaml`]: https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml + +## 测试配置 {#testing-the-configuration} + +{{< tabpane text=true >}} +{{% tab header="不使用负载均衡器" %}} + +获取由示例 Gateway 创建的 Envoy 服务的名称: + +```shell +export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}') +``` + +端口转发到 Envoy 服务: + +```shell +kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 & +``` + +通过 Envoy 代理,使用 curl 测试示例应用: + +```shell +curl --verbose --header "Host: www.example.com" http://localhost:8888/get +``` + +{{% /tab %}} + +{{% tab header="使用外部负载均衡器" %}} + +您还可以通过将流量发送到外部 IP 来测试相同的功能。运行下面的命令可以获取 Envoy 服务的外部 IP 地址: + +```shell +export GATEWAY_HOST=$(kubectl get svc/${ENVOY_SERVICE} -n envoy-gateway-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +``` + +在某些环境中,负载均衡器可能会公开主机名而不是 IP 地址,如果是这样,将上述命令中的 `ip` 替换为 `hostname` 。 + +使用 curl 来通过 Envoy Proxy 访问示例应用: + +```shell +curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get +``` + +{{% /tab %}} +{{< /tabpane >}} + +## 接下来的探索? {#what-to-explore-next} + +在快速开始(本节),您将: + +- 完成 Envoy Gateway 的安装 +- 部署一个后端服务和一个网关 +- 使用 Kubernetes Gateway API 资源 [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway/) 和 [HttpRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/) 配置网关。将网关传入的 HTTP 请求转发到后端服务。 + +以下是建议的后续任务列表,可指导您探索 Envoy Gateway: + +- [HTTP 路由](https://gateway.envoyproxy.io/latest/tasks/traffic/http-routing/) +- [流量拆分](https://gateway.envoyproxy.io/latest/tasks/traffic/http-traffic-splitting/) +- [安全网关](https://gateway.envoyproxy.io/latest/tasks/security/secure-gateways/) +- [全局限流](https://gateway.envoyproxy.io/latest/tasks/traffic/global-rate-limit/) +- [gRPC 路由](https://gateway.envoyproxy.io/latest/tasks/traffic/grpc-routing/) + +请查看与您使用情况相符的场景下的[任务](./)部分。Envoy Gateway 的任务按照流量管理、安全、扩展性、可观察性和运维等分类组织。 + +## 清理 {#clean-up} + +请按照本节中的步骤将快速入门中的所有内容卸载。 + +删除 GatewayClass,Gateway,HTTPRoute 和示例应用: + +```shell +kubectl delete -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml --ignore-not-found=true +``` + +删除 Gateway API CRD 和 Envoy Gateway: + +```shell +helm uninstall eg -n envoy-gateway-system +``` + +## 接下来 {#next-steps} + +浏览[开发者指南](../contributions/develop) ,了解如何参与项目。 diff --git a/site/go.mod b/site/go.mod index ec0974f5614..e5dbc323868 100644 --- a/site/go.mod +++ b/site/go.mod @@ -1,6 +1,6 @@ module github.com/google/docsy-example -go 1.12 +go 1.22.2 require ( github.com/FortAwesome/Font-Awesome v0.0.0-20230327165841-0698449d50f2 // indirect diff --git a/site/hugo.toml b/site/hugo.toml index a658bd29a28..b5a93a66168 100644 --- a/site/hugo.toml +++ b/site/hugo.toml @@ -238,47 +238,47 @@ enable = true desc = "与其他项目开发人员沟通" [menu] + [[menu.main]] + name = "Contributions" + weight = -98 + url = "/contributions" [[menu.main]] name = "Blog" weight = -99 - pre = "" url = "/blog" [[menu.main]] name = "About" weight = -100 - pre = "" url = "/about" [[menu.main]] name = "Announcements" weight = -101 - pre = "" url = "/announcements" [[menu.main]] name = "Documentation" weight = -102 - pre = "" url = "/v1.0.1" # i18n for Chinese + [[languages.zh.menu.main]] + name = "贡献" + weight = -98 + url = "/contributions" [[languages.zh.menu.main]] name = "博客" weight = -99 - pre = "" url = "/blog" [[languages.zh.menu.main]] name = "关于" weight = -100 - pre = "" url = "/about" [[languages.zh.menu.main]] name = "公告" weight = -101 - pre = "" url = "/announcements" [[languages.zh.menu.main]] name = "文档" weight = -102 - pre = "" url = "/latest" [[params.versions]] diff --git a/test/cel-validation/backendtrafficpolicy_test.go b/test/cel-validation/backendtrafficpolicy_test.go index 673ed81ef4d..2cefef85e3e 100644 --- a/test/cel-validation/backendtrafficpolicy_test.go +++ b/test/cel-validation/backendtrafficpolicy_test.go @@ -16,9 +16,7 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" "k8s.io/utils/ptr" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" @@ -436,8 +434,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { { desc: " valid config: min, max, nil", mutate: func(btp *egv1a1.BackendTrafficPolicy) { - valMax := pointer.Int64(4294967295) - valMin := pointer.Int64(0) + valMax := ptr.To[int64](4294967295) + valMin := ptr.To[int64](0) btp.Spec = egv1a1.BackendTrafficPolicySpec{ TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ @@ -459,8 +457,8 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { { desc: " invalid config: min and max values", mutate: func(btp *egv1a1.BackendTrafficPolicy) { - valOverMax := pointer.Int64(4294967296) - valUnderMin := pointer.Int64(-1) + valOverMax := ptr.To[int64](4294967296) + valUnderMin := ptr.To[int64](-1) btp.Spec = egv1a1.BackendTrafficPolicySpec{ TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ @@ -812,7 +810,6 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { { desc: "valid count of Global rate limit rules items", mutate: func(btp *egv1a1.BackendTrafficPolicy) { - rules := make([]egv1a1.RateLimitRule, 64) rule := egv1a1.RateLimitRule{ Limit: egv1a1.RateLimitValue{ @@ -845,7 +842,6 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { { desc: "invalid count of Global rate limit rules items", mutate: func(btp *egv1a1.BackendTrafficPolicy) { - rules := make([]egv1a1.RateLimitRule, 65) rule := egv1a1.RateLimitRule{ Limit: egv1a1.RateLimitValue{ diff --git a/test/cel-validation/clienttrafficpolicy_test.go b/test/cel-validation/clienttrafficpolicy_test.go index 5f5e56fec1c..2b132ea969e 100644 --- a/test/cel-validation/clienttrafficpolicy_test.go +++ b/test/cel-validation/clienttrafficpolicy_test.go @@ -16,7 +16,6 @@ import ( "time" "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -150,9 +149,11 @@ func TestClientTrafficPolicyTarget(t *testing.T) { Name: gwapiv1a2.ObjectName("eg"), }, }, - TLS: &egv1a1.TLSSettings{ - MinVersion: ptr.To(egv1a1.TLSv12), - MaxVersion: ptr.To(egv1a1.TLSv11), + TLS: &egv1a1.ClientTLSSettings{ + TLSSettings: egv1a1.TLSSettings{ + MinVersion: ptr.To(egv1a1.TLSv12), + MaxVersion: ptr.To(egv1a1.TLSv11), + }, }, } }, @@ -171,8 +172,10 @@ func TestClientTrafficPolicyTarget(t *testing.T) { Name: gwapiv1a2.ObjectName("eg"), }, }, - TLS: &egv1a1.TLSSettings{ - MaxVersion: ptr.To(egv1a1.TLSv11), + TLS: &egv1a1.ClientTLSSettings{ + TLSSettings: egv1a1.TLSSettings{ + MaxVersion: ptr.To(egv1a1.TLSv11), + }, }, } }, @@ -217,8 +220,10 @@ func TestClientTrafficPolicyTarget(t *testing.T) { }, }, HTTP3: &egv1a1.HTTP3Settings{}, - TLS: &egv1a1.TLSSettings{ - Ciphers: []string{"[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]"}, + TLS: &egv1a1.ClientTLSSettings{ + TLSSettings: egv1a1.TLSSettings{ + Ciphers: []string{"[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]"}, + }, }, } }, @@ -235,9 +240,11 @@ func TestClientTrafficPolicyTarget(t *testing.T) { Name: gwapiv1a2.ObjectName("eg"), }, }, - TLS: &egv1a1.TLSSettings{ - MinVersion: ptr.To(egv1a1.TLSv13), - Ciphers: []string{"[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]"}, + TLS: &egv1a1.ClientTLSSettings{ + TLSSettings: egv1a1.TLSSettings{ + MinVersion: ptr.To(egv1a1.TLSv13), + Ciphers: []string{"[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]"}, + }, }, } }, @@ -286,6 +293,46 @@ func TestClientTrafficPolicyTarget(t *testing.T) { "spec.connection.bufferLimit: Invalid value: \"\": bufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"", }, }, + { + desc: "invalid InitialStreamWindowSize format", + mutate: func(ctp *egv1a1.ClientTrafficPolicy) { + ctp.Spec = egv1a1.ClientTrafficPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + HTTP2: &egv1a1.HTTP2Settings{ + InitialStreamWindowSize: ptr.To(resource.MustParse("15m")), + }, + } + }, + wantErrors: []string{ + "spec.http2.initialStreamWindowSize: Invalid value: \"\": initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"", + }, + }, + { + desc: "invalid InitialConnectionWindowSize format", + mutate: func(ctp *egv1a1.ClientTrafficPolicy) { + ctp.Spec = egv1a1.ClientTrafficPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + HTTP2: &egv1a1.HTTP2Settings{ + InitialConnectionWindowSize: ptr.To(resource.MustParse("15m")), + }, + } + }, + wantErrors: []string{ + "spec.http2.InitialConnectionWindowSize: Invalid value: \"\": initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"", + }, + }, } for _, tc := range cases { diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go index 4a179c84ec3..efad71d74f8 100644 --- a/test/cel-validation/envoyextensionpolicy_test.go +++ b/test/cel-validation/envoyextensionpolicy_test.go @@ -15,9 +15,12 @@ import ( "testing" "time" + "k8s.io/utils/ptr" + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) @@ -151,6 +154,129 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { "spec.targetRef: Invalid value: \"object\": this policy does not yet support the sectionName field", }, }, + + // ExtProc + { + desc: "ExtProc with BackendRef", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + }, + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "ExtProc with invalid BackendRef Group", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Group: ptr.To(gwapiv1.Group("unsupported")), + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + }, + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + } + }, + wantErrors: []string{" spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Core group."}, + }, + { + desc: "ExtProc with invalid BackendRef Kind", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Kind: ptr.To(gwapiv1.Kind("unsupported")), + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + }, + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + } + }, + wantErrors: []string{"spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Service kind."}, + }, + { + desc: "ExtProc with invalid fields", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + ProcessingMode: &egv1a1.ExtProcProcessingMode{ + Request: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("not-a-body-mode")), + }, + Response: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("not-a-body-mode")), + }, + }, + }, + }, + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + } + }, + wantErrors: []string{ + "spec.extProc[0].processingMode.response.body: Unsupported value: \"not-a-body-mode\": supported values: \"Streamed\", \"Buffered\", \"BufferedPartial\"", + "spec.extProc[0].processingMode.request.body: Unsupported value: \"not-a-body-mode\": supported values: \"Streamed\", \"Buffered\", \"BufferedPartial\"", + }, + }, } for _, tc := range cases { diff --git a/test/cel-validation/envoyproxy_test.go b/test/cel-validation/envoyproxy_test.go index b7850a084ad..a4c9621c418 100644 --- a/test/cel-validation/envoyproxy_test.go +++ b/test/cel-validation/envoyproxy_test.go @@ -120,6 +120,56 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{"allocateLoadBalancerNodePorts can only be set for LoadBalancer type"}, }, + { + desc: "loadBalancerSourceRanges-pass-case1", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyService: &egv1a1.KubernetesServiceSpec{ + Type: ptr.To(egv1a1.ServiceTypeLoadBalancer), + LoadBalancerSourceRanges: []string{"1.1.1.1"}, + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "loadBalancerSourceRanges-pass-case2", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyService: &egv1a1.KubernetesServiceSpec{ + Type: ptr.To(egv1a1.ServiceTypeClusterIP), + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "loadBalancerSourceRanges-fail", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyService: &egv1a1.KubernetesServiceSpec{ + Type: ptr.To(egv1a1.ServiceTypeClusterIP), + LoadBalancerSourceRanges: []string{"1.1.1.1"}, + }, + }, + }, + } + }, + wantErrors: []string{"loadBalancerSourceRanges can only be set for LoadBalancer type"}, + }, { desc: "ServiceTypeLoadBalancer-with-valid-IP", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -321,6 +371,33 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{"If AccessLogFormat type is JSON, json field needs to be set"}, }, + { + desc: "ProxyAccessLogSink-with-TypeALS-but-no-als", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: egv1a1.ProxyAccessLogFormatTypeJSON, + JSON: map[string]string{ + "foo": "bar", + }, + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeALS, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"If AccessLogSink type is ALS, als field needs to be set"}, + }, { desc: "ProxyAccessLogSink-with-TypeFile-but-no-file", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -399,6 +476,216 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{}, }, + { + desc: "accesslog-ALS", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: egv1a1.ProxyAccessLogFormatTypeJSON, + JSON: map[string]string{ + "attr1": "value1", + "attr2": "value2", + }, + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeALS, + ALS: &egv1a1.ALSEnvoyProxyAccessLog{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(9000)), + }, + }, + }, + Type: egv1a1.ALSEnvoyProxyAccessLogTypeHTTP, + }, + }, + }, + }, + }, + }, + }, + } + }, + }, + { + desc: "invalid-accesslog-ALS-type", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeALS, + ALS: &egv1a1.ALSEnvoyProxyAccessLog{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(9000)), + }, + }, + }, + Type: egv1a1.ALSEnvoyProxyAccessLogTypeTCP, + HTTP: &egv1a1.ALSEnvoyProxyHTTPAccessLogConfig{}, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"The http field may only be set when type is HTTP."}, + }, + { + desc: "invalid-accesslog-ALS-backendrefs", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeALS, + ALS: &egv1a1.ALSEnvoyProxyAccessLog{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, + }, + }, + Type: egv1a1.ALSEnvoyProxyAccessLogTypeHTTP, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"BackendRefs only supports Service Kind."}, + }, + { + desc: "invalid-accesslog-ALS-no-backendrefs", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeALS, + ALS: &egv1a1.ALSEnvoyProxyAccessLog{ + Type: egv1a1.ALSEnvoyProxyAccessLogTypeHTTP, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"Invalid value: \"null\""}, + }, + { + desc: "invalid-accesslog-ALS-empty-backendrefs", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeALS, + ALS: &egv1a1.ALSEnvoyProxyAccessLog{ + BackendRefs: []egv1a1.BackendRef{}, + Type: egv1a1.ALSEnvoyProxyAccessLogTypeHTTP, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"should have at least 1 items"}, + }, + { + desc: "invalid-accesslog-ALS-multi-backendrefs", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeALS, + ALS: &egv1a1.ALSEnvoyProxyAccessLog{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + }, + Type: egv1a1.ALSEnvoyProxyAccessLogTypeHTTP, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"must have at most 1 items"}, + }, { desc: "accesslog-OpenTelemetry", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -415,7 +702,7 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - Host: "0.0.0.0", + Host: ptr.To("0.0.0.0"), Port: 8080, }, }, @@ -443,9 +730,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, + }, }, }, }, @@ -456,7 +747,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"BackendRef only support Service Kind."}, + wantErrors: []string{"only support Service Kind."}, }, { desc: "accesslog-backendref", @@ -474,10 +765,14 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -489,6 +784,49 @@ func TestEnvoyProxyProvider(t *testing.T) { } }, }, + { + desc: "multi-accesslog-backendref", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"must have at most 1 items"}, + }, { desc: "accesslog-backendref-empty-kind", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -505,9 +843,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -519,6 +861,32 @@ func TestEnvoyProxyProvider(t *testing.T) { } }, }, + { + desc: "accesslog-backend-empty", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + AccessLog: &egv1a1.ProxyAccessLog{ + Settings: []egv1a1.ProxyAccessLogSetting{ + { + Format: egv1a1.ProxyAccessLogFormat{ + Type: "Text", + Text: ptr.To("[%START_TIME%]"), + }, + Sinks: []egv1a1.ProxyAccessLogSink{ + { + Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{}, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"host or backendRefs needs to be set"}, + }, { desc: "ProxyMetricSink-with-TypeOpenTelemetry-but-no-openTelemetry", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -546,7 +914,7 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - Host: "0.0.0.0", + Host: ptr.To("0.0.0.0"), Port: 3217, }, }, @@ -557,6 +925,24 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{}, }, + { + desc: "ProxyMetrics-sinks-backend-empty", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Metrics: &egv1a1.ProxyMetrics{ + Sinks: []egv1a1.ProxyMetricSink{ + { + Type: egv1a1.MetricSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{}, + }, + }, + }, + }, + } + }, + wantErrors: []string{"host or backendRefs needs to be set"}, + }, { desc: "ProxyMetrics-sinks-backendref", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -567,10 +953,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -581,6 +970,39 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{}, }, + { + desc: "ProxyMetrics-sinks-multi-backendref", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Metrics: &egv1a1.ProxyMetrics{ + Sinks: []egv1a1.ProxyMetricSink{ + { + Type: egv1a1.MetricSinkTypeOpenTelemetry, + OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{"must have at most 1 items"}, + }, { desc: "ProxyMetrics-sinks-backendref-empty-kind", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -591,9 +1013,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -614,10 +1040,14 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -626,26 +1056,30 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"BackendRef only support Service Kind."}, + wantErrors: []string{"only support Service Kind."}, }, { - desc: "invalid-tracing-backendref", + desc: "invalid-tracing-backendref-invalid-kind", mutate: func(envoy *egv1a1.EnvoyProxy) { envoy.Spec = egv1a1.EnvoyProxySpec{ Telemetry: &egv1a1.ProxyTelemetry{ Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, + }, }, }, }, }, } }, - wantErrors: []string{"BackendRef only support Service Kind."}, + wantErrors: []string{"only support Service Kind."}, }, { desc: "tracing-backendref-empty-kind", @@ -655,9 +1089,13 @@ func TestEnvoyProxyProvider(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, @@ -673,16 +1111,66 @@ func TestEnvoyProxyProvider(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + } + }, + }, + { + desc: "tracing-multi-backendref", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Tracing: &egv1a1.ProxyTracing{ + Provider: egv1a1.TracingProvider{ + Type: egv1a1.TracingProviderTypeOpenTelemetry, + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, + }, }, }, }, }, } }, + wantErrors: []string{"must have at most 1 items"}, + }, + { + desc: "tracing-empty-backend", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Telemetry: &egv1a1.ProxyTelemetry{ + Tracing: &egv1a1.ProxyTracing{ + Provider: egv1a1.TracingProvider{ + Type: egv1a1.TracingProviderTypeOpenTelemetry, + }, + }, + }, + } + }, + wantErrors: []string{"host or backendRefs needs to be set"}, }, { desc: "ProxyHpa-maxReplicas-is-required", @@ -781,6 +1269,128 @@ func TestEnvoyProxyProvider(t *testing.T) { } }, }, + { + desc: "ProxyFilterOrder-with-before-and-after", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + FilterOrder: []egv1a1.FilterPosition{ + { + Name: egv1a1.EnvoyFilterRateLimit, + Before: ptr.To(egv1a1.EnvoyFilterCORS), + After: ptr.To(egv1a1.EnvoyFilterBasicAuthn), + }, + }, + } + }, + wantErrors: []string{"only one of before or after can be specified"}, + }, + { + desc: "ProxyFilterOrder-without-before-or-after", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + FilterOrder: []egv1a1.FilterPosition{ + { + Name: egv1a1.EnvoyFilterRateLimit, + }, + }, + } + }, + wantErrors: []string{"one of before or after must be specified"}, + }, + { + desc: "ProxyFilterOrder-with-before", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + FilterOrder: []egv1a1.FilterPosition{ + { + Name: egv1a1.EnvoyFilterRateLimit, + Before: ptr.To(egv1a1.EnvoyFilterCORS), + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "ProxyFilterOrder-with-after", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + FilterOrder: []egv1a1.FilterPosition{ + { + Name: egv1a1.EnvoyFilterRateLimit, + After: ptr.To(egv1a1.EnvoyFilterBasicAuthn), + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "EnvoyDeployment-and-EnvoyDaemonSet-both-used", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{}, + EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{}, + }, + }, + } + }, + wantErrors: []string{"only one of envoyDeployment or envoyDaemonSet can be specified"}, + }, + { + desc: "EnvoyHpa-and-EnvoyDaemonSet-both-used", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{}, + EnvoyHpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{ + MinReplicas: ptr.To[int32](5), + MaxReplicas: ptr.To[int32](10), + }, + }, + }, + } + }, + wantErrors: []string{"cannot use envoyHpa if envoyDaemonSet is used"}, + }, + { + desc: "EnvoyDeployment-and-EnvoyDaemonSet-both-used", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{}, + EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{}, + }, + }, + } + }, + wantErrors: []string{"only one of envoyDeployment or envoyDaemonSet can be specified"}, + }, + { + desc: "EnvoyHpa-and-EnvoyDaemonSet-both-used", + mutate: func(envoy *egv1a1.EnvoyProxy) { + envoy.Spec = egv1a1.EnvoyProxySpec{ + Provider: &egv1a1.EnvoyProxyProvider{ + Type: egv1a1.ProviderTypeKubernetes, + Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{ + EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{}, + EnvoyHpa: &egv1a1.KubernetesHorizontalPodAutoscalerSpec{ + MinReplicas: ptr.To[int32](5), + MaxReplicas: ptr.To[int32](10), + }, + }, + }, + } + }, + wantErrors: []string{"cannot use envoyHpa if envoyDaemonSet is used"}, + }, } for _, tc := range cases { @@ -799,7 +1409,7 @@ func TestEnvoyProxyProvider(t *testing.T) { } if (len(tc.wantErrors) != 0) != (err != nil) { - t.Fatalf("Unexpected response while creating EnvoyProxy; got err=\n%v\n;want error=%v", err, tc.wantErrors != nil) + t.Fatalf("Unexpected response while creating EnvoyProxy; got err=\n%v\n;want error=%v", err, tc.wantErrors) } var missingErrorStrings []string diff --git a/test/cel-validation/main_test.go b/test/cel-validation/main_test.go index 64915388439..30ab253d7de 100644 --- a/test/cel-validation/main_test.go +++ b/test/cel-validation/main_test.go @@ -28,6 +28,10 @@ import ( var c client.Client func TestMain(m *testing.M) { + os.Exit(runTest(m)) +} + +func runTest(m *testing.M) int { // Setup the test environment. testEnv, restCfg, err := startEnv() if err != nil { @@ -47,8 +51,7 @@ func TestMain(m *testing.M) { panic(fmt.Sprintf("Error initializing client: %v", err)) } _ = egv1a1.AddToScheme(c.Scheme()) - - os.Exit(m.Run()) + return m.Run() } func startEnv() (*envtest.Environment, *rest.Config, error) { diff --git a/test/config/gatewayclass.yaml b/test/config/gatewayclass.yaml index 2700448c7d5..4067b66d58d 100644 --- a/test/config/gatewayclass.yaml +++ b/test/config/gatewayclass.yaml @@ -22,8 +22,10 @@ spec: sinks: - type: OpenTelemetry openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 accessLog: settings: - format: @@ -36,14 +38,18 @@ spec: path: /dev/stdout - type: OpenTelemetry openTelemetry: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 resources: k8s.cluster.name: "envoy-gateway" tracing: provider: - host: otel-collector.monitoring.svc.cluster.local - port: 4317 + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 customTags: "k8s.cluster.name": type: Literal @@ -86,4 +92,23 @@ spec: kubernetes: envoyDeployment: replicas: 2 - +--- +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1 +metadata: + name: merge-gateways +spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: merge-gateways-config + namespace: envoy-gateway-system +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyProxy +metadata: + name: merge-gateways-config + namespace: envoy-gateway-system +spec: + mergeGateways: true diff --git a/test/conformance/conformance_test.go b/test/conformance/conformance_test.go index 149909e2ce4..7eca6ea9d26 100644 --- a/test/conformance/conformance_test.go +++ b/test/conformance/conformance_test.go @@ -54,5 +54,4 @@ func TestGatewayAPIConformance(t *testing.T) { }) cSuite.Setup(t) cSuite.Run(t, tests.ConformanceTests) - } diff --git a/test/conformance/experimental_conformance_test.go b/test/conformance/experimental_conformance_test.go index b6d6b19e953..fa3598be1e0 100644 --- a/test/conformance/experimental_conformance_test.go +++ b/test/conformance/experimental_conformance_test.go @@ -129,7 +129,7 @@ func experimentalConformanceReport(logf func(string, ...any), report confv1a1.Co } if output != "" { - if err = os.WriteFile(output, rawReport, 0600); err != nil { + if err = os.WriteFile(output, rawReport, 0o600); err != nil { return err } } diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 46e0fb30bec..3159f0bd2a4 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -51,6 +51,9 @@ func TestE2E(t *testing.T) { CleanupBaseResources: *flags.CleanupBaseResources, FS: &Manifests, RunTest: *flags.RunTest, + SkipTests: []string{ + tests.ClientTimeoutTest.ShortName, // https://github.com/envoyproxy/gateway/issues/2720 + }, }) cSuite.Setup(t) diff --git a/test/e2e/merge_gateways/merge_gateways_test.go b/test/e2e/merge_gateways/merge_gateways_test.go new file mode 100644 index 00000000000..9c056875c32 --- /dev/null +++ b/test/e2e/merge_gateways/merge_gateways_test.go @@ -0,0 +1,68 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +//go:build e2e +// +build e2e + +package mergegateways + +import ( + "flag" + "testing" + + "github.com/stretchr/testify/require" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/config" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + "sigs.k8s.io/gateway-api/conformance/utils/flags" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/test/e2e" + "github.com/envoyproxy/gateway/test/e2e/tests" +) + +func TestMergeGateways(t *testing.T) { + flag.Parse() + + cfg, err := config.GetConfig() + require.NoError(t, err) + + c, err := client.New(cfg, client.Options{}) + require.NoError(t, err) + require.NoError(t, gwapiv1a2.AddToScheme(c.Scheme())) + require.NoError(t, gwapiv1.AddToScheme(c.Scheme())) + require.NoError(t, egv1a1.AddToScheme(c.Scheme())) + + if flags.RunTest != nil && *flags.RunTest != "" { + t.Logf("Running E2E test %s with %s GatewayClass\n cleanup: %t\n debug: %t", + *flags.RunTest, *flags.GatewayClassName, *flags.CleanupBaseResources, *flags.ShowDebug) + } else { + t.Logf("Running E2E tests with %s GatewayClass\n cleanup: %t\n debug: %t", + *flags.GatewayClassName, *flags.CleanupBaseResources, *flags.ShowDebug) + } + + cSuite := suite.New(suite.Options{ + Client: c, + GatewayClassName: *flags.GatewayClassName, + Debug: *flags.ShowDebug, + CleanupBaseResources: *flags.CleanupBaseResources, + RunTest: *flags.RunTest, + SkipTests: []string{ + tests.MergeGatewaysTest.ShortName, // https://github.com/envoyproxy/gateway/issues/3290 + }, + }) + + // Setting up the necessary arguments for the suite instead of calling Suite.Setup method again, + // since this test suite reuse the base resources of previous test suite. + cSuite.Applier.FS = e2e.Manifests + cSuite.Applier.GatewayClass = *flags.GatewayClassName + cSuite.ControllerName = kubernetes.GWCMustHaveAcceptedConditionTrue(t, cSuite.Client, cSuite.TimeoutConfig, cSuite.GatewayClassName) + + t.Logf("Running %d MergeGateways tests", len(tests.MergeGatewaysTests)) + cSuite.Run(t, tests.MergeGatewaysTests) +} diff --git a/test/e2e/testdata/basic-merge-gateways.yaml b/test/e2e/testdata/basic-merge-gateways.yaml new file mode 100644 index 00000000000..f32fddb29ee --- /dev/null +++ b/test/e2e/testdata/basic-merge-gateways.yaml @@ -0,0 +1,147 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: merged-gateway-1 + namespace: gateway-conformance-infra +spec: + gatewayClassName: merge-gateways + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http1 + port: 8080 + protocol: HTTP +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: merged-gateway-2 + namespace: gateway-conformance-infra +spec: + gatewayClassName: merge-gateways + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http2 + port: 8081 + protocol: HTTP +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: merged-gateway-3 + namespace: gateway-conformance-infra +spec: + gatewayClassName: merge-gateways + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http3 + port: 8082 + protocol: HTTP +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: merged-gateway-4 + namespace: gateway-conformance-infra +spec: + gatewayClassName: merge-gateways + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http3 + port: 8082 + protocol: HTTP +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: merged-gateway-route-1 + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: merged-gateway-1 + hostnames: + - "www.example1.com" + rules: + - backendRefs: + - group: "" + kind: Service + name: infra-backend-v1 + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /merge1 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: merged-gateway-route-2 + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: merged-gateway-2 + hostnames: + - "www.example2.com" + rules: + - backendRefs: + - group: "" + kind: Service + name: infra-backend-v2 + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /merge2 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: merged-gateway-route-3 + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: merged-gateway-3 + hostnames: + - "www.example3.com" + rules: + - backendRefs: + - group: "" + kind: Service + name: infra-backend-v3 + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /merge3 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: merged-gateway-route-4 + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: merged-gateway-4 + hostnames: + - "www.example4.com" + rules: + - backendRefs: + - group: "" + kind: Service + name: infra-backend-v3 + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /merge4 diff --git a/test/e2e/testdata/connection-limit.yaml b/test/e2e/testdata/connection-limit.yaml index 998a26191fd..3edb268aad8 100644 --- a/test/e2e/testdata/connection-limit.yaml +++ b/test/e2e/testdata/connection-limit.yaml @@ -11,7 +11,7 @@ spec: namespace: gateway-conformance-infra connection: connectionLimit: - value: 5 + value: 3 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute diff --git a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml index 5119ac22c1f..e88657fee1b 100644 --- a/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml +++ b/test/e2e/testdata/ext-proc-envoyextensionpolicy.yaml @@ -20,7 +20,7 @@ spec: apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: - name: http-without-ext-proc + name: http-without-procmode namespace: gateway-conformance-infra spec: parentRefs: @@ -46,8 +46,27 @@ spec: kind: HTTPRoute name: http-with-ext-proc extProc: - - backendRef: - name: grpc-ext-proc + - backendRefs: + - name: grpc-ext-proc + namespace: gateway-conformance-infra + port: 9002 + processingMode: + request: {} + response: {} +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyExtensionPolicy +metadata: + name: ext-proc-no-procmode-test + namespace: gateway-conformance-infra +spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: http-without-procmode + extProc: + - backendRefs: + - name: grpc-ext-proc namespace: gateway-conformance-infra port: 9002 --- diff --git a/test/e2e/testdata/ext-proc-service.yaml b/test/e2e/testdata/ext-proc-service.yaml index 594cf14edef..665779e96e4 100644 --- a/test/e2e/testdata/ext-proc-service.yaml +++ b/test/e2e/testdata/ext-proc-service.yaml @@ -8,74 +8,73 @@ data: go.mod: | module github.com/envoyproxy/gateway - go 1.21 + go 1.22 require ( - github.com/envoyproxy/go-control-plane v0.12.0 + github.com/envoyproxy/go-control-plane v0.12.1-0.20240322155512-db0b36a50fa8 google.golang.org/grpc v1.62.1 ) require ( - github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect - github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect - github.com/golang/protobuf v1.5.3 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/protobuf v1.32.0 // indirect + github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect + github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect + google.golang.org/protobuf v1.33.0 // indirect ) go.sum: | github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= - github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= - github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= + github.com/envoyproxy/go-control-plane v0.12.1-0.20240322155512-db0b36a50fa8 h1:Zghtu+wdlGvrmutCyhU9Ew5ozU18PVpxP+zGSgyUpFs= + github.com/envoyproxy/go-control-plane v0.12.1-0.20240322155512-db0b36a50fa8/go.mod h1:YtsM9q/kVkKyvmemY+BF/ZK7I93OWsx4uk4Do2Mr/OA= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= - github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= - github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= - github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= - github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= + github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= + github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= + github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795 h1:pH+U6pJP0BhxqQ4njBUjOg0++WMMvv3eByWzB+oATBY= + github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= - google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= - google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= - google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= - google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= + google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= + google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= main.go: | package main import ( - "context" - "crypto/tls" - "crypto/x509" - "flag" - "fmt" - "google.golang.org/grpc/credentials" - "io" - "log" - "net" - "net/http" - "os" - "strings" - - envoy_api_v3_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_service_proc_v3 "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" - - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + "context" + "crypto/tls" + "crypto/x509" + "flag" + "fmt" + "io" + "log" + "net" + "net/http" + "os" + "strings" + + "google.golang.org/grpc/credentials" + + envoy_api_v3_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + envoy_service_proc_v3 "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type extProcServer struct{} @@ -103,7 +102,6 @@ data: envoy_service_proc_v3.RegisterExternalProcessorServer(gs, &extProcServer{}) - go func() { err = gs.Serve(lis) if err != nil { @@ -227,13 +225,23 @@ data: resp := &envoy_service_proc_v3.ProcessingResponse{} switch v := req.Request.(type) { case *envoy_service_proc_v3.ProcessingRequest_RequestHeaders: + xrch := "" + if v.RequestHeaders != nil { + hdrs := v.RequestHeaders.Headers.GetHeaders() + for _, hdr := range hdrs { + if hdr.Key == "x-request-client-header" { + xrch = string(hdr.RawValue) + } + } + } + rhq := &envoy_service_proc_v3.HeadersResponse{ Response: &envoy_service_proc_v3.CommonResponse{ HeaderMutation: &envoy_service_proc_v3.HeaderMutation{ SetHeaders: []*envoy_api_v3_core.HeaderValueOption{ { Header: &envoy_api_v3_core.HeaderValue{ - Key: "x-request-ext-processed", + Key: "x-request-ext-processed", RawValue: []byte("true"), }, }, @@ -242,6 +250,23 @@ data: }, } + if xrch != "" { + rhq.Response.HeaderMutation.SetHeaders = append(rhq.Response.HeaderMutation.SetHeaders, + &envoy_api_v3_core.HeaderValueOption{ + Header: &envoy_api_v3_core.HeaderValue{ + Key: "x-request-client-header", + RawValue: []byte("mutated"), + }, + }) + rhq.Response.HeaderMutation.SetHeaders = append(rhq.Response.HeaderMutation.SetHeaders, + &envoy_api_v3_core.HeaderValueOption{ + Header: &envoy_api_v3_core.HeaderValue{ + Key: "x-request-client-header-received", + RawValue: []byte(xrch), + }, + }) + } + resp = &envoy_service_proc_v3.ProcessingResponse{ Response: &envoy_service_proc_v3.ProcessingResponse_RequestHeaders{ RequestHeaders: rhq, @@ -255,7 +280,7 @@ data: SetHeaders: []*envoy_api_v3_core.HeaderValueOption{ { Header: &envoy_api_v3_core.HeaderValue{ - Key: "x-response-ext-processed", + Key: "x-response-ext-processed", RawValue: []byte("true"), }, }, @@ -352,7 +377,7 @@ spec: - sh - "-c" - "cp -a /app /app-live && cd /app-live && go run . --certPath=/app-live/certs/ " - image: golang:1.21.3-alpine + image: golang:1.22.1-alpine ports: - containerPort: 8000 volumeMounts: diff --git a/test/e2e/testdata/jwt-optional.yaml b/test/e2e/testdata/jwt-optional.yaml new file mode 100644 index 00000000000..398040fd1dd --- /dev/null +++ b/test/e2e/testdata/jwt-optional.yaml @@ -0,0 +1,42 @@ +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: SecurityPolicy +metadata: + name: jwt-optional + namespace: gateway-conformance-infra +spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: jwt-optional + jwt: + providers: + - name: example + claimToHeaders: + - claim: sub + header: x-sub + - claim: admin + header: x-admin + - claim: name + header: x-name + remoteJWKS: + uri: https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/jwks.json + optional: true +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: jwt-optional + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - backendRefs: + - kind: Service + name: infra-backend-v1 + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /public diff --git a/test/e2e/testdata/ratelimit-cidr-match.yaml b/test/e2e/testdata/ratelimit-cidr-match.yaml index 4ee92d26fcd..fdc112e6663 100644 --- a/test/e2e/testdata/ratelimit-cidr-match.yaml +++ b/test/e2e/testdata/ratelimit-cidr-match.yaml @@ -16,7 +16,7 @@ spec: - clientSelectors: - sourceCIDR: value: 0.0.0.0/0 - type: distinct + type: Distinct limit: requests: 3 unit: Hour diff --git a/test/e2e/testdata/ratelimit-multiple-listeners.yaml b/test/e2e/testdata/ratelimit-multiple-listeners.yaml index 33d789515a9..47aa3e46450 100644 --- a/test/e2e/testdata/ratelimit-multiple-listeners.yaml +++ b/test/e2e/testdata/ratelimit-multiple-listeners.yaml @@ -48,7 +48,7 @@ spec: - clientSelectors: - sourceCIDR: value: 0.0.0.0/0 - type: distinct + type: Distinct limit: requests: 3 unit: Hour diff --git a/test/e2e/testdata/wasm.yaml b/test/e2e/testdata/wasm.yaml new file mode 100644 index 00000000000..76723cafb8c --- /dev/null +++ b/test/e2e/testdata/wasm.yaml @@ -0,0 +1,55 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-with-http-wasm-source + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + hostnames: ["www.example.com"] + rules: + - matches: + - path: + type: PathPrefix + value: /wasm-http + backendRefs: + - name: infra-backend-v1 + port: 8080 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-without-wasm + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + hostnames: ["www.example.com"] + rules: + - matches: + - path: + type: PathPrefix + value: /no-wasm + backendRefs: + - name: infra-backend-v1 + port: 8080 +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyExtensionPolicy +metadata: + name: http-wasm-source-test + namespace: gateway-conformance-infra +spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: http-with-http-wasm-source + wasm: + - name: wasm-filter + rootID: my_root_id + code: + type: HTTP + http: + url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm + sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0 diff --git a/test/e2e/tests/backend_tls.go b/test/e2e/tests/backend_tls.go index 1c556a0bb78..dea222b477f 100644 --- a/test/e2e/tests/backend_tls.go +++ b/test/e2e/tests/backend_tls.go @@ -63,6 +63,5 @@ var BackendTLSTest = suite.ConformanceTest{ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) }) - }, } diff --git a/test/e2e/tests/client_timeout.go b/test/e2e/tests/client_timeout.go index c3edf9cf1cc..5ae5f00d106 100644 --- a/test/e2e/tests/client_timeout.go +++ b/test/e2e/tests/client_timeout.go @@ -22,9 +22,7 @@ import ( ) func init() { - // This test cause too much flakiness, so we disable it for now. - // TODO: find a better way to test client timeout. - // ConformanceTests = append(ConformanceTests, ClientTimeoutTest) + ConformanceTests = append(ConformanceTests, ClientTimeoutTest) } var largeSizeHeader = func() string { @@ -35,7 +33,6 @@ var largeSizeHeader = func() string { return b.String() } -// nolint var ClientTimeoutTest = suite.ConformanceTest{ ShortName: "ClientTimeout", Description: "Test that the ClientTrafficPolicy API implementation supports client timeout", diff --git a/test/e2e/tests/connection_limit.go b/test/e2e/tests/connection_limit.go index 220be1a5616..952a6086da6 100644 --- a/test/e2e/tests/connection_limit.go +++ b/test/e2e/tests/connection_limit.go @@ -9,21 +9,21 @@ package tests import ( - "errors" + "fmt" "net" - "net/url" "testing" "time" - "github.com/envoyproxy/gateway/internal/gatewayapi" - + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/types" - gwv1 "sigs.k8s.io/gateway-api/apis/v1" gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" "sigs.k8s.io/gateway-api/conformance/utils/http" "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" "sigs.k8s.io/gateway-api/conformance/utils/suite" + + "github.com/envoyproxy/gateway/internal/gatewayapi" + "github.com/envoyproxy/gateway/test/e2e/utils/prometheus" ) func init() { @@ -49,40 +49,50 @@ var ConnectionLimitTest = suite.ConformanceTest{ } ClientTrafficPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "connection-limit-ctp", Namespace: ns}, suite.ControllerName, ancestorRef) - // open some connections - for i := 0; i < 10; i++ { - conn, err := net.DialTimeout("tcp", gwAddr, 100*time.Millisecond) - if err == nil { - defer conn.Close() - } else { + promAddr, err := prometheus.Address(suite.Client, + types.NamespacedName{Name: "prometheus", Namespace: "monitoring"}, + ) + require.NoError(t, err) + + // we make the number of connections equal to the number of connectionLimit connections + 3 + // avoid partial connection errors or interruptions + for i := 0; i < 6; i++ { + conn, err := net.Dial("tcp", gwAddr) + if err != nil { t.Errorf("failed to open connection: %v", err) + } else { + defer conn.Close() } } - // make a request, expect a failure - expectedResponse := http.ExpectedResponse{ - Request: http.Request{ - Path: "/", - }, - Response: http.Response{ - StatusCode: 200, - }, - Namespace: ns, - } + prefix := "http" + gtwName := "connection-limit-gateway" + promQL := fmt.Sprintf(`envoy_connection_limit_limited_connections{envoy_connection_limit_prefix="%s",gateway_envoyproxy_io_owning_gateway_name="%s"}`, prefix, gtwName) - req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") - _, _, err := suite.RoundTripper.CaptureRoundTrip(req) + http.AwaitConvergence( + t, + suite.TimeoutConfig.RequiredConsecutiveSuccesses, + suite.TimeoutConfig.MaxTimeToConsistency, + func(_ time.Duration) bool { + // check connection_limit stats from Prometheus + v, err := prometheus.QuerySum(promAddr, promQL) + if err != nil { + // wait until Prometheus sync stats + return false + } + t.Logf("connection_limit stats query count: %v", v) - // expect error - if err != nil { - urlError := &url.Error{} - if !errors.As(err, &urlError) { - t.Errorf("expected net/url error when connection limit is reached") - } - } else { - t.Errorf("expected error when connection limit is reached") - } + // connection interruptions or other connection errors may occur + // we just need to determine whether there is a connection limit stats + if v == 0 { + t.Error("connection is not limited as expected") + } else { + t.Log("connection is limited as expected") + } + return true + }, + ) }) }, } diff --git a/test/e2e/tests/eg_upgrade.go b/test/e2e/tests/eg_upgrade.go index 48f07faad6f..d4128102e73 100644 --- a/test/e2e/tests/eg_upgrade.go +++ b/test/e2e/tests/eg_upgrade.go @@ -24,6 +24,10 @@ import ( "sigs.k8s.io/gateway-api/conformance/utils/suite" ) +func init() { + UpgradeTests = append(UpgradeTests, EGUpgradeTest) +} + var EGUpgradeTest = suite.ConformanceTest{ ShortName: "EGUpgrade", Description: "Upgrading from the last eg version should not lead to failures", diff --git a/test/e2e/tests/envoy_shutdown.go b/test/e2e/tests/envoy_shutdown.go index 6e870a265e6..4cb1e68ac7b 100644 --- a/test/e2e/tests/envoy_shutdown.go +++ b/test/e2e/tests/envoy_shutdown.go @@ -16,25 +16,22 @@ import ( "testing" "time" - "github.com/envoyproxy/gateway/api/v1alpha1" - "fortio.org/fortio/periodic" - - "github.com/envoyproxy/gateway/internal/gatewayapi" - "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/gateway-api/conformance/utils/config" "sigs.k8s.io/gateway-api/conformance/utils/http" "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" "sigs.k8s.io/gateway-api/conformance/utils/suite" + + "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/gatewayapi" + "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy" ) func init() { diff --git a/test/e2e/tests/ext_auth_http_service.go b/test/e2e/tests/ext_auth_http_service.go index d1fb8070de9..7005004b221 100644 --- a/test/e2e/tests/ext_auth_http_service.go +++ b/test/e2e/tests/ext_auth_http_service.go @@ -78,15 +78,7 @@ var HTTPExtAuthTest = suite.ConformanceTest{ Namespace: ns, } - req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") - cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) - if err != nil { - t.Errorf("failed to get expected response: %v", err) - } - - if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil { - t.Errorf("failed to compare request and response: %v", err) - } + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) }) t.Run("without Authorization header", func(t *testing.T) { diff --git a/test/e2e/tests/ext_proc.go b/test/e2e/tests/ext_proc.go index aa9978e92ea..eb069380b7b 100644 --- a/test/e2e/tests/ext_proc.go +++ b/test/e2e/tests/ext_proc.go @@ -26,10 +26,10 @@ func init() { ConformanceTests = append(ConformanceTests, ExtProcTest) } -// ExtProcTest tests ExtProcs authentication for an http route with ExtProcs configured. +// ExtProcTest tests ExtProc authentication for an http route with ExtProc configured. var ExtProcTest = suite.ConformanceTest{ - ShortName: "ExtProcs", - Description: "Test ExtProcs service that adds request and response headers", + ShortName: "ExtProc", + Description: "Test ExtProc service that adds request and response headers", Manifests: []string{"testdata/ext-proc-service.yaml", "testdata/ext-proc-envoyextensionpolicy.yaml"}, Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { t.Run("http route with ext proc", func(t *testing.T) { @@ -56,19 +56,25 @@ var ExtProcTest = suite.ConformanceTest{ Host: "www.example.com", Path: "/processor", Headers: map[string]string{ - "x-request-ext-processed": "true", // header added by ext-processor to request + "x-request-ext-processed": "true", // header added by ext-processor to backend-bound request + "x-request-client-header-received": "original", // this is the original client header preserved by ext-proc in a new header + "x-request-client-header": "mutated", // this is the mutated value expected to reach upstream }, }, Response: http.Response{ StatusCode: 200, Headers: map[string]string{ - "x-response-ext-processed": "true", // header added by ext-processor to request + "x-response-ext-processed": "true", // header added by ext-processor to client-bound response }, }, Namespace: ns, } req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") + + // add a request header that will be mutated by ext-proc + req.Headers["x-request-client-header"] = []string{"original"} + cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) if err != nil { t.Errorf("failed to get expected response: %v", err) @@ -79,9 +85,9 @@ var ExtProcTest = suite.ConformanceTest{ } }) - t.Run("http route without ext proc", func(t *testing.T) { + t.Run("http route without proc mode", func(t *testing.T) { ns := "gateway-conformance-infra" - routeNN := types.NamespacedName{Name: "http-with-ext-proc", Namespace: ns} + routeNN := types.NamespacedName{Name: "http-without-procmode", Namespace: ns} gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) @@ -91,7 +97,7 @@ var ExtProcTest = suite.ConformanceTest{ Namespace: gatewayapi.NamespacePtr(gwNN.Namespace), Name: gwv1.ObjectName(gwNN.Name), } - EnvoyExtensionPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "ext-proc-test", Namespace: ns}, suite.ControllerName, ancestorRef) + EnvoyExtensionPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "ext-proc-no-procmode-test", Namespace: ns}, suite.ControllerName, ancestorRef) podReady := corev1.PodCondition{Type: corev1.PodReady, Status: corev1.ConditionTrue} @@ -102,6 +108,9 @@ var ExtProcTest = suite.ConformanceTest{ Request: http.Request{ Host: "www.example.com", Path: "/no-processor", + Headers: map[string]string{ + "x-request-client-header": "original", + }, }, Response: http.Response{ StatusCode: 200, @@ -111,6 +120,10 @@ var ExtProcTest = suite.ConformanceTest{ } req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") + + // add a request header that will be mutated by ext-proc if the request headers are sent + req.Headers["x-request-client-header"] = []string{"original"} + cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) if err != nil { t.Errorf("failed to get expected response: %v", err) diff --git a/test/e2e/tests/gateway_infra_resource.go b/test/e2e/tests/gateway_infra_resource.go index 9d234922991..c14cb145050 100644 --- a/test/e2e/tests/gateway_infra_resource.go +++ b/test/e2e/tests/gateway_infra_resource.go @@ -21,14 +21,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/conformance/utils/suite" - - "github.com/envoyproxy/gateway/internal/utils" ) func init() { - ConformanceTests = append(ConformanceTests, GatewayInfraResourceTest) + // nolint + // ConformanceTests = append(ConformanceTests, GatewayInfraResourceTest) } +// nolint var GatewayInfraResourceTest = suite.ConformanceTest{ ShortName: "GatewayInfraResourceTest", Description: "Gateway Infra Resource E2E Test", @@ -90,6 +90,7 @@ var GatewayInfraResourceTest = suite.ConformanceTest{ awaitOperation.Add(1) newListenerTCPName := "custom-tcp" + containerPortName := "tcp-5432" newListenerHTTPPort := int32(8001) changedGatewayObj := &gwapiv1.Gateway{ @@ -129,10 +130,9 @@ var GatewayInfraResourceTest = suite.ConformanceTest{ for _, container := range gatewayDeployment.Spec.Template.Spec.Containers { var isTCPPortNameMatch, isHTTPPortNumberMatch bool - hashedPortName := utils.GetHashedName(newListenerTCPName, 6) if container.Name == "envoy" { for _, port := range container.Ports { - if port.Name == hashedPortName { + if port.Name == containerPortName { isTCPPortNameMatch = true } @@ -142,11 +142,11 @@ var GatewayInfraResourceTest = suite.ConformanceTest{ } if !isTCPPortNameMatch { - t.Errorf("container expected TCP port name '%v' is not found", hashedPortName) + t.Errorf("container expected TCP port name '%v' is not found", containerPortName) } if !isHTTPPortNumberMatch { - t.Errorf("container expected HTTP port number '%v' is not found", hashedPortName) + t.Errorf("container expected HTTP port number '%d' is not found", newListenerHTTPPort) } } } diff --git a/test/e2e/tests/jwt.go b/test/e2e/tests/jwt.go index 89de5fa60dc..fc7e826dd46 100644 --- a/test/e2e/tests/jwt.go +++ b/test/e2e/tests/jwt.go @@ -18,7 +18,7 @@ import ( ) func init() { - ConformanceTests = append(ConformanceTests, JWTTest) + ConformanceTests = append(ConformanceTests, JWTTest, OptionalJWTTest) } const ( @@ -30,6 +30,8 @@ const ( v2Token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRvbSIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjJ9.kyzDDSo7XpweSPU1lxoI9IHzhTBrRNlnmcW9lmCbloZELShg-8isBx4AFoM4unXZTHpS_Y24y0gmd4nDQxgUE-CgjVSnGCb0Xhy3WO1gm9iChoKDyyQ3kHp98EmKxTyxKG2X9GyKcDFNBDjH12OBD7TcJUaBEvLf6Jw1SG2A7FakUPWeK04DQ916-ROylzI6qKyaZ0OpfYIbijvyAQxlQRxxs2XHlAkLdJhfVcUqJBwsFTbwHYARC-WNgd2_etAk1GWdwwZ_NoTmRzZAMryrYJpHY9KPlbnZ93Ye3o9h2viBQ_XRb7JBkWnAGYO4_KswpJWE_7ROUVj8iOJo2jfY6w" // nolint: gosec anotherToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkplcnJ5IiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.VKLURpaPLWanwE5xoGTfuYKqT9a91Fg1tRBAOyFzNa5t9SbtK8As7-3iJg4f_VlBHj13OeKjfpDEvgLerIt5TKnU708YKERB45di_7TNURoiVZayq3_gFznMqoSarP3irLDzh0YKUjc7Vuh3MX99fueTdbeA-c4pMhG_nwiFeRJhZNQQDzzKtmL9C_L2uwP4bDupmcYz6FAA2EN_r67WoXCjPWQoRQmE435EVQ-FYKgAR7qZ5TdjoSN91ByRQ7Ior9srPl7gOvjuaRbu7fjC-LT7wRE26v2vu-BCM2PveJf2NMobNb8q0pcmpB1TWhSXp1MIZs9yxbqEAZLOumYfUw" + // nolint: gosec + invalidToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" ) var JWTTest = suite.ConformanceTest{ @@ -108,3 +110,65 @@ var JWTTest = suite.ConformanceTest{ }) }, } + +var OptionalJWTTest = suite.ConformanceTest{ + ShortName: "OptionalJWT", + Description: "Test enable optional JWT", + Manifests: []string{"testdata/jwt-optional.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "jwt-optional", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + + testCases := []http.ExpectedResponse{ + { + TestCaseName: "with a valid JWT", + Request: http.Request{ + Path: "/public", + Headers: map[string]string{ + "Authorization": "Bearer " + v1Token, + }, + }, + Backend: "infra-backend-v1", + Response: http.Response{ + StatusCode: 200, + }, + Namespace: ns, + }, + { + TestCaseName: "with an invalid JWT", + Request: http.Request{ + Path: "/public", + Headers: map[string]string{ + "Authorization": "Bearer " + invalidToken, + }, + }, + Backend: "infra-backend-v1", + Response: http.Response{ + StatusCode: 401, + }, + Namespace: ns, + }, + { + TestCaseName: "omitting JWT", + Request: http.Request{ + Path: "/public", + }, + Backend: "infra-backend-v1", + Response: http.Response{ + StatusCode: 200, + }, + Namespace: ns, + }, + } + + for i := range testCases { + tc := testCases[i] + t.Run(tc.GetTestCaseName(i), func(t *testing.T) { + t.Parallel() + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc) + }) + } + }, +} diff --git a/test/e2e/tests/merge_gateways.go b/test/e2e/tests/merge_gateways.go new file mode 100644 index 00000000000..abcd809f70d --- /dev/null +++ b/test/e2e/tests/merge_gateways.go @@ -0,0 +1,150 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +//go:build e2e +// +build e2e + +package tests + +import ( + "net" + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" + + "github.com/envoyproxy/gateway/internal/gatewayapi" +) + +func init() { + MergeGatewaysTests = append(MergeGatewaysTests, MergeGatewaysTest) +} + +var MergeGatewaysTest = suite.ConformanceTest{ + ShortName: "BasicMergeGateways", + Description: "Basic test for MergeGateways feature", + Manifests: []string{"testdata/basic-merge-gateways.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + ns := "gateway-conformance-infra" + + route1NN := types.NamespacedName{Name: "merged-gateway-route-1", Namespace: ns} + gw1NN := types.NamespacedName{Name: "merged-gateway-1", Namespace: ns} + gw1HostPort := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gw1NN), route1NN) + + route2NN := types.NamespacedName{Name: "merged-gateway-route-2", Namespace: ns} + gw2NN := types.NamespacedName{Name: "merged-gateway-2", Namespace: ns} + gw2HostPort := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gw2NN), route2NN) + + route3NN := types.NamespacedName{Name: "merged-gateway-route-3", Namespace: ns} + gw3NN := types.NamespacedName{Name: "merged-gateway-3", Namespace: ns} + gw3HostPort := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gw3NN), route3NN) + + gw1Addr, _, err := net.SplitHostPort(gw1HostPort) + if err != nil { + t.Errorf("failed to split hostport %s of gateway %s: %v", gw1HostPort, gw1NN.String(), err) + } + + gw2Addr, _, err := net.SplitHostPort(gw2HostPort) + if err != nil { + t.Errorf("failed to split hostport %s of gateway %s: %v", gw2HostPort, gw2NN.String(), err) + } + + gw3Addr, _, err := net.SplitHostPort(gw3HostPort) + if err != nil { + t.Errorf("failed to split hostport %s of gateway %s: %v", gw3HostPort, gw3NN.String(), err) + } + + if gw1Addr != gw2Addr || gw2Addr != gw3Addr { + t.Errorf("inconsistent gateway address %s: %s, %s: %s and %s: %s", + gw1NN.String(), gw1Addr, gw2NN.String(), gw2Addr, gw3NN.String(), gw3Addr) + t.FailNow() + } + + t.Run("merged three gateways under the same namespace with http routes", func(t *testing.T) { + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gw1HostPort, http.ExpectedResponse{ + Request: http.Request{Path: "/merge1", Host: "www.example1.com"}, + Response: http.Response{StatusCode: 200}, + Namespace: ns, + Backend: "infra-backend-v1", + }) + + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gw2HostPort, http.ExpectedResponse{ + Request: http.Request{Path: "/merge2", Host: "www.example2.com"}, + Response: http.Response{StatusCode: 200}, + Namespace: ns, + Backend: "infra-backend-v2", + }) + + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gw3HostPort, http.ExpectedResponse{ + Request: http.Request{Path: "/merge3", Host: "www.example3.com"}, + Response: http.Response{StatusCode: 200}, + Namespace: ns, + Backend: "infra-backend-v3", + }) + }) + + t.Run("gateway with conflicted listener cannot be merged", func(t *testing.T) { + route4NN := types.NamespacedName{Name: "merged-gateway-route-4", Namespace: ns} + gw4NN := types.NamespacedName{Name: "merged-gateway-4", Namespace: ns} + + gw4HostPort, err := kubernetes.WaitForGatewayAddress(t, suite.Client, suite.TimeoutConfig, gw4NN) + if err != nil { + t.Errorf("failed to get the address of gateway %s", gw4NN.String()) + } + + // Even the gateway cannot be merged, it still has the consistent address. + gw4Addr, _, err := net.SplitHostPort(gw4HostPort) + if err != nil { + t.Errorf("failed to split hostport %s of gateway %s: %v", gw4HostPort, gw4NN.String(), err) + t.FailNow() + } + + if gw4Addr != gw1Addr { + t.Errorf("gateway %s has inconsistent address %s with other gateways %s", + gw4NN.String(), gw4Addr, gw1Addr) + t.FailNow() + } + + conflictedListener := []gwapiv1.ListenerStatus{{ + Name: gwapiv1.SectionName("http3"), + SupportedKinds: []gwapiv1.RouteGroupKind{ + { + Group: gatewayapi.GroupPtr(gwapiv1.GroupName), + Kind: gatewayapi.KindHTTPRoute, + }, + { + Group: gatewayapi.GroupPtr(gwapiv1.GroupName), + Kind: gatewayapi.KindGRPCRoute, + }, + }, + Conditions: []metav1.Condition{{ + Type: string(gwapiv1.ListenerConditionConflicted), + Status: metav1.ConditionTrue, + Reason: string(gwapiv1.ListenerReasonHostnameConflict), + }}, + AttachedRoutes: 1, + }} + kubernetes.GatewayStatusMustHaveListeners(t, suite.Client, suite.TimeoutConfig, gw4NN, conflictedListener) + + expectedHTTPRouteCondition := metav1.Condition{ + Type: string(gwapiv1.RouteConditionAccepted), + Status: metav1.ConditionFalse, + Reason: "NoReadyListeners", + } + kubernetes.HTTPRouteMustHaveCondition(t, suite.Client, suite.TimeoutConfig, route4NN, gw4NN, expectedHTTPRouteCondition) + + // Not merged gateway should not receive any traffic. + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gw4HostPort, http.ExpectedResponse{ + Request: http.Request{Path: "/merge4", Host: "www.example4.com"}, + Response: http.Response{StatusCode: 404}, + Namespace: ns, + }) + }) + }, +} diff --git a/test/e2e/tests/preservecase.go b/test/e2e/tests/preservecase.go index 59d54c2f84e..458bebd8219 100644 --- a/test/e2e/tests/preservecase.go +++ b/test/e2e/tests/preservecase.go @@ -135,6 +135,5 @@ var PreserveCaseTest = suite.ConformanceTest{ t.Errorf("case was not preserved for test header: %+v", respBody) } }) - }, } diff --git a/test/e2e/tests/ratelimit.go b/test/e2e/tests/ratelimit.go index c02802abe1f..0115dbe0089 100644 --- a/test/e2e/tests/ratelimit.go +++ b/test/e2e/tests/ratelimit.go @@ -284,7 +284,6 @@ var RateLimitBasedJwtClaimsTest = suite.ConformanceTest{ if err := GotExactExpectedResponse(t, 1, suite.RoundTripper, noTokenReq, noTokenResp); err != nil { t.Errorf("failed to get expected response: %v", err) } - }) }, } diff --git a/test/e2e/tests/redirect_replaceprefixmatch_slash.go b/test/e2e/tests/redirect_replaceprefixmatch_slash.go index 3dcc4e90873..c1986809000 100644 --- a/test/e2e/tests/redirect_replaceprefixmatch_slash.go +++ b/test/e2e/tests/redirect_replaceprefixmatch_slash.go @@ -19,7 +19,6 @@ import ( func init() { ConformanceTests = append(ConformanceTests, RedirectTrailingSlashTest) - } // RedirectTrailingSlashTest tests that only one slash in the redirect URL diff --git a/test/e2e/tests/retry.go b/test/e2e/tests/retry.go index c2acfecf34c..c067df3752d 100644 --- a/test/e2e/tests/retry.go +++ b/test/e2e/tests/retry.go @@ -24,7 +24,6 @@ import ( func init() { ConformanceTests = append(ConformanceTests, RetryTest) - } var RetryTest = suite.ConformanceTest{ diff --git a/test/e2e/tests/tcp_route.go b/test/e2e/tests/tcp_route.go index 0aa8b609e79..f09521db010 100644 --- a/test/e2e/tests/tcp_route.go +++ b/test/e2e/tests/tcp_route.go @@ -77,7 +77,6 @@ var TCPRouteTest = suite.ConformanceTest{ // Send a request to an valid path and expect a successful response http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, OkResp) }) - }, } @@ -124,7 +123,6 @@ func GatewayAndTCPRoutesMustBeAccepted(t *testing.T, c client.Client, timeoutCon } return gwAddr - } // WaitForGatewayAddress waits until at least one IP Address has been set in the diff --git a/test/e2e/tests/tests.go b/test/e2e/tests/tests.go index f5f0657de4d..6888cff3a8c 100644 --- a/test/e2e/tests/tests.go +++ b/test/e2e/tests/tests.go @@ -11,6 +11,7 @@ package tests import "sigs.k8s.io/gateway-api/conformance/utils/suite" var ( - ConformanceTests []suite.ConformanceTest - UpgradeTests []suite.ConformanceTest + ConformanceTests []suite.ConformanceTest + UpgradeTests []suite.ConformanceTest + MergeGatewaysTests []suite.ConformanceTest ) diff --git a/test/e2e/tests/tracing.go b/test/e2e/tests/tracing.go index 880b166b4f8..9ded2662cf9 100644 --- a/test/e2e/tests/tracing.go +++ b/test/e2e/tests/tracing.go @@ -119,7 +119,6 @@ func QueryTraceFromTempo(t *testing.T, c client.Client, tags map[string]string) req, err := http.NewRequest("GET", tempoURL.String(), nil) if err != nil { - return -1, err } diff --git a/test/e2e/tests/utils.go b/test/e2e/tests/utils.go index 6903534558b..a07cf6cb464 100644 --- a/test/e2e/tests/utils.go +++ b/test/e2e/tests/utils.go @@ -9,7 +9,6 @@ import ( "context" "fmt" "io" - "testing" "time" @@ -216,6 +215,7 @@ func EnvoyExtensionPolicyMustBeAccepted(t *testing.T, client client.Client, poli } if policyAcceptedByAncestor(policy.Status.Ancestors, controllerName, ancestorRef) { + t.Logf("EnvoyExtensionPolicy has been accepted: %v", policy) return true, nil } diff --git a/test/e2e/tests/wasm.go b/test/e2e/tests/wasm.go new file mode 100644 index 00000000000..d4a36029f3b --- /dev/null +++ b/test/e2e/tests/wasm.go @@ -0,0 +1,117 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +//go:build e2e +// +build e2e + +package tests + +import ( + "testing" + + "k8s.io/apimachinery/pkg/types" + gwv1 "sigs.k8s.io/gateway-api/apis/v1" + gwv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" + + "github.com/envoyproxy/gateway/internal/gatewayapi" +) + +func init() { + ConformanceTests = append(ConformanceTests, WasmTest) +} + +// WasmTest tests Wasm extension for an http route with HTTP Wasm configured. +var WasmTest = suite.ConformanceTest{ + ShortName: "Wasm", + Description: "Test Wasm extension that adds response headers", + Manifests: []string{"testdata/wasm.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + t.Run("http route with http wasm source", func(t *testing.T) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "http-with-http-wasm-source", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + + ancestorRef := gwv1a2.ParentReference{ + Group: gatewayapi.GroupPtr(gwv1.GroupName), + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Namespace: gatewayapi.NamespacePtr(gwNN.Namespace), + Name: gwv1.ObjectName(gwNN.Name), + } + EnvoyExtensionPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "http-wasm-source-test", Namespace: ns}, suite.ControllerName, ancestorRef) + + expectedResponse := http.ExpectedResponse{ + Request: http.Request{ + Host: "www.example.com", + Path: "/wasm-http", + }, + + // Set the expected request properties to empty strings. + // This is a workaround to avoid the test failure. + // These values can't be extracted from the json format response + // body because the test wasm code appends a "Hello, world" text + // to the response body, invalidating the json format. + ExpectedRequest: &http.ExpectedRequest{ + Request: http.Request{ + Host: "", + Method: "", + Path: "", + Headers: nil, + }, + }, + Namespace: "", + + Response: http.Response{ + StatusCode: 200, + Headers: map[string]string{ + "x-wasm-custom": "FOO", // response header added by wasm + }, + }, + } + + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) + }) + + t.Run("http route without wasm", func(t *testing.T) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "http-without-wasm", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + + ancestorRef := gwv1a2.ParentReference{ + Group: gatewayapi.GroupPtr(gwv1.GroupName), + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Namespace: gatewayapi.NamespacePtr(gwNN.Namespace), + Name: gwv1.ObjectName(gwNN.Name), + } + EnvoyExtensionPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "http-wasm-source-test", Namespace: ns}, suite.ControllerName, ancestorRef) + + expectedResponse := http.ExpectedResponse{ + Request: http.Request{ + Host: "www.example.com", + Path: "/no-wasm", + }, + Response: http.Response{ + StatusCode: 200, + AbsentHeaders: []string{"x-wasm-custom"}, + }, + Namespace: ns, + } + + req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") + cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Errorf("failed to get expected response: %v", err) + } + + if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil { + t.Errorf("failed to compare request and response: %v", err) + } + }) + }, +} diff --git a/test/e2e/tests/weighted_backend.go b/test/e2e/tests/weighted_backend.go index b31dce8f04f..250c6ef4cc3 100644 --- a/test/e2e/tests/weighted_backend.go +++ b/test/e2e/tests/weighted_backend.go @@ -70,7 +70,6 @@ var WeightEqualTest = suite.ConformanceTest{ if len(podName) == 0 { // it shouldn't be missing here t.Errorf("failed to get pod header in response: %v", err) - } else { // all we need is the pod Name prefix podNamePrefix := ExtractPodNamePrefix(podName) @@ -135,7 +134,6 @@ var WeightBlueGreenTest = suite.ConformanceTest{ if len(podName) == 0 { // it shouldn't be missing here t.Errorf("failed to get pod header in response: %v", err) - } else { // all we need is the pod Name prefix podNamePrefix := ExtractPodNamePrefix(podName) @@ -200,7 +198,6 @@ var WeightCompleteRolloutTest = suite.ConformanceTest{ if len(podName) == 0 { // it shouldn't be missing here t.Errorf("failed to get pod header in response: %v", err) - } else { // all we need is the pod Name prefix podNamePrefix := ExtractPodNamePrefix(podName) @@ -222,7 +219,6 @@ var WeightCompleteRolloutTest = suite.ConformanceTest{ // ExtractPodNamePrefix Extract the Pod Name prefix func ExtractPodNamePrefix(podName string) string { - pattern := regexp.MustCompile(`infra-backend-(.+?)-`) match := pattern.FindStringSubmatch(podName) if len(match) > 1 { diff --git a/test/e2e/upgrade/eg_upgrade_test.go b/test/e2e/upgrade/eg_upgrade_test.go index 431ecf01960..999a85ccc53 100644 --- a/test/e2e/upgrade/eg_upgrade_test.go +++ b/test/e2e/upgrade/eg_upgrade_test.go @@ -10,14 +10,11 @@ package upgrade import ( "flag" - "testing" "github.com/stretchr/testify/require" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" "sigs.k8s.io/gateway-api/conformance/utils/flags" @@ -30,6 +27,7 @@ import ( func TestEGUpgrade(t *testing.T) { flag.Parse() + cfg, err := config.GetConfig() require.NoError(t, err) @@ -54,9 +52,13 @@ func TestEGUpgrade(t *testing.T) { CleanupBaseResources: *flags.CleanupBaseResources, FS: &e2e.Manifests, RunTest: *flags.RunTest, + SkipTests: []string{ + tests.EnvoyShutdownTest.ShortName, // https://github.com/envoyproxy/gateway/issues/3262 + tests.EGUpgradeTest.ShortName, // https://github.com/envoyproxy/gateway/issues/3311 + }, }) cSuite.Setup(t) - t.Logf("Upgrade: Running tests") - cSuite.Run(t, []suite.ConformanceTest{tests.EnvoyShutdownTest, tests.EGUpgradeTest}) + t.Logf("Running %d Upgrade tests", len(tests.UpgradeTests)) + cSuite.Run(t, tests.UpgradeTests) } diff --git a/test/helm/default.yaml b/test/helm/default.yaml index 4b2976a62ce..5bebac04aad 100644 --- a/test/helm/default.yaml +++ b/test/helm/default.yaml @@ -194,6 +194,7 @@ rules: - apps resources: - deployments + - daemonsets verbs: - create - get @@ -368,7 +369,7 @@ spec: - name: KUBERNETES_CLUSTER_DOMAIN value: cluster.local image: docker.io/envoyproxy/gateway-dev:latest - imagePullPolicy: Always + imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: /healthz @@ -516,7 +517,7 @@ spec: - name: KUBERNETES_CLUSTER_DOMAIN value: cluster.local image: docker.io/envoyproxy/gateway-dev:latest - imagePullPolicy: Always + imagePullPolicy: IfNotPresent name: envoy-gateway-certgen restartPolicy: Never securityContext: @@ -524,4 +525,4 @@ spec: runAsNonRoot: true runAsUser: 65534 serviceAccountName: eg-gateway-helm-certgen - ttlSecondsAfterFinished: 0 + ttlSecondsAfterFinished: 30 diff --git a/tools/crd-ref-docs/config.yaml b/tools/crd-ref-docs/config.yaml index 18e84746d4c..d6fa4e4fc1f 100644 --- a/tools/crd-ref-docs/config.yaml +++ b/tools/crd-ref-docs/config.yaml @@ -6,6 +6,9 @@ processor: ignoreFields: - "status$" - "TypeMeta$" + customMarkers: + - name: "notImplementedHide" + target: "field" render: # Version of Kubernetes to use when generating links to Kubernetes API documentation. diff --git a/tools/crd-ref-docs/templates/type.tpl b/tools/crd-ref-docs/templates/type.tpl index 581cd8fcd9a..a1bb44833a7 100644 --- a/tools/crd-ref-docs/templates/type.tpl +++ b/tools/crd-ref-docs/templates/type.tpl @@ -24,10 +24,18 @@ _Appears in:_ {{ end -}} {{ range $type.Members -}} +{{- with .Markers.notImplementedHide -}} +{{- else -}} | `{{ .Name }}` | _{{ markdownRenderType .Type }}_ | {{ with .Markers.optional }} {{ "false" }} {{ else }} {{ "true" }} {{end}} | {{ template "type_members" . }} | {{ end -}} - +{{- end -}} +{{- end -}} +{{ if $type.EnumValues -}} +| Value | Description | +| ----- | ----------- | +{{ range $type.EnumValues -}} +| `{{ .Name }}` | {{ markdownRenderFieldDoc .Doc }} | {{ end -}} - +{{- end -}} {{- end -}} {{- end -}} diff --git a/tools/docker/envoy-gateway/Dockerfile b/tools/docker/envoy-gateway/Dockerfile index 9109a33e7ea..074320308eb 100644 --- a/tools/docker/envoy-gateway/Dockerfile +++ b/tools/docker/envoy-gateway/Dockerfile @@ -1,6 +1,6 @@ # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details -FROM gcr.io/distroless/static:nonroot@sha256:f41b84cda410b05cc690c2e33d1973a31c6165a2721e2b5343aab50fecb63441 +FROM gcr.io/distroless/static:nonroot@sha256:e9ac71e2b8e279a8372741b7a0293afda17650d926900233ec3a7b2b7c22a246 ARG TARGETPLATFORM COPY $TARGETPLATFORM/envoy-gateway /usr/local/bin/ diff --git a/tools/linter/codespell/.codespell.ignorewords b/tools/linter/codespell/.codespell.ignorewords index e773f85868e..7e58fec561e 100644 --- a/tools/linter/codespell/.codespell.ignorewords +++ b/tools/linter/codespell/.codespell.ignorewords @@ -2,3 +2,4 @@ keypair keypairs als requestor +immediatedly \ No newline at end of file diff --git a/tools/linter/golangci-lint/.golangci.yml b/tools/linter/golangci-lint/.golangci.yml index 36ed0cb1ff2..267fbc46c9a 100644 --- a/tools/linter/golangci-lint/.golangci.yml +++ b/tools/linter/golangci-lint/.golangci.yml @@ -8,6 +8,7 @@ linters: - errorlint - exportloopref - gofmt + - gofumpt - goimports - goheader - gocritic diff --git a/tools/make/golang.mk b/tools/make/golang.mk index 4ea47019f0f..9e4937b3df3 100644 --- a/tools/make/golang.mk +++ b/tools/make/golang.mk @@ -59,7 +59,7 @@ go.testdata.complete: ## Override test ouputdata go.test.coverage: go.test.cel ## Run go unit and integration tests in GitHub Actions @$(LOG_TARGET) KUBEBUILDER_ASSETS="$(shell $(tools/setup-envtest) use $(ENVTEST_K8S_VERSION) -p path)" \ - go test ./... --tags=integration,celvalidation -race -coverprofile=coverage.xml -covermode=atomic + go test ./... --tags=integration -race -coverprofile=coverage.xml -covermode=atomic .PHONY: go.test.cel go.test.cel: manifests $(tools/setup-envtest) # Run the CEL validation tests diff --git a/tools/make/kube.mk b/tools/make/kube.mk index f30dd5e0e7a..8d8c96a76d2 100644 --- a/tools/make/kube.mk +++ b/tools/make/kube.mk @@ -126,9 +126,12 @@ run-e2e: install-e2e-telemetry kubectl apply -f test/config/gatewayclass.yaml ifeq ($(E2E_RUN_TEST),) go test -v -tags e2e ./test/e2e --gateway-class=envoy-gateway --debug=true --cleanup-base-resources=false + go test -v -tags e2e ./test/e2e/merge_gateways --gateway-class=merge-gateways --debug=true --cleanup-base-resources=false go test -v -tags e2e ./test/e2e/upgrade --gateway-class=upgrade --debug=true --cleanup-base-resources=$(E2E_CLEANUP) else ifeq ($(E2E_RUN_EG_UPGRADE_TESTS),false) + go test -v -tags e2e ./test/e2e/merge_gateways --gateway-class=merge-gateways --debug=true --cleanup-base-resources=false \ + --run-test $(E2E_RUN_TEST) go test -v -tags e2e ./test/e2e --gateway-class=envoy-gateway --debug=true --cleanup-base-resources=$(E2E_CLEANUP) \ --run-test $(E2E_RUN_TEST) else @@ -136,6 +139,7 @@ else --run-test $(E2E_RUN_TEST) endif endif + .PHONY: install-e2e-telemetry install-e2e-telemetry: prepare-helm-repo install-fluent-bit install-loki install-tempo install-otel-collector install-prometheus @$(LOG_TARGET) diff --git a/tools/make/lint.mk b/tools/make/lint.mk index 57bf36dffff..f68bc85ea10 100644 --- a/tools/make/lint.mk +++ b/tools/make/lint.mk @@ -20,7 +20,7 @@ lint: lint.golint lint-deps: $(tools/golangci-lint) lint.golint: $(tools/golangci-lint) @$(LOG_TARGET) - $(tools/golangci-lint) run $(GOLANGCI_LINT_FLAGS) --build-tags=e2e --config=tools/linter/golangci-lint/.golangci.yml + $(tools/golangci-lint) run $(GOLANGCI_LINT_FLAGS) --build-tags=e2e,celvalidation --config=tools/linter/golangci-lint/.golangci.yml .PHONY: lint.yamllint lint: lint.yamllint @@ -69,10 +69,10 @@ lint.shellcheck: $(tools/shellcheck) $(tools/shellcheck) tools/hack/*.sh .PHONY: gen-check -gen-check: generate manifests go.testdata.complete +gen-check: generate manifests protos go.testdata.complete @$(LOG_TARGET) @if [ ! -z "`git status --porcelain`" ]; then \ - $(call errorlog, ERROR: Some files need to be updated, please run 'make generate' and 'make manifests' to include any changed files to your PR); \ + $(call errorlog, ERROR: Some files need to be updated, please run 'make generate', 'make manifests' and 'make protos' to include any changed files to your PR); \ git diff --exit-code; \ fi diff --git a/tools/src/buf/go.mod b/tools/src/buf/go.mod index c2c481a8605..ce8418a052e 100644 --- a/tools/src/buf/go.mod +++ b/tools/src/buf/go.mod @@ -1,26 +1,25 @@ module local -go 1.22 +go 1.22.2 -require github.com/bufbuild/buf v1.30.1 +require github.com/bufbuild/buf v1.31.0 require ( - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1 // indirect - connectrpc.com/connect v1.16.0 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1 // indirect + connectrpc.com/connect v1.16.1 // indirect connectrpc.com/otelconnect v0.7.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/bufbuild/protocompile v0.9.0 // indirect - github.com/bufbuild/protovalidate-go v0.6.0 // indirect - github.com/bufbuild/protoyaml-go v0.1.8 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/bufbuild/protocompile v0.12.0 // indirect + github.com/bufbuild/protovalidate-go v0.6.2 // indirect + github.com/bufbuild/protoyaml-go v0.1.9 // indirect github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/cli v26.0.0+incompatible // indirect + github.com/docker/cli v26.1.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v26.0.0+incompatible // indirect + github.com/docker/docker v26.1.0+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.1 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -29,16 +28,16 @@ require ( github.com/go-chi/chi/v5 v5.0.12 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/gofrs/uuid/v5 v5.0.0 // indirect + github.com/gofrs/uuid/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/cel-go v0.20.1 // indirect github.com/google/go-containerregistry v0.19.1 // indirect - github.com/google/pprof v0.0.0-20240327155427-868f304927ed // indirect + github.com/google/pprof v0.0.0-20240422182052-72c8669ad3e7 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jdx/go-netrc v1.0.0 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/pgzip v1.2.6 // indirect - github.com/kr/pretty v0.3.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/term v0.5.0 // indirect @@ -48,7 +47,6 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/profile v1.7.0 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/cors v1.10.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect @@ -56,27 +54,25 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/vbatts/tar-split v0.11.5 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect + go.opentelemetry.io/otel v1.25.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/sdk v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/otel/sdk v1.25.0 // indirect + go.opentelemetry.io/otel/trace v1.25.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect - golang.org/x/mod v0.16.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.19.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect + google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/tools/src/buf/go.sum b/tools/src/buf/go.sum index 89205e47859..0989f6b445e 100644 --- a/tools/src/buf/go.sum +++ b/tools/src/buf/go.sum @@ -1,25 +1,25 @@ -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1 h1:0nWhrRcnkgw1kwJ7xibIO8bqfOA7pBzBjGCDBxIHch8= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1/go.mod h1:Tgn5bgL220vkFOI0KPStlcClPeOJzAv4uT+V8JXGUnw= -connectrpc.com/connect v1.16.0 h1:rdtfQjZ0OyFkWPTegBNcH7cwquGAN1WzyJy80oFNibg= -connectrpc.com/connect v1.16.0/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1 h1:2IGhRovxlsOIQgx2ekZWo4wTPAYpck41+18ICxs37is= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1/go.mod h1:Tgn5bgL220vkFOI0KPStlcClPeOJzAv4uT+V8JXGUnw= +connectrpc.com/connect v1.16.1 h1:rOdrK/RTI/7TVnn3JsVxt3n028MlTRwmK5Q4heSpjis= +connectrpc.com/connect v1.16.1/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw= connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY= connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= -github.com/bufbuild/buf v1.30.1 h1:QFtanwsXodoGFAwzXFXGXpzBkb7N2u8ZDyA3jWB4Pbs= -github.com/bufbuild/buf v1.30.1/go.mod h1:7W8DJnj76wQa55EA3z2CmDxS0/nsHh8FqtE00dyDAdA= -github.com/bufbuild/protocompile v0.9.0 h1:DI8qLG5PEO0Mu1Oj51YFPqtx6I3qYXUAhJVJ/IzAVl0= -github.com/bufbuild/protocompile v0.9.0/go.mod h1:s89m1O8CqSYpyE/YaSGtg1r1YFMF5nLTwh4vlj6O444= -github.com/bufbuild/protovalidate-go v0.6.0 h1:Jgs1kFuZ2LHvvdj8SpCLA1W/+pXS8QSM3F/E2l3InPY= -github.com/bufbuild/protovalidate-go v0.6.0/go.mod h1:1LamgoYHZ2NdIQH0XGczGTc6Z8YrTHjcJVmiBaar4t4= -github.com/bufbuild/protoyaml-go v0.1.8 h1:X9QDLfl9uEllh4gsXUGqPanZYCOKzd92uniRtW2OnAQ= -github.com/bufbuild/protoyaml-go v0.1.8/go.mod h1:R8vE2+l49bSiIExP4VJpxOXleHE+FDzZ6HVxr3cYunw= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/bufbuild/buf v1.31.0 h1:YHLGIr8bjcLaTCIw0+/bCAvJLiR8u46QTwKvn7miSEg= +github.com/bufbuild/buf v1.31.0/go.mod h1:LlxpG2LF33f1Ixw29BTt0pyLriLzg3rXY1K9XQVHSio= +github.com/bufbuild/protocompile v0.12.0 h1:KnGWHxI4IX+/44yQTyOl9VYzfk6TUWuYepTwnUFuRI0= +github.com/bufbuild/protocompile v0.12.0/go.mod h1:dr++fGGeMPWHv7jPeT06ZKukm45NJscd7rUxQVzEKRk= +github.com/bufbuild/protovalidate-go v0.6.2 h1:U/V3CGF0kPlR12v41rjO4DrYZtLcS4ZONLmWN+rJVCQ= +github.com/bufbuild/protovalidate-go v0.6.2/go.mod h1:4BR3rKEJiUiTy+sqsusFn2ladOf0kYmA2Reo6BHSBgQ= +github.com/bufbuild/protoyaml-go v0.1.9 h1:anV5UtF1Mlvkkgp4NWA6U/zOnJFng8Orq4Vf3ZUQHBU= +github.com/bufbuild/protoyaml-go v0.1.9/go.mod h1:KCBItkvZOK/zwGueLdH1Wx1RLyFn5rCH7YjQrdty2Wc= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= @@ -36,7 +36,6 @@ github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9N github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,12 +43,12 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v26.0.0+incompatible h1:90BKrx1a1HKYpSnnBFR6AgDq/FqkHxwlUyzJVPxD30I= -github.com/docker/cli v26.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v26.1.0+incompatible h1:+nwRy8Ocd8cYNQ60mozDDICICD8aoFGtlPXifX/UQ3Y= +github.com/docker/cli v26.1.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v26.0.0+incompatible h1:Ng2qi+gdKADUa/VM+6b6YaY2nlZhk/lVJiKR/2bMudU= -github.com/docker/docker v26.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v26.1.0+incompatible h1:W1G9MPNbskA6VZWL7b3ZljTh0pXI68FpINx0GKaOdaM= +github.com/docker/docker v26.1.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= @@ -75,8 +74,8 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M= -github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +github.com/gofrs/uuid/v5 v5.1.0 h1:S5rqVKIigghZTCBKPCw0Y+bXkn26K3TB5mvQq2Ix8dk= +github.com/gofrs/uuid/v5 v5.1.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -91,10 +90,10 @@ github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/pprof v0.0.0-20240327155427-868f304927ed h1:n8QtJTrwsv3P7dNxPaMeNkMcxvUpqocsHLr8iDLGlQI= -github.com/google/pprof v0.0.0-20240327155427-868f304927ed/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/google/pprof v0.0.0-20240422182052-72c8669ad3e7 h1:3q13T5NW3mlTJZM6B5UAsf2N5NYFbYWIyI3W8DlvBDU= +github.com/google/pprof v0.0.0-20240422182052-72c8669ad3e7/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -106,8 +105,8 @@ github.com/jhump/protoreflect v1.15.6/go.mod h1:jCHoyYQIJnaabEYnbGwyo9hUqfyUMTbJ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -131,14 +130,12 @@ github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2sz github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= @@ -166,24 +163,24 @@ github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinC github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 h1:9M3+rhx7kZCIQQhQRYaZCdNu1V73tm4TvXs2ntl98C4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0/go.mod h1:noq80iT8rrHP1SfybmPiRGc9dc5M8RPmGvtwo7Oo7tc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= -go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= +go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= go.opentelemetry.io/otel/sdk/metric v1.19.0 h1:EJoTO5qysMsYCa+w4UghwFV/ptQgqSL/8Ni+hx+8i1k= go.opentelemetry.io/otel/sdk/metric v1.19.0/go.mod h1:XjG0jQyFJrv2PbMvwND7LwCEhsJzCzV5210euduKcKY= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= -go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -195,25 +192,25 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -223,10 +220,10 @@ golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -237,21 +234,22 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa h1:Jt1XW5PaLXF1/ePZrznsh/aAUvI7Adfc3LY1dAKlzRs= -google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:K4kfzHtI0kqWA79gecJarFtDn/Mls+GxQcg3Zox91Ac= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa h1:RBgMaUMP+6soRkik4VoN8ojR2nex2TqZwjSSogic+eo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU= +google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002 h1:V7Da7qt0MkY3noVANIMVBk28nOnijADeOR3i5Hcvpj4= +google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/tools/src/controller-gen/go.mod b/tools/src/controller-gen/go.mod index 8e0dc95e504..912f4804b90 100644 --- a/tools/src/controller-gen/go.mod +++ b/tools/src/controller-gen/go.mod @@ -1,12 +1,12 @@ module local -go 1.22 +go 1.22.2 -require sigs.k8s.io/controller-tools v0.14.0 +require sigs.k8s.io/controller-tools v0.15.0 require ( github.com/fatih/color v1.16.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/gobuffalo/flect v1.0.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -18,19 +18,20 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.20.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.29.0 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/apimachinery v0.29.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + k8s.io/api v0.30.0 // indirect + k8s.io/apiextensions-apiserver v0.30.0 // indirect + k8s.io/apimachinery v0.30.0 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/tools/src/controller-gen/go.sum b/tools/src/controller-gen/go.sum index c7762224299..797074f310a 100644 --- a/tools/src/controller-gen/go.sum +++ b/tools/src/controller-gen/go.sum @@ -6,8 +6,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -42,8 +42,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -69,26 +69,26 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -97,8 +97,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -116,18 +116,18 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= -sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= +k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= +k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= +k8s.io/apiextensions-apiserver v0.30.0 h1:jcZFKMqnICJfRxTgnC4E+Hpcq8UEhT8B2lhBcQ+6uAs= +k8s.io/apiextensions-apiserver v0.30.0/go.mod h1:N9ogQFGcrbWqAY9p2mUAL5mGxsLqwgtUce127VtRX5Y= +k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= +k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 h1:ao5hUqGhsqdm+bYbjH/pRkCs0unBGe9UyDahzs9zQzQ= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-tools v0.15.0 h1:4dxdABXGDhIa68Fiwaif0vcu32xfwmgQ+w8p+5CxoAI= +sigs.k8s.io/controller-tools v0.15.0/go.mod h1:8zUSS2T8Hx0APCNRhJWbS3CAQEbIxLa07khzh7pZmXM= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/tools/src/crd-ref-docs/go.mod b/tools/src/crd-ref-docs/go.mod index eb1f6e419eb..764ff255a6f 100644 --- a/tools/src/crd-ref-docs/go.mod +++ b/tools/src/crd-ref-docs/go.mod @@ -1,22 +1,22 @@ module local -go 1.22 +go 1.22.2 -require github.com/elastic/crd-ref-docs v0.0.11 +require github.com/elastic/crd-ref-docs v0.0.13-0.20240413123740-ea9fcaa0230f require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/fatih/color v1.16.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/gobuffalo/flect v1.0.2 // indirect - github.com/goccy/go-yaml v1.11.0 // indirect + github.com/goccy/go-yaml v1.11.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -27,22 +27,22 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + golang.org/x/tools v0.20.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/apimachinery v0.29.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + k8s.io/apiextensions-apiserver v0.29.3 // indirect + k8s.io/apimachinery v0.29.3 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/utils v0.0.0-20240310230437-4693a0247e57 // indirect sigs.k8s.io/controller-tools v0.14.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/tools/src/crd-ref-docs/go.sum b/tools/src/crd-ref-docs/go.sum index 53559cc9ef3..af2c38bb430 100644 --- a/tools/src/crd-ref-docs/go.sum +++ b/tools/src/crd-ref-docs/go.sum @@ -4,20 +4,22 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/crd-ref-docs v0.0.11 h1:/wNYycaIOQSnWPDdteRnx3IqvTBTzieQ6PHJS+g6nO4= -github.com/elastic/crd-ref-docs v0.0.11/go.mod h1:B4kHxcBLQ41TbGnUTjdliNmuG6Dv7MFrH2pmYTjN4IQ= +github.com/elastic/crd-ref-docs v0.0.12 h1:F3seyncbzUz3rT3d+caeYWhumb5ojYQ6Bl0Z+zOp16M= +github.com/elastic/crd-ref-docs v0.0.12/go.mod h1:X83mMBdJt05heJUYiS3T0yJ/JkCuliuhSUNav5Gjo/U= +github.com/elastic/crd-ref-docs v0.0.13-0.20240413123740-ea9fcaa0230f h1:cE1CF4Bfi+9gvaNz35jOsp3tFJVm/mFr88szZ41FG8Q= +github.com/elastic/crd-ref-docs v0.0.13-0.20240413123740-ea9fcaa0230f/go.mod h1:X83mMBdJt05heJUYiS3T0yJ/JkCuliuhSUNav5Gjo/U= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= @@ -26,8 +28,8 @@ github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7a github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/goccy/go-yaml v1.11.0 h1:n7Z+zx8S9f9KgzG6KtQKf+kwqXZlLNR2F6018Dgau54= -github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng= +github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= +github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -38,10 +40,14 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -70,8 +76,6 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -86,45 +90,55 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +github.com/zirain/crd-ref-docs v0.0.0-20240330085406-9336d26578da h1:hWtaeh12ZlN8dCexpNFhzK68LayDbql4nNgfe+cYUPc= +github.com/zirain/crd-ref-docs v0.0.0-20240330085406-9336d26578da/go.mod h1:X83mMBdJt05heJUYiS3T0yJ/JkCuliuhSUNav5Gjo/U= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -133,14 +147,16 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -156,12 +172,18 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= +k8s.io/apiextensions-apiserver v0.29.3 h1:9HF+EtZaVpFjStakF4yVufnXGPRppWFEQ87qnO91YeI= +k8s.io/apiextensions-apiserver v0.29.3/go.mod h1:po0XiY5scnpJfFizNGo6puNU6Fq6D70UJY2Cb2KwAVc= +k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= +k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= +k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/tools/src/golangci-lint/go.mod b/tools/src/golangci-lint/go.mod index 73ad3b2baae..9452d02b750 100644 --- a/tools/src/golangci-lint/go.mod +++ b/tools/src/golangci-lint/go.mod @@ -1,6 +1,6 @@ module local -go 1.22 +go 1.22.2 require github.com/golangci/golangci-lint v1.57.2 diff --git a/tools/src/helm-docs/go.mod b/tools/src/helm-docs/go.mod index 7febe31cc86..b965c0bb36c 100644 --- a/tools/src/helm-docs/go.mod +++ b/tools/src/helm-docs/go.mod @@ -1,6 +1,6 @@ module github.com/envoyproxy/gateway/tools/src/helm-docs -go 1.22 +go 1.22.2 require github.com/norwoodj/helm-docs v1.13.0 diff --git a/tools/src/kind/go.mod b/tools/src/kind/go.mod index 5bde933138b..4489b3fa0b1 100644 --- a/tools/src/kind/go.mod +++ b/tools/src/kind/go.mod @@ -1,6 +1,6 @@ module github.com/envoyproxy/gateway/tools/src/kind -go 1.22 +go 1.22.2 require sigs.k8s.io/kind v0.22.0 diff --git a/tools/src/protoc-gen-go-grpc/go.mod b/tools/src/protoc-gen-go-grpc/go.mod index d1a4ce8af09..df13e99fa8f 100644 --- a/tools/src/protoc-gen-go-grpc/go.mod +++ b/tools/src/protoc-gen-go-grpc/go.mod @@ -1,7 +1,7 @@ module github.com/envoyproxy/gateway/tools/src/protoc-gen-go-grpc -go 1.22 +go 1.22.2 require google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 -require google.golang.org/protobuf v1.28.1 // indirect +require google.golang.org/protobuf v1.33.0 // indirect diff --git a/tools/src/protoc-gen-go-grpc/go.sum b/tools/src/protoc-gen-go-grpc/go.sum index 8d750cf2b44..310db1131fb 100644 --- a/tools/src/protoc-gen-go-grpc/go.sum +++ b/tools/src/protoc-gen-go-grpc/go.sum @@ -1,10 +1,8 @@ -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= diff --git a/tools/src/protoc-gen-go/go.mod b/tools/src/protoc-gen-go/go.mod index f8a47363e9e..fac0556186e 100644 --- a/tools/src/protoc-gen-go/go.mod +++ b/tools/src/protoc-gen-go/go.mod @@ -1,5 +1,5 @@ module github.com/envoyproxy/gateway/tools/src/protoc-gen-go -go 1.22 +go 1.22.2 -require google.golang.org/protobuf v1.30.0 +require google.golang.org/protobuf v1.33.0 diff --git a/tools/src/protoc-gen-go/go.sum b/tools/src/protoc-gen-go/go.sum index 1838366909d..2e26fa55dea 100644 --- a/tools/src/protoc-gen-go/go.sum +++ b/tools/src/protoc-gen-go/go.sum @@ -1,8 +1,6 @@ -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= diff --git a/tools/src/setup-envtest/go.mod b/tools/src/setup-envtest/go.mod index 63d0027536d..02a0ec3ef80 100644 --- a/tools/src/setup-envtest/go.mod +++ b/tools/src/setup-envtest/go.mod @@ -1,22 +1,15 @@ module local -go 1.22 +go 1.22.2 -require sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20220706173534-cd0058ad295c +require sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240423173400-ed81fa696dea require ( - github.com/fsnotify/fsnotify v1.5.1 // indirect - github.com/go-logr/logr v1.2.0 // indirect - github.com/go-logr/zapr v1.2.0 // indirect - github.com/onsi/gomega v1.18.1 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/zapr v1.2.4 // indirect github.com/spf13/afero v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/goleak v1.1.12 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.19.1 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.27.1 // indirect + go.uber.org/multierr v1.10.0 // indirect + go.uber.org/zap v1.26.0 // indirect + golang.org/x/text v0.12.0 // indirect ) diff --git a/tools/src/setup-envtest/go.sum b/tools/src/setup-envtest/go.sum index 21852a2c4b5..42182a05c06 100644 --- a/tools/src/setup-envtest/go.sum +++ b/tools/src/setup-envtest/go.sum @@ -1,57 +1,28 @@ -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= +github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -61,102 +32,66 @@ github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20220706173534-cd0058ad295c h1:lLwQLSoxN2jTkJdtzpBgm8bFrKP450F0KWx85/ga68s= -sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20220706173534-cd0058ad295c/go.mod h1:nLkMD2WB4Jcix1qfVuJeOF4j5y/VfyeOIlTxG5Wj9co= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240423173400-ed81fa696dea h1:DHNmuXblCDcQ9DoxnUWcqsSeFneWU2SxvGUnOOqUcZE= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20240423173400-ed81fa696dea/go.mod h1:B2xTzIWVko5xZLWDkXFS7Zo9hxX+ecdMzZ8oiTPJoRI= diff --git a/tools/src/sphinx-build/requirements.txt b/tools/src/sphinx-build/requirements.txt index c25f298978f..16fc53701bf 100644 --- a/tools/src/sphinx-build/requirements.txt +++ b/tools/src/sphinx-build/requirements.txt @@ -1,2 +1,2 @@ -Sphinx==7.2.6 -myst-parser==2.0.0 +Sphinx==7.3.7 +myst-parser==3.0.1