From 3ca99a2a63c88926cf90c2510f82d0a4458cedd2 Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Wed, 12 Nov 2025 10:44:31 +0000 Subject: [PATCH 1/5] Add ProxySettingPolicy API and CRDs --- apis/v1alpha1/policy_methods.go | 12 + apis/v1alpha1/proxysettingspolicy_types.go | 82 ++++ apis/v1alpha1/register.go | 2 + apis/v1alpha1/zz_generated.deepcopy.go | 134 ++++++ ...teway.nginx.org_proxysettingspolicies.yaml | 440 ++++++++++++++++++ config/crd/kustomization.yaml | 1 + deploy/crds.yaml | 439 +++++++++++++++++ 7 files changed, 1110 insertions(+) create mode 100644 apis/v1alpha1/proxysettingspolicy_types.go create mode 100644 config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml diff --git a/apis/v1alpha1/policy_methods.go b/apis/v1alpha1/policy_methods.go index 02350ef82b..09b0df12e9 100644 --- a/apis/v1alpha1/policy_methods.go +++ b/apis/v1alpha1/policy_methods.go @@ -20,6 +20,18 @@ func (p *ClientSettingsPolicy) SetPolicyStatus(status gatewayv1.PolicyStatus) { p.Status = status } +func (p *ProxySettingsPolicy) GetTargetRefs() []gatewayv1.LocalPolicyTargetReference { + return p.Spec.TargetRefs +} + +func (p *ProxySettingsPolicy) GetPolicyStatus() gatewayv1.PolicyStatus { + return p.Status +} + +func (p *ProxySettingsPolicy) SetPolicyStatus(status gatewayv1.PolicyStatus) { + p.Status = status +} + func (p *UpstreamSettingsPolicy) GetTargetRefs() []gatewayv1.LocalPolicyTargetReference { return p.Spec.TargetRefs } diff --git a/apis/v1alpha1/proxysettingspolicy_types.go b/apis/v1alpha1/proxysettingspolicy_types.go new file mode 100644 index 0000000000..aa834ab8a1 --- /dev/null +++ b/apis/v1alpha1/proxysettingspolicy_types.go @@ -0,0 +1,82 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:subresource:status +// +kubebuilder:resource:categories=nginx-gateway-fabric,shortName=pspolicy +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` +// +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=inherited" + +// ProxySettingsPolicy is an Inherited Attached Policy. It provides a way to configure the behavior of the connection +// between NGINX Gateway Fabric and the upstream applications (backends). +type ProxySettingsPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the ProxySettingsPolicy. + Spec ProxySettingsPolicySpec `json:"spec"` + + // Status defines the state of the ProxySettingsPolicy. + Status gatewayv1.PolicyStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ProxySettingsPolicyList contains a list of ProxySettingsPolicies. +type ProxySettingsPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ProxySettingsPolicy `json:"items"` +} + +// ProxySettingsPolicySpec defines the desired state of the ProxySettingsPolicy. +type ProxySettingsPolicySpec struct { + Buffering *ProxyBuffering `json:"buffering,omitempty"` + TargetRefs []gatewayv1.LocalPolicyTargetReference `json:"targetRefs"` +} + +// ProxyBuffering contains the settings for proxy buffering. +type ProxyBuffering struct { + // Disable enables or disables buffering of responses from the proxied server. + // If Disable is true, buffering is disabled. If Disable is false, or if Disable is not set, buffering is enabled. + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering + // + // +optional + Disable *bool `json:"disable,omitempty"` + + // BufferSize sets the size of the buffer used for reading the first part of the response received from + // the proxied server. This part usually contains a small response header. + // Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size + // + // +optional + BufferSize *Size `json:"bufferSize,omitempty"` + + // Buffers sets the number and size of buffers used for reading a response from the proxied server, + // for a single connection. + // Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers + // + // +optional + Buffers *ProxyBuffers `json:"buffers,omitempty"` + + // BusyBuffersSize sets the total size of buffers that can be busy sending a response to the client, + // while the response is not yet fully read. + // Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + // + // +optional + BusyBuffersSize *Size `json:"busyBuffersSize,omitempty"` +} + +// ProxyBuffers defines the number and size of the proxy buffers. +type ProxyBuffers struct { + Size Size `json:"size"` + Number int32 `json:"number"` +} diff --git a/apis/v1alpha1/register.go b/apis/v1alpha1/register.go index d01bfcd6e1..f317f54292 100644 --- a/apis/v1alpha1/register.go +++ b/apis/v1alpha1/register.go @@ -36,6 +36,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &NginxGatewayList{}, &ClientSettingsPolicy{}, &ClientSettingsPolicyList{}, + &ProxySettingsPolicy{}, + &ProxySettingsPolicyList{}, &SnippetsFilter{}, &SnippetsFilterList{}, &UpstreamSettingsPolicy{}, diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index d07825de2d..dc929789f5 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -318,6 +318,140 @@ func (in *NginxGatewayStatus) DeepCopy() *NginxGatewayStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProxyBuffering) DeepCopyInto(out *ProxyBuffering) { + *out = *in + if in.Disable != nil { + in, out := &in.Disable, &out.Disable + *out = new(bool) + **out = **in + } + if in.BufferSize != nil { + in, out := &in.BufferSize, &out.BufferSize + *out = new(Size) + **out = **in + } + if in.Buffers != nil { + in, out := &in.Buffers, &out.Buffers + *out = new(ProxyBuffers) + **out = **in + } + if in.BusyBuffersSize != nil { + in, out := &in.BusyBuffersSize, &out.BusyBuffersSize + *out = new(Size) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyBuffering. +func (in *ProxyBuffering) DeepCopy() *ProxyBuffering { + if in == nil { + return nil + } + out := new(ProxyBuffering) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProxyBuffers) DeepCopyInto(out *ProxyBuffers) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyBuffers. +func (in *ProxyBuffers) DeepCopy() *ProxyBuffers { + if in == nil { + return nil + } + out := new(ProxyBuffers) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProxySettingsPolicy) DeepCopyInto(out *ProxySettingsPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxySettingsPolicy. +func (in *ProxySettingsPolicy) DeepCopy() *ProxySettingsPolicy { + if in == nil { + return nil + } + out := new(ProxySettingsPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProxySettingsPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProxySettingsPolicyList) DeepCopyInto(out *ProxySettingsPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ProxySettingsPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxySettingsPolicyList. +func (in *ProxySettingsPolicyList) DeepCopy() *ProxySettingsPolicyList { + if in == nil { + return nil + } + out := new(ProxySettingsPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProxySettingsPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProxySettingsPolicySpec) DeepCopyInto(out *ProxySettingsPolicySpec) { + *out = *in + if in.Buffering != nil { + in, out := &in.Buffering, &out.Buffering + *out = new(ProxyBuffering) + (*in).DeepCopyInto(*out) + } + if in.TargetRefs != nil { + in, out := &in.TargetRefs, &out.TargetRefs + *out = make([]apisv1.LocalPolicyTargetReference, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxySettingsPolicySpec. +func (in *ProxySettingsPolicySpec) DeepCopy() *ProxySettingsPolicySpec { + if in == nil { + return nil + } + out := new(ProxySettingsPolicySpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Snippet) DeepCopyInto(out *Snippet) { *out = *in diff --git a/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml b/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml new file mode 100644 index 0000000000..65d9c60519 --- /dev/null +++ b/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml @@ -0,0 +1,440 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + gateway.networking.k8s.io/policy: inherited + name: proxysettingspolicies.gateway.nginx.org +spec: + group: gateway.nginx.org + names: + categories: + - nginx-gateway-fabric + kind: ProxySettingsPolicy + listKind: ProxySettingsPolicyList + plural: proxysettingspolicies + shortNames: + - pspolicy + singular: proxysettingspolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ProxySettingsPolicy is an Inherited Attached Policy. It provides a way to configure the behavior of the connection + between NGINX Gateway Fabric and the upstream applications (backends). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of the ProxySettingsPolicy. + properties: + buffering: + description: ProxyBuffering contains the settings for proxy buffering. + properties: + bufferSize: + description: |- + BufferSize sets the size of the buffer used for reading the first part of the response received from + the proxied server. This part usually contains a small response header. + Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size + pattern: ^\d{1,4}(k|m|g)?$ + type: string + buffers: + description: |- + Buffers sets the number and size of buffers used for reading a response from the proxied server, + for a single connection. + Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers + properties: + number: + format: int32 + type: integer + size: + description: |- + Size is a string value representing a size. Size can be specified in bytes, kilobytes (k), megabytes (m), + or gigabytes (g). + Examples: 1024, 8k, 1m. + pattern: ^\d{1,4}(k|m|g)?$ + type: string + required: + - number + - size + type: object + busyBuffersSize: + description: |- + BusyBuffersSize sets the total size of buffers that can be busy sending a response to the client, + while the response is not yet fully read. + Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + pattern: ^\d{1,4}(k|m|g)?$ + type: string + disable: + description: |- + Disable enables or disables buffering of responses from the proxied server. + If Disable is true, buffering is disabled. If Disable is false, or if Disable is not set, buffering is enabled. + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering + type: boolean + type: object + targetRefs: + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + type: array + required: + - targetRefs + type: object + status: + description: Status defines the state of the ProxySettingsPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + 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: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + 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. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: |- + Conditions describes the status of the Policy with respect to the given Ancestor. + + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - conditions + - controllerName + type: object + maxItems: 16 + type: array + x-kubernetes-list-type: atomic + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index b067d64141..7fa33d80fa 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -5,5 +5,6 @@ resources: - bases/gateway.nginx.org_nginxgateways.yaml - bases/gateway.nginx.org_nginxproxies.yaml - bases/gateway.nginx.org_observabilitypolicies.yaml + - bases/gateway.nginx.org_proxysettingspolicies.yaml - bases/gateway.nginx.org_snippetsfilters.yaml - bases/gateway.nginx.org_upstreamsettingspolicies.yaml diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 2a526a961f..3faf985287 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -9339,6 +9339,445 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + gateway.networking.k8s.io/policy: inherited + name: proxysettingspolicies.gateway.nginx.org +spec: + group: gateway.nginx.org + names: + categories: + - nginx-gateway-fabric + kind: ProxySettingsPolicy + listKind: ProxySettingsPolicyList + plural: proxysettingspolicies + shortNames: + - pspolicy + singular: proxysettingspolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ProxySettingsPolicy is an Inherited Attached Policy. It provides a way to configure the behavior of the connection + between NGINX Gateway Fabric and the upstream applications (backends). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of the ProxySettingsPolicy. + properties: + buffering: + description: ProxyBuffering contains the settings for proxy buffering. + properties: + bufferSize: + description: |- + BufferSize sets the size of the buffer used for reading the first part of the response received from + the proxied server. This part usually contains a small response header. + Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size + pattern: ^\d{1,4}(k|m|g)?$ + type: string + buffers: + description: |- + Buffers sets the number and size of buffers used for reading a response from the proxied server, + for a single connection. + Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers + properties: + number: + format: int32 + type: integer + size: + description: |- + Size is a string value representing a size. Size can be specified in bytes, kilobytes (k), megabytes (m), + or gigabytes (g). + Examples: 1024, 8k, 1m. + pattern: ^\d{1,4}(k|m|g)?$ + type: string + required: + - number + - size + type: object + busyBuffersSize: + description: |- + BusyBuffersSize sets the total size of buffers that can be busy sending a response to the client, + while the response is not yet fully read. + Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + pattern: ^\d{1,4}(k|m|g)?$ + type: string + disable: + description: |- + Disable enables or disables buffering of responses from the proxied server. + If Disable is true, buffering is disabled. If Disable is false, or if Disable is not set, buffering is enabled. + Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering + type: boolean + type: object + targetRefs: + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + 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 target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + type: array + required: + - targetRefs + type: object + status: + description: Status defines the state of the ProxySettingsPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + 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: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + 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. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - conditions + - controllerName + type: object + maxItems: 16 + type: array + x-kubernetes-list-type: atomic + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.19.0 From 2ea19ecc200c7f920197dbacf592ac7e05a8e66c Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Wed, 12 Nov 2025 20:16:12 +0000 Subject: [PATCH 2/5] Add missing field comments --- apis/v1alpha1/proxysettingspolicy_types.go | 19 +++++++++++++++++-- ...teway.nginx.org_proxysettingspolicies.yaml | 16 +++++++++++----- deploy/crds.yaml | 16 +++++++++++----- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/apis/v1alpha1/proxysettingspolicy_types.go b/apis/v1alpha1/proxysettingspolicy_types.go index aa834ab8a1..926adf15b6 100644 --- a/apis/v1alpha1/proxysettingspolicy_types.go +++ b/apis/v1alpha1/proxysettingspolicy_types.go @@ -37,7 +37,17 @@ type ProxySettingsPolicyList struct { // ProxySettingsPolicySpec defines the desired state of the ProxySettingsPolicy. type ProxySettingsPolicySpec struct { - Buffering *ProxyBuffering `json:"buffering,omitempty"` + // Buffering configures the buffering of responses from the proxied server. + // + // +optional + Buffering *ProxyBuffering `json:"buffering,omitempty"` + + // TargetRefs identifies the API object(s) to apply the policy to. + // Objects must be in the same namespace as the policy. + // Support: Gateway, HTTPRoute, GRPCRoute + // + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=16 TargetRefs []gatewayv1.LocalPolicyTargetReference `json:"targetRefs"` } @@ -77,6 +87,11 @@ type ProxyBuffering struct { // ProxyBuffers defines the number and size of the proxy buffers. type ProxyBuffers struct { - Size Size `json:"size"` + // Size sets the size of each buffer. + Size Size `json:"size"` + + // Number sets the number of buffers. + // + // +kubebuilder:validation:Minimum=2 Number int32 `json:"number"` } diff --git a/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml b/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml index 65d9c60519..479c7d7dfc 100644 --- a/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml +++ b/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml @@ -52,7 +52,8 @@ spec: description: Spec defines the desired state of the ProxySettingsPolicy. properties: buffering: - description: ProxyBuffering contains the settings for proxy buffering. + description: Buffering configures the buffering of responses from + the proxied server. properties: bufferSize: description: |- @@ -70,13 +71,12 @@ spec: Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers properties: number: + description: Number sets the number of buffers. format: int32 + minimum: 2 type: integer size: - description: |- - Size is a string value representing a size. Size can be specified in bytes, kilobytes (k), megabytes (m), - or gigabytes (g). - Examples: 1024, 8k, 1m. + description: Size sets the size of each buffer. pattern: ^\d{1,4}(k|m|g)?$ type: string required: @@ -99,6 +99,10 @@ spec: type: boolean type: object targetRefs: + description: |- + TargetRefs identifies the API object(s) to apply the policy to. + Objects must be in the same namespace as the policy. + Support: Gateway, HTTPRoute, GRPCRoute items: description: |- LocalPolicyTargetReference identifies an API object to apply a direct or @@ -128,6 +132,8 @@ spec: - kind - name type: object + maxItems: 16 + minItems: 1 type: array required: - targetRefs diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 3faf985287..4fe815034e 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -9390,7 +9390,8 @@ spec: description: Spec defines the desired state of the ProxySettingsPolicy. properties: buffering: - description: ProxyBuffering contains the settings for proxy buffering. + description: Buffering configures the buffering of responses from + the proxied server. properties: bufferSize: description: |- @@ -9408,13 +9409,12 @@ spec: Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers properties: number: + description: Number sets the number of buffers. format: int32 + minimum: 2 type: integer size: - description: |- - Size is a string value representing a size. Size can be specified in bytes, kilobytes (k), megabytes (m), - or gigabytes (g). - Examples: 1024, 8k, 1m. + description: Size sets the size of each buffer. pattern: ^\d{1,4}(k|m|g)?$ type: string required: @@ -9437,6 +9437,10 @@ spec: type: boolean type: object targetRefs: + description: |- + TargetRefs identifies the API object(s) to apply the policy to. + Objects must be in the same namespace as the policy. + Support: Gateway, HTTPRoute, GRPCRoute items: description: |- LocalPolicyTargetReference identifies an API object to apply a direct or @@ -9466,6 +9470,8 @@ spec: - kind - name type: object + maxItems: 16 + minItems: 1 type: array required: - targetRefs From b850fcebadd9a6a6f01a8a7f7d20cef2a85bcd7b Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Wed, 12 Nov 2025 20:31:18 +0000 Subject: [PATCH 3/5] Add in CEL validation for TargetRefs --- apis/v1alpha1/proxysettingspolicy_types.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apis/v1alpha1/proxysettingspolicy_types.go b/apis/v1alpha1/proxysettingspolicy_types.go index 926adf15b6..6fccee2c55 100644 --- a/apis/v1alpha1/proxysettingspolicy_types.go +++ b/apis/v1alpha1/proxysettingspolicy_types.go @@ -48,6 +48,10 @@ type ProxySettingsPolicySpec struct { // // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 + // +kubebuilder:validation:XValidation:message="TargetRefs entries must have kind Gateway, HTTPRoute, or GRPCRoute",rule="self.all(t, t.kind == 'Gateway' || t.kind == 'HTTPRoute' || t.kind == 'GRPCRoute')" + // +kubebuilder:validation:XValidation:message="TargetRefs entries must have group gateway.networking.k8s.io",rule="self.all(t, t.group == 'gateway.networking.k8s.io')" + // +kubebuilder:validation:XValidation:message="TargetRefs must be unique",rule="self.all(t1, self.exists_one(t2, t1.group == t2.group && t1.kind == t2.kind && t1.name == t2.name))" + //nolint:lll TargetRefs []gatewayv1.LocalPolicyTargetReference `json:"targetRefs"` } @@ -93,5 +97,6 @@ type ProxyBuffers struct { // Number sets the number of buffers. // // +kubebuilder:validation:Minimum=2 + // +kubebuilder:validation:Maximum=256 Number int32 `json:"number"` } From 8fff74af01c7abdf64ee35998216a1c2b3714345 Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Thu, 13 Nov 2025 08:10:22 +0000 Subject: [PATCH 4/5] Move size type; remove duplicates strings; regen crds --- apis/v1alpha1/clientsettingspolicy_types.go | 7 ------- apis/v1alpha1/proxysettingspolicy_types.go | 3 --- apis/v1alpha1/shared_types.go | 7 +++++++ .../gateway.nginx.org_proxysettingspolicies.yaml | 14 +++++++++++--- deploy/crds.yaml | 14 +++++++++++--- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/apis/v1alpha1/clientsettingspolicy_types.go b/apis/v1alpha1/clientsettingspolicy_types.go index f0b8b2c7be..1d883ca120 100644 --- a/apis/v1alpha1/clientsettingspolicy_types.go +++ b/apis/v1alpha1/clientsettingspolicy_types.go @@ -121,10 +121,3 @@ type ClientKeepAliveTimeout struct { // +optional Header *Duration `json:"header,omitempty"` } - -// Size is a string value representing a size. Size can be specified in bytes, kilobytes (k), megabytes (m), -// or gigabytes (g). -// Examples: 1024, 8k, 1m. -// -// +kubebuilder:validation:Pattern=`^\d{1,4}(k|m|g)?$` -type Size string diff --git a/apis/v1alpha1/proxysettingspolicy_types.go b/apis/v1alpha1/proxysettingspolicy_types.go index 6fccee2c55..be28755a9b 100644 --- a/apis/v1alpha1/proxysettingspolicy_types.go +++ b/apis/v1alpha1/proxysettingspolicy_types.go @@ -66,7 +66,6 @@ type ProxyBuffering struct { // BufferSize sets the size of the buffer used for reading the first part of the response received from // the proxied server. This part usually contains a small response header. - // Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size // // +optional @@ -74,7 +73,6 @@ type ProxyBuffering struct { // Buffers sets the number and size of buffers used for reading a response from the proxied server, // for a single connection. - // Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers // // +optional @@ -82,7 +80,6 @@ type ProxyBuffering struct { // BusyBuffersSize sets the total size of buffers that can be busy sending a response to the client, // while the response is not yet fully read. - // Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size // // +optional diff --git a/apis/v1alpha1/shared_types.go b/apis/v1alpha1/shared_types.go index 7d206c769f..598ec08bc0 100644 --- a/apis/v1alpha1/shared_types.go +++ b/apis/v1alpha1/shared_types.go @@ -26,3 +26,10 @@ type SpanAttribute struct { // +kubebuilder:validation:Pattern=`^([^"$\\]|\\[^$])*$` Value string `json:"value"` } + +// Size is a string value representing a size. Size can be specified in bytes, kilobytes (k), megabytes (m), +// or gigabytes (g). +// Examples: 1024, 8k, 1m. +// +// +kubebuilder:validation:Pattern=`^\d{1,4}(k|m|g)?$` +type Size string diff --git a/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml b/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml index 479c7d7dfc..b527e80cf3 100644 --- a/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml +++ b/config/crd/bases/gateway.nginx.org_proxysettingspolicies.yaml @@ -59,7 +59,6 @@ spec: description: |- BufferSize sets the size of the buffer used for reading the first part of the response received from the proxied server. This part usually contains a small response header. - Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size pattern: ^\d{1,4}(k|m|g)?$ type: string @@ -67,12 +66,12 @@ spec: description: |- Buffers sets the number and size of buffers used for reading a response from the proxied server, for a single connection. - Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers properties: number: description: Number sets the number of buffers. format: int32 + maximum: 256 minimum: 2 type: integer size: @@ -87,7 +86,6 @@ spec: description: |- BusyBuffersSize sets the total size of buffers that can be busy sending a response to the client, while the response is not yet fully read. - Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size pattern: ^\d{1,4}(k|m|g)?$ type: string @@ -135,6 +133,16 @@ spec: maxItems: 16 minItems: 1 type: array + x-kubernetes-validations: + - message: TargetRefs entries must have kind Gateway, HTTPRoute, or + GRPCRoute + rule: self.all(t, t.kind == 'Gateway' || t.kind == 'HTTPRoute' || + t.kind == 'GRPCRoute') + - message: TargetRefs entries must have group gateway.networking.k8s.io + rule: self.all(t, t.group == 'gateway.networking.k8s.io') + - message: TargetRefs must be unique + rule: self.all(t1, self.exists_one(t2, t1.group == t2.group && t1.kind + == t2.kind && t1.name == t2.name)) required: - targetRefs type: object diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 4fe815034e..217c730570 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -9397,7 +9397,6 @@ spec: description: |- BufferSize sets the size of the buffer used for reading the first part of the response received from the proxied server. This part usually contains a small response header. - Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size pattern: ^\d{1,4}(k|m|g)?$ type: string @@ -9405,12 +9404,12 @@ spec: description: |- Buffers sets the number and size of buffers used for reading a response from the proxied server, for a single connection. - Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers properties: number: description: Number sets the number of buffers. format: int32 + maximum: 256 minimum: 2 type: integer size: @@ -9425,7 +9424,6 @@ spec: description: |- BusyBuffersSize sets the total size of buffers that can be busy sending a response to the client, while the response is not yet fully read. - Default: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size pattern: ^\d{1,4}(k|m|g)?$ type: string @@ -9473,6 +9471,16 @@ spec: maxItems: 16 minItems: 1 type: array + x-kubernetes-validations: + - message: TargetRefs entries must have kind Gateway, HTTPRoute, or + GRPCRoute + rule: self.all(t, t.kind == 'Gateway' || t.kind == 'HTTPRoute' || + t.kind == 'GRPCRoute') + - message: TargetRefs entries must have group gateway.networking.k8s.io + rule: self.all(t, t.group == 'gateway.networking.k8s.io') + - message: TargetRefs must be unique + rule: self.all(t1, self.exists_one(t2, t1.group == t2.group && t1.kind + == t2.kind && t1.name == t2.name)) required: - targetRefs type: object From 176aee4af8dc7398ee91fedb44b95e0a2116af55 Mon Sep 17 00:00:00 2001 From: Ciara Stacke <18287516+ciarams87@users.noreply.github.com> Date: Thu, 13 Nov 2025 20:07:07 +0000 Subject: [PATCH 5/5] Update the proposal to reflect the implemented API --- docs/proposals/proxy-settings.md | 166 ++++++++++++++----------------- 1 file changed, 74 insertions(+), 92 deletions(-) diff --git a/docs/proposals/proxy-settings.md b/docs/proposals/proxy-settings.md index 50c1ee353f..177124e0b8 100644 --- a/docs/proposals/proxy-settings.md +++ b/docs/proposals/proxy-settings.md @@ -64,119 +64,101 @@ Below is the Golang API for the `ProxySettingsPolicy` API: package v1alpha1 import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" ) -// ProxySettingsPolicy is an Inherited Attached Policy. It provides a way to configure the behavior of the -// connection between NGINX and the upstream applications. -// // +genclient // +kubebuilder:object:root=true // +kubebuilder:storageversion // +kubebuilder:subresource:status -// +kubebuilder:resource:categories=gateway-api,scope=Namespaced +// +kubebuilder:resource:categories=nginx-gateway-fabric,shortName=pspolicy // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` // +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=inherited" + +// ProxySettingsPolicy is an Inherited Attached Policy. It provides a way to configure the behavior of the connection +// between NGINX Gateway Fabric and the upstream applications (backends). type ProxySettingsPolicy struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` - // Spec defines the desired state of the ProxySettingsPolicy. - Spec ProxySettingsPolicySpec `json:"spec"` + // Spec defines the desired state of the ProxySettingsPolicy. + Spec ProxySettingsPolicySpec `json:"spec"` + + // Status defines the state of the ProxySettingsPolicy. + Status gatewayv1.PolicyStatus `json:"status,omitempty"` +} - // Status defines the state of the ProxySettingsPolicy. - Status gatewayv1.PolicyStatus `json:"status,omitempty"` +// +kubebuilder:object:root=true + +// ProxySettingsPolicyList contains a list of ProxySettingsPolicies. +type ProxySettingsPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ProxySettingsPolicy `json:"items"` } // ProxySettingsPolicySpec defines the desired state of the ProxySettingsPolicy. type ProxySettingsPolicySpec struct { - // TargetRefs identifies API object(s) to apply the policy to. - // Objects must be in the same namespace as the policy. - // - // Support: Gateway, HTTPRoute, GRPCRoute - // - // +kubebuilder:validation:MinItems=1 - // +kubebuilder:validation:MaxItems=16 - // +kubebuilder:validation:XValidation:message="TargetRefs entries must have kind Gateway, HTTPRoute, or GRPCRoute",rule="self.all(t, t.kind == 'Gateway' || t.kind == 'HTTPRoute' || t.kind == 'GRPCRoute')" - // +kubebuilder:validation:XValidation:message="TargetRefs entries must have group gateway.networking.k8s.io",rule="self.all(t, t.group == 'gateway.networking.k8s.io')" - // +kubebuilder:validation:XValidation:message="TargetRefs must be unique",rule="self.all(t1, self.exists_one(t2, t1.group == t2.group && t1.kind == t2.kind && t1.name == t2.name))" - TargetRefs []gatewayv1.LocalPolicyTargetReference `json:"targetRefs"` - - // Buffering defines the proxy buffering settings. - // - // +optional - Buffering *ProxyBuffering `json:"buffering,omitempty"` + // Buffering configures the buffering of responses from the proxied server. + // + // +optional + Buffering *ProxyBuffering `json:"buffering,omitempty"` + + // TargetRefs identifies the API object(s) to apply the policy to. + // Objects must be in the same namespace as the policy. + // Support: Gateway, HTTPRoute, GRPCRoute + // + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=16 + // +kubebuilder:validation:XValidation:message="TargetRefs entries must have kind Gateway, HTTPRoute, or GRPCRoute",rule="self.all(t, t.kind == 'Gateway' || t.kind == 'HTTPRoute' || t.kind == 'GRPCRoute')" + // +kubebuilder:validation:XValidation:message="TargetRefs entries must have group gateway.networking.k8s.io",rule="self.all(t, t.group == 'gateway.networking.k8s.io')" + // +kubebuilder:validation:XValidation:message="TargetRefs must be unique",rule="self.all(t1, self.exists_one(t2, t1.group == t2.group && t1.kind == t2.kind && t1.name == t2.name))" + //nolint:lll + TargetRefs []gatewayv1.LocalPolicyTargetReference `json:"targetRefs"` } -// ProxyBuffering contains settings for proxy buffering. +// ProxyBuffering contains the settings for proxy buffering. type ProxyBuffering struct { - // Disable disables buffering of responses from the proxied server. - // When not disabled, NGINX receives a response from the proxied server as soon as possible, - // saving it into buffers. When disabled, the response is passed to a client synchronously, - // immediately as it is received. - // - // Default: false (buffering is enabled by default in NGINX) - // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering - // - // +optional - Disable *bool `json:"disable,omitempty"` - - // BufferSize sets the size of the buffer used for reading the first part of the response - // received from the proxied server. This part usually contains a small response header. - // - // Default: "4k|8k" (one memory page, platform dependent) - // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size - // - // +optional - BufferSize *Size `json:"bufferSize,omitempty"` - - // Buffers sets the number and size of the buffers used for reading a response from the - // proxied server, for a single connection. - // - // Default: "8 4k|8k" (8 buffers of one memory page, platform dependent) - // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers - // - // +optional - Buffers *ProxyBuffers `json:"buffers,omitempty"` - - // BusyBuffersSize limits the total size of buffers that can be busy sending a response - // to the client while the response is not yet fully read. - // - // Default: "8k|16k" (platform dependent) - // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size - // - // +optional - // +kubebuilder:validation:XValidation:message="BusyBuffersSize must be greater than or equal to BufferSize",rule="!has(self.busyBuffersSize) || !has(self.bufferSize) || self.busyBuffersSize >= self.bufferSize" - BusyBuffersSize *Size `json:"busyBuffersSize,omitempty"` + // Disable enables or disables buffering of responses from the proxied server. + // If Disable is true, buffering is disabled. If Disable is false, or if Disable is not set, buffering is enabled. + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering + // + // +optional + Disable *bool `json:"disable,omitempty"` + + // BufferSize sets the size of the buffer used for reading the first part of the response received from + // the proxied server. This part usually contains a small response header. + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size + // + // +optional + BufferSize *Size `json:"bufferSize,omitempty"` + + // Buffers sets the number and size of buffers used for reading a response from the proxied server, + // for a single connection. + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers + // + // +optional + Buffers *ProxyBuffers `json:"buffers,omitempty"` + + // BusyBuffersSize sets the total size of buffers that can be busy sending a response to the client, + // while the response is not yet fully read. + // Directive: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size + // + // +optional + BusyBuffersSize *Size `json:"busyBuffersSize,omitempty"` } -// ProxyBuffers defines the number and size of buffers. +// ProxyBuffers defines the number and size of the proxy buffers. type ProxyBuffers struct { - // Number sets the number of buffers. - // - // +kubebuilder:validation:Minimum=2 - // +kubebuilder:validation:Maximum=256 - Number int32 `json:"number"` - - // Size sets the size of each buffer. - Size Size `json:"size"` -} - -// Size is a string value representing a size. Size can be specified in bytes, kilobytes (suffix k), -// or megabytes (suffix m). -// Examples: 1024, 8k, 1m. -// -// +kubebuilder:validation:Pattern=`^\d+[kKmM]?$` -type Size string - -// ProxySettingsPolicyList contains a list of ProxySettingsPolicies. -// -// +kubebuilder:object:root=true -type ProxySettingsPolicyList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ProxySettingsPolicy `json:"items"` + // Size sets the size of each buffer. + Size Size `json:"size"` + + // Number sets the number of buffers. + // + // +kubebuilder:validation:Minimum=2 + // +kubebuilder:validation:Maximum=256 + Number int32 `json:"number"` } ```