diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go
index c94682198b4..36cc1b1e5aa 100644
--- a/api/v1alpha1/ext_proc_types.go
+++ b/api/v1alpha1/ext_proc_types.go
@@ -9,6 +9,88 @@ import (
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
+// +kubebuilder:validation:Enum=Default;Send;Skip
+type ExtProcHeaderProcessingMode string
+
+const (
+ DefaultExtProcHeaderProcessingMode ExtProcHeaderProcessingMode = "Default"
+ SendExtProcHeaderProcessingMode ExtProcHeaderProcessingMode = "Send"
+ SkipExtProcHeaderProcessingMode ExtProcHeaderProcessingMode = "Skip"
+)
+
+// +kubebuilder:validation:Enum=None;Streamed;Buffered;BufferedPartial
+type ExtProcBodyProcessingMode string
+
+const (
+ NoneExtProcHeaderProcessingMode ExtProcBodyProcessingMode = "None"
+ StreamedExtProcHeaderProcessingMode ExtProcBodyProcessingMode = "Streamed"
+ BufferedExtProcHeaderProcessingMode ExtProcBodyProcessingMode = "Buffered"
+ BufferedPartialExtProcHeaderProcessingMode ExtProcBodyProcessingMode = "BufferedPartial"
+)
+
+// ProcessingModeOptions defines if headers or body should be processed by the external service
+type ProcessingModeOptions struct {
+ // Defines header processing mode
+ //
+ // +optional
+ Headers *ExtProcHeaderProcessingMode `json:"headers,omitempty"`
+
+ // 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 header and body processing for requests
+ //
+ // +optional
+ Request *ProcessingModeOptions `json:"request,omitempty"`
+
+ // Defines header and body processing for responses
+ //
+ // +optional
+ Response *ProcessingModeOptions `json:"response,omitempty"`
+}
+
+// ExtProcAttributes defines which attributes are
+type ExtProcAttributes struct {
+ // defines attributes to send for Request processing
+ //
+ // +optional
+ Request []string `json:"request,omitempty"`
+
+ // defines attributes to send for Response processing
+ //
+ // +optional
+ Response []string `json:"response,omitempty"`
+}
+
+// MetadataNamespaces defines metadata namespaces that can be used to forward or receive dynamic metadata
+type MetadataNamespaces struct {
+ // Specifies a list of metadata namespaces whose values, if present, will be passed to the ext_proc service
+ // as an opaque protobuf::Struct.
+ //
+ // +optional
+ Untyped []string `json:"untyped,omitempty"`
+}
+
+// ExtProcMetadataOptions defines options related to the sending and receiving of dynamic metadata to and from the
+// external processor service
+type ExtProcMetadataOptions struct {
+ // metadata namespaces forwarded to external processor
+ //
+ // +optional
+ ForwardingNamespaces []MetadataNamespaces `json:"forwardingNamespaces,omitempty"`
+
+ // metadata namespaces updatable by external processor
+ //
+ // +optional
+ ReceivingNamespaces []MetadataNamespaces `json:"receivingNamespaces,omitempty"`
+}
+
// +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"
//
@@ -16,6 +98,37 @@ import (
type ExtProc struct {
// Service defines the configuration of the external processing service
BackendRef ExtProcBackendRef `json:"backendRef"`
+
+ // ProcessingMode defines how request and response headers and body are processed
+ // Default: request and response headers are sent, body is not sent
+ //
+ // +optional
+ ProcessingMode *ExtProcProcessingMode `json:"processingMode,omitempty"`
+
+ // Attributes defines which envoy request and response attributes are provided as context to external processor
+ // Default: no attributes are sent
+ //
+ // +optional
+ Attributes *ExtProcAttributes `json:"attributes,omitempty"`
+
+ // MetadataOptions defines options related to the sending and receiving of dynamic metadata
+ // Default: no metadata context is sent or received
+ //
+ // +optional
+ MetadataOptions *ExtProcMetadataOptions `json:"metadataOptions,omitempty"`
+
+ // 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
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index a5005944bbe..652218e15f7 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -1490,6 +1490,31 @@ func (in *ExtAuth) DeepCopy() *ExtAuth {
func (in *ExtProc) DeepCopyInto(out *ExtProc) {
*out = *in
in.BackendRef.DeepCopyInto(&out.BackendRef)
+ if in.ProcessingMode != nil {
+ in, out := &in.ProcessingMode, &out.ProcessingMode
+ *out = new(ExtProcProcessingMode)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Attributes != nil {
+ in, out := &in.Attributes, &out.Attributes
+ *out = new(ExtProcAttributes)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.MetadataOptions != nil {
+ in, out := &in.MetadataOptions, &out.MetadataOptions
+ *out = new(ExtProcMetadataOptions)
+ (*in).DeepCopyInto(*out)
+ }
+ 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
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProc.
@@ -1502,6 +1527,31 @@ func (in *ExtProc) DeepCopy() *ExtProc {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ExtProcAttributes) DeepCopyInto(out *ExtProcAttributes) {
+ *out = *in
+ if in.Request != nil {
+ in, out := &in.Request, &out.Request
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.Response != nil {
+ in, out := &in.Response, &out.Response
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProcAttributes.
+func (in *ExtProcAttributes) DeepCopy() *ExtProcAttributes {
+ if in == nil {
+ return nil
+ }
+ out := new(ExtProcAttributes)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExtProcBackendRef) DeepCopyInto(out *ExtProcBackendRef) {
*out = *in
@@ -1518,6 +1568,60 @@ func (in *ExtProcBackendRef) DeepCopy() *ExtProcBackendRef {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ExtProcMetadataOptions) DeepCopyInto(out *ExtProcMetadataOptions) {
+ *out = *in
+ if in.ForwardingNamespaces != nil {
+ in, out := &in.ForwardingNamespaces, &out.ForwardingNamespaces
+ *out = make([]MetadataNamespaces, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.ReceivingNamespaces != nil {
+ in, out := &in.ReceivingNamespaces, &out.ReceivingNamespaces
+ *out = make([]MetadataNamespaces, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProcMetadataOptions.
+func (in *ExtProcMetadataOptions) DeepCopy() *ExtProcMetadataOptions {
+ if in == nil {
+ return nil
+ }
+ out := new(ExtProcMetadataOptions)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ExtProcProcessingMode) DeepCopyInto(out *ExtProcProcessingMode) {
+ *out = *in
+ 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 ExtProcProcessingMode.
+func (in *ExtProcProcessingMode) DeepCopy() *ExtProcProcessingMode {
+ if in == nil {
+ return nil
+ }
+ out := new(ExtProcProcessingMode)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExtensionAPISettings) DeepCopyInto(out *ExtensionAPISettings) {
*out = *in
@@ -2584,6 +2688,26 @@ func (in *LocalRateLimit) DeepCopy() *LocalRateLimit {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetadataNamespaces) DeepCopyInto(out *MetadataNamespaces) {
+ *out = *in
+ if in.Untyped != nil {
+ in, out := &in.Untyped, &out.Untyped
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetadataNamespaces.
+func (in *MetadataNamespaces) DeepCopy() *MetadataNamespaces {
+ if in == nil {
+ return nil
+ }
+ out := new(MetadataNamespaces)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDC) DeepCopyInto(out *OIDC) {
*out = *in
@@ -2773,6 +2897,31 @@ 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.Headers != nil {
+ in, out := &in.Headers, &out.Headers
+ *out = new(ExtProcHeaderProcessingMode)
+ **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
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..c0b70836bc7 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
@@ -57,6 +57,22 @@ spec:
description: ExtProc defines the configuration for External Processing
filter.
properties:
+ attributes:
+ description: |-
+ Attributes defines which envoy request and response attributes are provided as context to external processor
+ Default: no attributes are sent
+ properties:
+ request:
+ description: defines attributes to send for Request processing
+ items:
+ type: string
+ type: array
+ response:
+ description: defines attributes to send for Response processing
+ items:
+ type: string
+ type: array
+ type: object
backendRef:
description: Service defines the configuration of the external
processing service
@@ -134,6 +150,98 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
+ 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
+ metadataOptions:
+ description: |-
+ MetadataOptions defines options related to the sending and receiving of dynamic metadata
+ Default: no metadata context is sent or received
+ properties:
+ forwardingNamespaces:
+ description: metadata namespaces forwarded to external processor
+ items:
+ description: MetadataNamespaces defines metadata namespaces
+ that can be used to forward or receive dynamic metadata
+ properties:
+ untyped:
+ description: |-
+ Specifies a list of metadata namespaces whose values, if present, will be passed to the ext_proc service
+ as an opaque protobuf::Struct.
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ receivingNamespaces:
+ description: metadata namespaces updatable by external processor
+ items:
+ description: MetadataNamespaces defines metadata namespaces
+ that can be used to forward or receive dynamic metadata
+ properties:
+ untyped:
+ description: |-
+ Specifies a list of metadata namespaces whose values, if present, will be passed to the ext_proc service
+ as an opaque protobuf::Struct.
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ type: object
+ processingMode:
+ description: |-
+ ProcessingMode defines how request and response headers and body are processed
+ Default: request and response headers are sent, body is not sent
+ properties:
+ request:
+ description: Defines header and body processing for requests
+ properties:
+ body:
+ description: Defines body processing mode
+ enum:
+ - None
+ - Streamed
+ - Buffered
+ - BufferedPartial
+ type: string
+ headers:
+ description: Defines header processing mode
+ enum:
+ - Default
+ - Send
+ - Skip
+ type: string
+ type: object
+ response:
+ description: Defines header and body processing for responses
+ properties:
+ body:
+ description: Defines body processing mode
+ enum:
+ - None
+ - Streamed
+ - Buffered
+ - BufferedPartial
+ type: string
+ headers:
+ description: Defines header processing mode
+ enum:
+ - Default
+ - Send
+ - Skip
+ type: string
+ type: object
+ type: object
required:
- backendRef
type: object
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index 48eaf709334..045a608cc50 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -1018,6 +1018,26 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `backendRef` | _[ExtProcBackendRef](#extprocbackendref)_ | true | Service defines the configuration of the external processing service |
+| `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response headers and body are processed
Default: request and response headers are sent, body is not sent |
+| `attributes` | _[ExtProcAttributes](#extprocattributes)_ | false | Attributes defines which envoy request and response attributes are provided as context to external processor
Default: no attributes are sent |
+| `metadataOptions` | _[ExtProcMetadataOptions](#extprocmetadataoptions)_ | false | MetadataOptions defines options related to the sending and receiving of dynamic metadata
Default: no metadata context is sent or received |
+| `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 |
+
+
+#### ExtProcAttributes
+
+
+
+ExtProcAttributes defines which attributes are
+
+_Appears in:_
+- [ExtProc](#extproc)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `request` | _string array_ | false | defines attributes to send for Request processing |
+| `response` | _string array_ | false | defines attributes to send for Response processing |
#### ExtProcBackendRef
@@ -1040,6 +1060,60 @@ _Appears in:_
| `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. |
+#### ExtProcBodyProcessingMode
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProcessingModeOptions](#processingmodeoptions)
+
+
+
+#### ExtProcHeaderProcessingMode
+
+_Underlying type:_ _string_
+
+
+
+_Appears in:_
+- [ProcessingModeOptions](#processingmodeoptions)
+
+
+
+#### ExtProcMetadataOptions
+
+
+
+ExtProcMetadataOptions defines options related to the sending and receiving of dynamic metadata to and from the
+external processor service
+
+_Appears in:_
+- [ExtProc](#extproc)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `forwardingNamespaces` | _[MetadataNamespaces](#metadatanamespaces) array_ | false | metadata namespaces forwarded to external processor |
+| `receivingNamespaces` | _[MetadataNamespaces](#metadatanamespaces) array_ | false | metadata namespaces updatable by external processor |
+
+
+#### ExtProcProcessingMode
+
+
+
+ExtProcProcessingMode defines if and how headers and bodies are sent to the service.
+https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto#envoy-v3-api-msg-extensions-filters-http-ext-proc-v3-processingmode
+
+_Appears in:_
+- [ExtProc](#extproc)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `request` | _[ProcessingModeOptions](#processingmodeoptions)_ | false | Defines header and body processing for requests |
+| `response` | _[ProcessingModeOptions](#processingmodeoptions)_ | false | Defines header and body processing for responses |
+
+
#### ExtensionAPISettings
@@ -1774,6 +1848,20 @@ _Appears in:_
+#### MetadataNamespaces
+
+
+
+MetadataNamespaces defines metadata namespaces that can be used to forward or receive dynamic metadata
+
+_Appears in:_
+- [ExtProcMetadataOptions](#extprocmetadataoptions)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `untyped` | _string array_ | false | Specifies a list of metadata namespaces whose values, if present, will be passed to the ext_proc service
as an opaque protobuf::Struct. |
+
+
#### MetricSinkType
_Underlying type:_ _string_
@@ -1926,6 +2014,21 @@ _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 |
+| --- | --- | --- | --- |
+| `headers` | _[ExtProcHeaderProcessingMode](#extprocheaderprocessingmode)_ | false | Defines header processing mode |
+| `body` | _[ExtProcBodyProcessingMode](#extprocbodyprocessingmode)_ | false | Defines body processing mode |
+
+
#### ProviderType
_Underlying type:_ _string_
diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go
index 4a179c84ec3..a18c9b892f2 100644
--- a/test/cel-validation/envoyextensionpolicy_test.go
+++ b/test/cel-validation/envoyextensionpolicy_test.go
@@ -11,6 +11,8 @@ package celvalidation
import (
"context"
"fmt"
+ "k8s.io/utils/ptr"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
"strings"
"testing"
"time"
@@ -151,6 +153,121 @@ 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{
+ {
+ BackendRef: egv1a1.ExtProcBackendRef{
+ 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{
+ {
+ BackendRef: egv1a1.ExtProcBackendRef{
+ 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]: Invalid value: \"object\": group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported"},
+ },
+ {
+ desc: "ExtProc with invalid BackendRef Kind",
+ mutate: func(sp *egv1a1.EnvoyExtensionPolicy) {
+ sp.Spec = egv1a1.EnvoyExtensionPolicySpec{
+ ExtProc: []egv1a1.ExtProc{
+ {
+ BackendRef: egv1a1.ExtProcBackendRef{
+ 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]: Invalid value: \"object\": kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported"},
+ },
+ {
+ desc: "ExtProc with invalid fields",
+ mutate: func(sp *egv1a1.EnvoyExtensionPolicy) {
+ sp.Spec = egv1a1.EnvoyExtensionPolicySpec{
+ ExtProc: []egv1a1.ExtProc{
+ {
+ BackendRef: egv1a1.ExtProcBackendRef{
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "grpc-proc-service",
+ Port: ptr.To(gwapiv1.PortNumber(80)),
+ },
+ },
+ ProcessingMode: &egv1a1.ExtProcProcessingMode{
+ Request: &egv1a1.ProcessingModeOptions{
+ Headers: ptr.To(egv1a1.ExtProcHeaderProcessingMode("not-a-header-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: \"None\", \"Streamed\", \"Buffered\", \"BufferedPartial\"",
+ "spec.extProc[0].processingMode.request.headers: Unsupported value: \"not-a-header-mode\": supported values: \"Default\", \"Send\", \"Skip\"",
+ },
+ },
}
for _, tc := range cases {