From 455b9f2b538f05d98aea7412017374d72a64473f Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Tue, 2 Apr 2024 16:06:24 -0500 Subject: [PATCH 1/7] extend extproc api Signed-off-by: Guy Daich --- api/v1alpha1/ext_proc_types.go | 113 +++++++++++++ api/v1alpha1/zz_generated.deepcopy.go | 149 ++++++++++++++++++ ....envoyproxy.io_envoyextensionpolicies.yaml | 108 +++++++++++++ site/content/en/latest/api/extension_types.md | 103 ++++++++++++ .../envoyextensionpolicy_test.go | 117 ++++++++++++++ 5 files changed, 590 insertions(+) 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 { From d1660eea97d080794f68d6b58662f9241f5351ac Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Wed, 3 Apr 2024 18:14:28 -0500 Subject: [PATCH 2/7] fix metadata options Signed-off-by: Guy Daich --- api/v1alpha1/ext_proc_types.go | 4 +- api/v1alpha1/zz_generated.deepcopy.go | 16 +------ ....envoyproxy.io_envoyextensionpolicies.yaml | 44 ++++++++----------- site/content/en/latest/api/extension_types.md | 4 +- 4 files changed, 24 insertions(+), 44 deletions(-) diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go index 36cc1b1e5aa..6be4186a07a 100644 --- a/api/v1alpha1/ext_proc_types.go +++ b/api/v1alpha1/ext_proc_types.go @@ -83,12 +83,12 @@ type ExtProcMetadataOptions struct { // metadata namespaces forwarded to external processor // // +optional - ForwardingNamespaces []MetadataNamespaces `json:"forwardingNamespaces,omitempty"` + ForwardingNamespaces MetadataNamespaces `json:"forwardingNamespaces,omitempty"` // metadata namespaces updatable by external processor // // +optional - ReceivingNamespaces []MetadataNamespaces `json:"receivingNamespaces,omitempty"` + 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" diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 652218e15f7..896b182b9aa 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1571,20 +1571,8 @@ func (in *ExtProcBackendRef) DeepCopy() *ExtProcBackendRef { // 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]) - } - } + in.ForwardingNamespaces.DeepCopyInto(&out.ForwardingNamespaces) + in.ReceivingNamespaces.DeepCopyInto(&out.ReceivingNamespaces) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtProcMetadataOptions. 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 c0b70836bc7..a5b95b11bfe 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -169,34 +169,26 @@ spec: 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 + 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 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 + 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: object processingMode: description: |- diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 045a608cc50..8e6895d30b0 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1094,8 +1094,8 @@ _Appears in:_ | 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 | +| `forwardingNamespaces` | _[MetadataNamespaces](#metadatanamespaces)_ | false | metadata namespaces forwarded to external processor | +| `receivingNamespaces` | _[MetadataNamespaces](#metadatanamespaces)_ | false | metadata namespaces updatable by external processor | #### ExtProcProcessingMode From 9d6fa29142cc929a59033725e0314f98cdb09c84 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Wed, 10 Apr 2024 12:05:15 -0500 Subject: [PATCH 3/7] rm attributes, metadata and processing mode Signed-off-by: Guy Daich --- api/v1alpha1/ext_proc_types.go | 20 +---- api/v1alpha1/zz_generated.deepcopy.go | 15 ---- ....envoyproxy.io_envoyextensionpolicies.yaml | 90 +------------------ site/content/en/latest/api/extension_types.md | 46 +--------- 4 files changed, 3 insertions(+), 168 deletions(-) diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go index 6be4186a07a..69b7e4e5a4c 100644 --- a/api/v1alpha1/ext_proc_types.go +++ b/api/v1alpha1/ext_proc_types.go @@ -96,27 +96,9 @@ type ExtProcMetadataOptions struct { // // ExtProc defines the configuration for External Processing filter. type ExtProc struct { - // Service defines the configuration of the external processing service + // BackendRef 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 // diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 86680f9d7a9..4da059030c7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1495,21 +1495,6 @@ 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) 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 a5b95b11bfe..b81adb1bebb 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -57,24 +57,8 @@ 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 + description: BackendRef defines the configuration of the external processing service properties: group: @@ -162,78 +146,6 @@ spec: 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 - 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 - receivingNamespaces: - description: metadata namespaces updatable by external processor - 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: 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 c375fabf1ed..53448875657 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1018,27 +1018,11 @@ _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 | +| `backendRef` | _[ExtProcBackendRef](#extprocbackendref)_ | true | BackendRef 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 | -#### 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 @@ -1083,36 +1067,8 @@ _Appears in:_ -#### 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)_ | false | metadata namespaces forwarded to external processor | -| `receivingNamespaces` | _[MetadataNamespaces](#metadatanamespaces)_ | 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 From 418e8359c295699756570074d7810df7be403c9a Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Wed, 10 Apr 2024 12:22:12 -0500 Subject: [PATCH 4/7] rm enums Signed-off-by: Guy Daich --- api/v1alpha1/ext_proc_types.go | 82 ------------- api/v1alpha1/zz_generated.deepcopy.go | 112 ------------------ site/content/en/latest/api/extension_types.md | 57 --------- 3 files changed, 251 deletions(-) diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go index 69b7e4e5a4c..4120d141635 100644 --- a/api/v1alpha1/ext_proc_types.go +++ b/api/v1alpha1/ext_proc_types.go @@ -9,88 +9,6 @@ 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" // diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 4da059030c7..edac7646ca7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1517,31 +1517,6 @@ 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 @@ -1558,48 +1533,6 @@ 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 - in.ForwardingNamespaces.DeepCopyInto(&out.ForwardingNamespaces) - in.ReceivingNamespaces.DeepCopyInto(&out.ReceivingNamespaces) -} - -// 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 @@ -2701,26 +2634,6 @@ 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 @@ -2910,31 +2823,6 @@ 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/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 53448875657..dea8a98f32d 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1023,8 +1023,6 @@ _Appears in:_ | `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 | - - #### ExtProcBackendRef @@ -1045,32 +1043,6 @@ _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) - - - - - - - #### ExtensionAPISettings @@ -1822,20 +1794,6 @@ _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_ @@ -1988,21 +1946,6 @@ _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_ From d407e1c66861c03fd159bfc182c6d7a76b34ee3b Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Wed, 10 Apr 2024 12:35:41 -0500 Subject: [PATCH 5/7] rm unrealted CEL Signed-off-by: Guy Daich --- .../envoyextensionpolicy_test.go | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go index a18c9b892f2..343a2be45fd 100644 --- a/test/cel-validation/envoyextensionpolicy_test.go +++ b/test/cel-validation/envoyextensionpolicy_test.go @@ -232,42 +232,6 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { }, 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 { From 1e0652d529f7b290ef38c15474dce4edbbe7f78d Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Fri, 12 Apr 2024 09:20:48 -0500 Subject: [PATCH 6/7] sort imports, add optional plural backendRefs Signed-off-by: Guy Daich --- api/v1alpha1/ext_proc_types.go | 5 ++ api/v1alpha1/zz_generated.deepcopy.go | 7 ++ ....envoyproxy.io_envoyextensionpolicies.yaml | 81 +++++++++++++++++++ site/content/en/latest/api/extension_types.md | 2 + .../envoyextensionpolicy_test.go | 9 ++- 5 files changed, 100 insertions(+), 4 deletions(-) diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go index 4120d141635..7499b9f8e4f 100644 --- a/api/v1alpha1/ext_proc_types.go +++ b/api/v1alpha1/ext_proc_types.go @@ -17,6 +17,11 @@ type ExtProc struct { // BackendRef defines the configuration of the external processing service BackendRef ExtProcBackendRef `json:"backendRef"` + // BackendRefs defines the configuration of the external processing service + // + // +optional + BackendRefs []BackendRef `json:"backendRefs,omitempty"` + // MessageTimeout is the timeout for a response to be returned from the external processor // Default: 200ms // diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 8f8ad8f184b..8cdc235e406 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1511,6 +1511,13 @@ func (in *ExtAuth) DeepCopy() *ExtAuth { 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) 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 b81adb1bebb..5016b3bd2d3 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -134,6 +134,87 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' + backendRefs: + description: BackendRefs defines the configuration of the external + processing 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. + + + 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' + type: array failOpen: description: |- FailOpen defines if requests or responses that cannot be processed due to connectivity to the diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 89f89055021..53750461e94 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -122,6 +122,7 @@ _Appears in:_ BackendRef defines how an ObjectReference that is specific to BackendRef. _Appears in:_ +- [ExtProc](#extproc) - [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog) - [ProxyOpenTelemetrySink](#proxyopentelemetrysink) - [TracingProvider](#tracingprovider) @@ -1039,6 +1040,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `backendRef` | _[ExtProcBackendRef](#extprocbackendref)_ | true | BackendRef defines the configuration of the external processing service | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | 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 | diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go index 343a2be45fd..2283212cd5c 100644 --- a/test/cel-validation/envoyextensionpolicy_test.go +++ b/test/cel-validation/envoyextensionpolicy_test.go @@ -11,15 +11,16 @@ package celvalidation import ( "context" "fmt" - "k8s.io/utils/ptr" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" "strings" "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" ) @@ -189,8 +190,8 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { BackendRef: egv1a1.ExtProcBackendRef{ BackendObjectReference: gwapiv1.BackendObjectReference{ Group: ptr.To(gwapiv1.Group("unsupported")), - Name: "grpc-proc-service", - Port: ptr.To(gwapiv1.PortNumber(80)), + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), }, }, }, From da182e85ef2aa7a5d103807a5209570d78288c29 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Fri, 12 Apr 2024 09:30:22 -0500 Subject: [PATCH 7/7] fix gen Signed-off-by: Guy Daich --- site/content/en/latest/api/extension_types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index f47db76e725..d88a7d4fb8a 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1038,12 +1038,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | + | `backendRef` | _[ExtProcBackendRef](#extprocbackendref)_ | true | BackendRef defines the configuration of the external processing service | | `backendRefs` | _[BackendRef](#backendref) array_ | false | 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 | - #### ExtProcBackendRef