From ae1954110764695534440eb6c503ebf25cfcefe7 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Tue, 25 Nov 2025 13:41:44 +0000 Subject: [PATCH 1/3] Generate CRD for AuthenticationFilter --- apis/v1alpha1/authenticationfilter_types.go | 166 +++++++++++++ apis/v1alpha1/zz_generated.deepcopy.go | 173 ++++++++++++++ config/crd/kustomization.yaml | 1 + deploy/crds.yaml | 245 ++++++++++++++++++++ 4 files changed, 585 insertions(+) create mode 100644 apis/v1alpha1/authenticationfilter_types.go diff --git a/apis/v1alpha1/authenticationfilter_types.go b/apis/v1alpha1/authenticationfilter_types.go new file mode 100644 index 0000000000..bc5d4227fc --- /dev/null +++ b/apis/v1alpha1/authenticationfilter_types.go @@ -0,0 +1,166 @@ +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:subresource:status +// +kubebuilder:resource:categories=nginx-gateway-fabric,shortName=authfilter;authenticationfilter +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` + +// AuthenticationFilter configures request authentication and is +// referenced by HTTPRoute or a GRPCRoute. Filters via ExtensionRef. +type AuthenticationFilter struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + + // Spec defines the desired state of the AuthenticationFilter. + Spec AuthenticationFilterSpec `json:"spec"` + + // Status defines the state of the AuthenticationFilter, following the same + // pattern as SnippetsFilter: per-controller conditions with an Accepted condition. + // + // +optional + Status AuthenticationFilterStatus `json:"status"` +} + +// +kubebuilder:object:root=true + +// AuthenticationFilterList contains a list of AuthenticationFilter. +type AuthenticationFilterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []AuthenticationFilter `json:"items"` +} + +// AuthenticationFilterSpec defines the desired configuration. +// For now only Basic is supported. +// +kubebuilder:validation:XValidation:message="for type=Basic, spec.basic must be set",rule="self.type == 'Basic' ? self.basic != null : true" +// +kubebuilder:validation:XValidation:message="when spec.basic is set, type must be 'Basic'",rule="self.basic != null ? self.type == 'Basic' : true" +type AuthenticationFilterSpec struct { + // Type selects the authentication mechanism. + // +kubebuilder:default=Basic + Type AuthType `json:"type"` + + // Basic configures HTTP Basic Authentication. + // Required when Type == Basic. + // + // +optional + Basic *BasicAuth `json:"basic,omitempty"` +} + +// AuthType defines the authentication mechanism. +// +kubebuilder:validation:Enum=Basic +type AuthType string + +const ( + AuthTypeBasic AuthType = "Basic" +) + +// BasicAuth configures HTTP Basic Authentication. +type BasicAuth struct { + // SecretRef allows referencing a Secret in the same namespace + SecretRef LocalObjectReferenceWithKey `json:"secretRef"` + + // Realm used by NGINX `auth_basic` directive. + // https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic + // Also configures "realm="" in WWW-Authenticate header in error page location. + // + // +optional + // +kubebuilder:default="Restricted" + Realm *string `json:"realm,omitempty"` + + // OnFailure customizes the 401 response for failed authentication. + // + // +optional + OnFailure *AuthFailureResponse `json:"onFailure,omitempty"` +} + +type LocalObjectReferenceWithKey struct { + v1.LocalObjectReference `json:",inline"` + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:XValidation:rule="self != ''",message="key must be non-empty" + Key string `json:"key"` +} + +// AuthFailureBodyPolicy controls the failure response body behavior. +// +kubebuilder:validation:Enum=Unauthorized;Forbidden;Empty +type AuthFailureBodyPolicy string + +const ( + AuthFailureBodyPolicyUnauthorized AuthFailureBodyPolicy = "Unauthorized" + AuthFailureBodyPolicyForbidden AuthFailureBodyPolicy = "Forbidden" + AuthFailureBodyPolicyEmpty AuthFailureBodyPolicy = "Empty" +) + +// AuthScheme enumerates supported WWW-Authenticate schemes.Add a comment on lines R320 to R321Add diff commentMarkdown input: edit mode selected.WritePreviewAdd a suggestionHeadingBoldItalicQuoteCodeLinkUnordered listNumbered listTask listMentionReferenceSaved repliesAdd FilesPaste, drop, or click to add filesCancelCommentStart a reviewReturn to code +// +kubebuilder:validation:Enum=Basic;Bearer +type AuthScheme string + +const ( + AuthSchemeBasic AuthScheme = "Basic" + AuthSchemeBearer AuthScheme = "Bearer" +) + +// AuthFailureResponse customizes 401/403 failures. +type AuthFailureResponse struct { + // Allowed: 401, 403. + // Default: 401. + // + // +optional + // +kubebuilder:default=401 + // +kubebuilder:validation:XValidation:message="statusCode must be 401 or 403",rule="self in [401, 403]" + StatusCode *int32 `json:"statusCode,omitempty"` + + // Challenge scheme. If omitted, inferred from filter Type (Basic|Bearer). + // Configures WWW-Authenticate header in error page location. + // + // +optional + // +kubebuilder:default=Basic + Scheme *AuthScheme `json:"scheme,omitempty"` + + // Controls whether a default canned body is sent or an empty body. + // Default: Unauthorized. + // + // +optional + // +kubebuilder:default=Unauthorized + BodyPolicy *AuthFailureBodyPolicy `json:"bodyPolicy,omitempty"` +} + +// AuthenticationFilterStatus defines the state of AuthenticationFilter. +type AuthenticationFilterStatus struct { + // Controllers is a list of Gateway API controllers that processed the AuthenticationFilter + // and the status of the AuthenticationFilter with respect to each controller. + // + // +kubebuilder:validation:MaxItems=16 + Controllers []ControllerStatus `json:"controllers,omitempty"` +} + +// AuthenticationFilterConditionType is a type of condition associated with AuthenticationFilter. +type AuthenticationFilterConditionType string + +// AuthenticationFilterConditionReason is a reason for an AuthenticationFilter condition type. +type AuthenticationFilterConditionReason string + +const ( + // AuthenticationFilterConditionTypeAccepted indicates that the AuthenticationFilter is accepted. + // + // Possible reasons for this condition to be True: + // * Accepted + // + // Possible reasons for this condition to be False: + // * Invalid + AuthenticationFilterConditionTypeAccepted AuthenticationFilterConditionType = "Accepted" + + // AuthenticationFilterConditionReasonAccepted is used with the Accepted condition type when + // the condition is true. + AuthenticationFilterConditionReasonAccepted AuthenticationFilterConditionReason = "Accepted" + + // AuthenticationFilterConditionReasonInvalid is used with the Accepted condition type when + // the filter is invalid. + AuthenticationFilterConditionReasonInvalid AuthenticationFilterConditionReason = "Invalid" +) diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index d07825de2d..6d0390df62 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -10,6 +10,163 @@ import ( apisv1 "sigs.k8s.io/gateway-api/apis/v1" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthFailureResponse) DeepCopyInto(out *AuthFailureResponse) { + *out = *in + if in.StatusCode != nil { + in, out := &in.StatusCode, &out.StatusCode + *out = new(int32) + **out = **in + } + if in.Scheme != nil { + in, out := &in.Scheme, &out.Scheme + *out = new(AuthScheme) + **out = **in + } + if in.BodyPolicy != nil { + in, out := &in.BodyPolicy, &out.BodyPolicy + *out = new(AuthFailureBodyPolicy) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthFailureResponse. +func (in *AuthFailureResponse) DeepCopy() *AuthFailureResponse { + if in == nil { + return nil + } + out := new(AuthFailureResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationFilter) DeepCopyInto(out *AuthenticationFilter) { + *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 AuthenticationFilter. +func (in *AuthenticationFilter) DeepCopy() *AuthenticationFilter { + if in == nil { + return nil + } + out := new(AuthenticationFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthenticationFilter) 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 *AuthenticationFilterList) DeepCopyInto(out *AuthenticationFilterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AuthenticationFilter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationFilterList. +func (in *AuthenticationFilterList) DeepCopy() *AuthenticationFilterList { + if in == nil { + return nil + } + out := new(AuthenticationFilterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthenticationFilterList) 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 *AuthenticationFilterSpec) DeepCopyInto(out *AuthenticationFilterSpec) { + *out = *in + if in.Basic != nil { + in, out := &in.Basic, &out.Basic + *out = new(BasicAuth) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationFilterSpec. +func (in *AuthenticationFilterSpec) DeepCopy() *AuthenticationFilterSpec { + if in == nil { + return nil + } + out := new(AuthenticationFilterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationFilterStatus) DeepCopyInto(out *AuthenticationFilterStatus) { + *out = *in + if in.Controllers != nil { + in, out := &in.Controllers, &out.Controllers + *out = make([]ControllerStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationFilterStatus. +func (in *AuthenticationFilterStatus) DeepCopy() *AuthenticationFilterStatus { + if in == nil { + return nil + } + out := new(AuthenticationFilterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { + *out = *in + out.SecretRef = in.SecretRef + if in.Realm != nil { + in, out := &in.Realm, &out.Realm + *out = new(string) + **out = **in + } + if in.OnFailure != nil { + in, out := &in.OnFailure, &out.OnFailure + *out = new(AuthFailureResponse) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuth. +func (in *BasicAuth) DeepCopy() *BasicAuth { + if in == nil { + return nil + } + out := new(BasicAuth) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClientBody) DeepCopyInto(out *ClientBody) { *out = *in @@ -197,6 +354,22 @@ func (in *ControllerStatus) DeepCopy() *ControllerStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalObjectReferenceWithKey) DeepCopyInto(out *LocalObjectReferenceWithKey) { + *out = *in + out.LocalObjectReference = in.LocalObjectReference +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalObjectReferenceWithKey. +func (in *LocalObjectReferenceWithKey) DeepCopy() *LocalObjectReferenceWithKey { + if in == nil { + return nil + } + out := new(LocalObjectReferenceWithKey) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Logging) DeepCopyInto(out *Logging) { *out = *in diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index b067d64141..f203dec505 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -1,6 +1,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: + - bases/gateway.nginx.org_authenticationfilters.yaml - bases/gateway.nginx.org_clientsettingspolicies.yaml - bases/gateway.nginx.org_nginxgateways.yaml - bases/gateway.nginx.org_nginxproxies.yaml diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 2a526a961f..1513292261 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -1,5 +1,250 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: authenticationfilters.gateway.nginx.org +spec: + group: gateway.nginx.org + names: + categories: + - nginx-gateway-fabric + kind: AuthenticationFilter + listKind: AuthenticationFilterList + plural: authenticationfilters + shortNames: + - authfilter + - authenticationfilter + singular: authenticationfilter + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AuthenticationFilter configures request authentication and is + referenced by HTTPRoute or a GRPCRoute. Filters via ExtensionRef. + 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 AuthenticationFilter. + properties: + basic: + description: |- + Basic configures HTTP Basic Authentication. + Required when Type == Basic. + properties: + onFailure: + description: OnFailure customizes the 401 response for failed + authentication. + properties: + bodyPolicy: + default: Unauthorized + description: |- + Controls whether a default canned body is sent or an empty body. + Default: Unauthorized. + enum: + - Unauthorized + - Forbidden + - Empty + type: string + scheme: + default: Basic + description: |- + Challenge scheme. If omitted, inferred from filter Type (Basic|Bearer). + Configures WWW-Authenticate header in error page location. + enum: + - Basic + - Bearer + type: string + statusCode: + default: 401 + description: |- + Allowed: 401, 403. + Default: 401. + format: int32 + type: integer + x-kubernetes-validations: + - message: statusCode must be 401 or 403 + rule: self in [401, 403] + type: object + realm: + default: Restricted + description: |- + Realm used by NGINX `auth_basic` directive. + https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic + Also configures "realm="" in WWW-Authenticate header in error page location. + type: string + secretRef: + description: SecretRef allows referencing a Secret in the same + namespace + properties: + key: + minLength: 1 + type: string + x-kubernetes-validations: + - message: key must be non-empty + rule: self != '' + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + type: + default: Basic + description: Type selects the authentication mechanism. + enum: + - Basic + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: for type=Basic, spec.basic must be set + rule: 'self.type == ''Basic'' ? self.basic != null : true' + - message: when spec.basic is set, type must be 'Basic' + rule: 'self.basic != null ? self.type == ''Basic'' : true' + status: + description: |- + Status defines the state of the AuthenticationFilter, following the same + pattern as SnippetsFilter: per-controller conditions with an Accepted condition. + properties: + controllers: + description: |- + Controllers is a list of Gateway API controllers that processed the AuthenticationFilter + and the status of the AuthenticationFilter with respect to each controller. + items: + properties: + conditions: + description: Conditions describe the status of the SnippetsFilter. + 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: + - controllerName + type: object + maxItems: 16 + type: array + type: object + required: + - metadata + - 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 c7b7faf335c4a2de53649b7b261b242579336b6c Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Tue, 25 Nov 2025 13:53:11 +0000 Subject: [PATCH 2/3] Generate CRD in config/crd/bases --- ...teway.nginx.org_authenticationfilters.yaml | 245 ++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 config/crd/bases/gateway.nginx.org_authenticationfilters.yaml diff --git a/config/crd/bases/gateway.nginx.org_authenticationfilters.yaml b/config/crd/bases/gateway.nginx.org_authenticationfilters.yaml new file mode 100644 index 0000000000..285ad74a2f --- /dev/null +++ b/config/crd/bases/gateway.nginx.org_authenticationfilters.yaml @@ -0,0 +1,245 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: authenticationfilters.gateway.nginx.org +spec: + group: gateway.nginx.org + names: + categories: + - nginx-gateway-fabric + kind: AuthenticationFilter + listKind: AuthenticationFilterList + plural: authenticationfilters + shortNames: + - authfilter + - authenticationfilter + singular: authenticationfilter + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AuthenticationFilter configures request authentication and is + referenced by HTTPRoute or a GRPCRoute. Filters via ExtensionRef. + 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 AuthenticationFilter. + properties: + basic: + description: |- + Basic configures HTTP Basic Authentication. + Required when Type == Basic. + properties: + onFailure: + description: OnFailure customizes the 401 response for failed + authentication. + properties: + bodyPolicy: + default: Unauthorized + description: |- + Controls whether a default canned body is sent or an empty body. + Default: Unauthorized. + enum: + - Unauthorized + - Forbidden + - Empty + type: string + scheme: + default: Basic + description: |- + Challenge scheme. If omitted, inferred from filter Type (Basic|Bearer). + Configures WWW-Authenticate header in error page location. + enum: + - Basic + - Bearer + type: string + statusCode: + default: 401 + description: |- + Allowed: 401, 403. + Default: 401. + format: int32 + type: integer + x-kubernetes-validations: + - message: statusCode must be 401 or 403 + rule: self in [401, 403] + type: object + realm: + default: Restricted + description: |- + Realm used by NGINX `auth_basic` directive. + https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic + Also configures "realm="" in WWW-Authenticate header in error page location. + type: string + secretRef: + description: SecretRef allows referencing a Secret in the same + namespace + properties: + key: + minLength: 1 + type: string + x-kubernetes-validations: + - message: key must be non-empty + rule: self != '' + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + type: + default: Basic + description: Type selects the authentication mechanism. + enum: + - Basic + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: for type=Basic, spec.basic must be set + rule: 'self.type == ''Basic'' ? self.basic != null : true' + - message: when spec.basic is set, type must be 'Basic' + rule: 'self.basic != null ? self.type == ''Basic'' : true' + status: + description: |- + Status defines the state of the AuthenticationFilter, following the same + pattern as SnippetsFilter: per-controller conditions with an Accepted condition. + properties: + controllers: + description: |- + Controllers is a list of Gateway API controllers that processed the AuthenticationFilter + and the status of the AuthenticationFilter with respect to each controller. + items: + properties: + conditions: + description: Conditions describe the status of the SnippetsFilter. + 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: + - controllerName + type: object + maxItems: 16 + type: array + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} From 5b970bb6853d5b4651f2fac45c400c3c8df58025 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Tue, 25 Nov 2025 14:04:20 +0000 Subject: [PATCH 3/3] Fix lint errors --- apis/v1alpha1/authenticationfilter_types.go | 32 +++++-------------- apis/v1alpha1/zz_generated.deepcopy.go | 2 +- ...teway.nginx.org_authenticationfilters.yaml | 17 ++-------- deploy/crds.yaml | 17 ++-------- 4 files changed, 15 insertions(+), 53 deletions(-) diff --git a/apis/v1alpha1/authenticationfilter_types.go b/apis/v1alpha1/authenticationfilter_types.go index bc5d4227fc..dc38a8f38d 100644 --- a/apis/v1alpha1/authenticationfilter_types.go +++ b/apis/v1alpha1/authenticationfilter_types.go @@ -38,19 +38,13 @@ type AuthenticationFilterList struct { } // AuthenticationFilterSpec defines the desired configuration. -// For now only Basic is supported. // +kubebuilder:validation:XValidation:message="for type=Basic, spec.basic must be set",rule="self.type == 'Basic' ? self.basic != null : true" // +kubebuilder:validation:XValidation:message="when spec.basic is set, type must be 'Basic'",rule="self.basic != null ? self.type == 'Basic' : true" +// +//nolint:lll type AuthenticationFilterSpec struct { - // Type selects the authentication mechanism. - // +kubebuilder:default=Basic - Type AuthType `json:"type"` - - // Basic configures HTTP Basic Authentication. - // Required when Type == Basic. - // - // +optional Basic *BasicAuth `json:"basic,omitempty"` + Type AuthType `json:"type"` } // AuthType defines the authentication mechanism. @@ -63,21 +57,9 @@ const ( // BasicAuth configures HTTP Basic Authentication. type BasicAuth struct { - // SecretRef allows referencing a Secret in the same namespace + Realm *string `json:"realm,omitempty"` + OnFailure *AuthFailureResponse `json:"onFailure,omitempty"` SecretRef LocalObjectReferenceWithKey `json:"secretRef"` - - // Realm used by NGINX `auth_basic` directive. - // https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic - // Also configures "realm="" in WWW-Authenticate header in error page location. - // - // +optional - // +kubebuilder:default="Restricted" - Realm *string `json:"realm,omitempty"` - - // OnFailure customizes the 401 response for failed authentication. - // - // +optional - OnFailure *AuthFailureResponse `json:"onFailure,omitempty"` } type LocalObjectReferenceWithKey struct { @@ -99,6 +81,8 @@ const ( // AuthScheme enumerates supported WWW-Authenticate schemes.Add a comment on lines R320 to R321Add diff commentMarkdown input: edit mode selected.WritePreviewAdd a suggestionHeadingBoldItalicQuoteCodeLinkUnordered listNumbered listTask listMentionReferenceSaved repliesAdd FilesPaste, drop, or click to add filesCancelCommentStart a reviewReturn to code // +kubebuilder:validation:Enum=Basic;Bearer +// +//nolint:lll type AuthScheme string const ( @@ -153,7 +137,7 @@ const ( // * Accepted // // Possible reasons for this condition to be False: - // * Invalid + // * Invalid. AuthenticationFilterConditionTypeAccepted AuthenticationFilterConditionType = "Accepted" // AuthenticationFilterConditionReasonAccepted is used with the Accepted condition type when diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index 6d0390df62..cb0fb721ca 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -144,7 +144,6 @@ func (in *AuthenticationFilterStatus) DeepCopy() *AuthenticationFilterStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { *out = *in - out.SecretRef = in.SecretRef if in.Realm != nil { in, out := &in.Realm, &out.Realm *out = new(string) @@ -155,6 +154,7 @@ func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { *out = new(AuthFailureResponse) (*in).DeepCopyInto(*out) } + out.SecretRef = in.SecretRef } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuth. diff --git a/config/crd/bases/gateway.nginx.org_authenticationfilters.yaml b/config/crd/bases/gateway.nginx.org_authenticationfilters.yaml index 285ad74a2f..42beb13478 100644 --- a/config/crd/bases/gateway.nginx.org_authenticationfilters.yaml +++ b/config/crd/bases/gateway.nginx.org_authenticationfilters.yaml @@ -51,13 +51,10 @@ spec: description: Spec defines the desired state of the AuthenticationFilter. properties: basic: - description: |- - Basic configures HTTP Basic Authentication. - Required when Type == Basic. + description: BasicAuth configures HTTP Basic Authentication. properties: onFailure: - description: OnFailure customizes the 401 response for failed - authentication. + description: AuthFailureResponse customizes 401/403 failures. properties: bodyPolicy: default: Unauthorized @@ -90,15 +87,8 @@ spec: rule: self in [401, 403] type: object realm: - default: Restricted - description: |- - Realm used by NGINX `auth_basic` directive. - https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic - Also configures "realm="" in WWW-Authenticate header in error page location. type: string secretRef: - description: SecretRef allows referencing a Secret in the same - namespace properties: key: minLength: 1 @@ -123,8 +113,7 @@ spec: - secretRef type: object type: - default: Basic - description: Type selects the authentication mechanism. + description: AuthType defines the authentication mechanism. enum: - Basic type: string diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 1513292261..d91c63b285 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -50,13 +50,10 @@ spec: description: Spec defines the desired state of the AuthenticationFilter. properties: basic: - description: |- - Basic configures HTTP Basic Authentication. - Required when Type == Basic. + description: BasicAuth configures HTTP Basic Authentication. properties: onFailure: - description: OnFailure customizes the 401 response for failed - authentication. + description: AuthFailureResponse customizes 401/403 failures. properties: bodyPolicy: default: Unauthorized @@ -89,15 +86,8 @@ spec: rule: self in [401, 403] type: object realm: - default: Restricted - description: |- - Realm used by NGINX `auth_basic` directive. - https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic - Also configures "realm="" in WWW-Authenticate header in error page location. type: string secretRef: - description: SecretRef allows referencing a Secret in the same - namespace properties: key: minLength: 1 @@ -122,8 +112,7 @@ spec: - secretRef type: object type: - default: Basic - description: Type selects the authentication mechanism. + description: AuthType defines the authentication mechanism. enum: - Basic type: string