diff --git a/apis/v1alpha1/nginxproxy_types.go b/apis/v1alpha1/nginxproxy_types.go index fac34f0504..431adeeab5 100644 --- a/apis/v1alpha1/nginxproxy_types.go +++ b/apis/v1alpha1/nginxproxy_types.go @@ -155,7 +155,8 @@ type RewriteClientIP struct { // Sets NGINX directive set_real_ip_from: https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from // This field is required if mode is set. // +kubebuilder:validation:MaxItems=16 - // +listType=atomic + // +listType=map + // +listMapKey=type // // // +optional @@ -200,6 +201,6 @@ type AddressType string const ( // AddressTypeCIDR specifies that the address is a CIDR block. - // kubebuilder:validation:Pattern=`(\/([0-9]?[0-9]?[0-8]))$` + // kubebuilder:validation:Pattern=`^[\.a-zA-Z0-9::]*(\/([0-9]?[0-9]?[0-8]))$` AddressTypeCIDR AddressType = "cidr" ) diff --git a/config/crd/bases/gateway.nginx.org_nginxproxies.yaml b/config/crd/bases/gateway.nginx.org_nginxproxies.yaml index e1644b852d..19ed93c64b 100644 --- a/config/crd/bases/gateway.nginx.org_nginxproxies.yaml +++ b/config/crd/bases/gateway.nginx.org_nginxproxies.yaml @@ -118,7 +118,9 @@ spec: type: object maxItems: 16 type: array - x-kubernetes-list-type: atomic + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map type: object x-kubernetes-validations: - message: if mode is set, trustedAddresses is a required field diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 2b0ea4f133..ef8ffea772 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -703,7 +703,9 @@ spec: type: object maxItems: 16 type: array - x-kubernetes-list-type: atomic + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map type: object x-kubernetes-validations: - message: if mode is set, trustedAddresses is a required field diff --git a/internal/mode/static/state/graph/nginxproxy.go b/internal/mode/static/state/graph/nginxproxy.go index 67d156791a..2c1cd3ffb9 100644 --- a/internal/mode/static/state/graph/nginxproxy.go +++ b/internal/mode/static/state/graph/nginxproxy.go @@ -172,12 +172,23 @@ func validateRewriteClientIP(npCfg *ngfAPI.NginxProxy) field.ErrorList { } for _, addr := range rewriteClientIP.TrustedAddresses { - if err := k8svalidation.IsValidCIDR(trustedAddressesPath, addr.Value); err != nil { + switch addr.Type { + case ngfAPI.AddressTypeCIDR: + if err := k8svalidation.IsValidCIDR(trustedAddressesPath, addr.Value); err != nil { + allErrs = append( + allErrs, + field.Invalid(trustedAddressesPath.Child(addr.Value), + addr, + err.ToAggregate().Error(), + ), + ) + } + default: allErrs = append( allErrs, - field.Invalid(trustedAddressesPath.Child(addr.Value), - addr, - err.ToAggregate().Error(), + field.NotSupported(trustedAddressesPath.Child(addr.Value), + addr.Type, + []string{string(ngfAPI.AddressTypeCIDR)}, ), ) } diff --git a/internal/mode/static/state/graph/nginxproxy_test.go b/internal/mode/static/state/graph/nginxproxy_test.go index e5ecab47b8..8603598f5c 100644 --- a/internal/mode/static/state/graph/nginxproxy_test.go +++ b/internal/mode/static/state/graph/nginxproxy_test.go @@ -517,6 +517,27 @@ func TestValidateRewriteClientIP(t *testing.T) { "required when mode is set, spec.rewriteClientIP.mode: " + "Unsupported value: \"invalid\": supported values: \"ProxyProtocol\", \"XForwardedFor\"]", }, + { + name: "invalid address type in trustedAddresses", + validator: createInvalidValidator(), + np: &ngfAPI.NginxProxy{ + Spec: ngfAPI.NginxProxySpec{ + RewriteClientIP: &ngfAPI.RewriteClientIP{ + SetIPRecursively: helpers.GetPointer(true), + TrustedAddresses: []ngfAPI.Address{ + { + Type: ngfAPI.AddressType("invalid"), + Value: "2001:db8::/129", + }, + }, + Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeProxyProtocol), + }, + }, + }, + expectErrCount: 1, + errorString: "spec.rewriteClientIP.trustedAddresses.2001:db8::/129: " + + "Unsupported value: \"invalid\": supported values: \"cidr\"", + }, } for _, test := range tests { diff --git a/site/content/reference/api.md b/site/content/reference/api.md index b7e49011af..702e758b2e 100644 --- a/site/content/reference/api.md +++ b/site/content/reference/api.md @@ -533,7 +533,7 @@ string

"cidr"

AddressTypeCIDR specifies that the address is a CIDR block. -kubebuilder:validation:Pattern=(\/([0-9]?[0-9]?[0-8]))$

+kubebuilder:validation:Pattern=^[\.a-zA-Z0-9::]*(\/([0-9]?[0-9]?[0-8]))$