Skip to content

Commit a8a5157

Browse files
Merge pull request #2308 from grzpiotrowski/OCPBUGS-55192-ic-spec-domain-validation
OCPBUGS-55192: Add IngressController .spec.domain validation
2 parents 5050707 + 63691f4 commit a8a5157

File tree

7 files changed

+219
-3
lines changed

7 files changed

+219
-3
lines changed

openapi/generated_openapi/zz_generated.openapi.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

openapi/openapi.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30464,7 +30464,7 @@
3046430464
"$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference"
3046530465
},
3046630466
"domain": {
30467-
"description": "domain is a DNS name serviced by the ingress controller and is used to configure multiple features:\n\n* For the LoadBalancerService endpoint publishing strategy, domain is\n used to configure DNS records. See endpointPublishingStrategy.\n\n* When using a generated default certificate, the certificate will be valid\n for domain and its subdomains. See defaultCertificate.\n\n* The value is published to individual Route statuses so that end-users\n know where to target external DNS records.\n\ndomain must be unique among all IngressControllers, and cannot be updated.\n\nIf empty, defaults to ingress.config.openshift.io/cluster .spec.domain.",
30467+
"description": "domain is a DNS name serviced by the ingress controller and is used to configure multiple features:\n\n* For the LoadBalancerService endpoint publishing strategy, domain is\n used to configure DNS records. See endpointPublishingStrategy.\n\n* When using a generated default certificate, the certificate will be valid\n for domain and its subdomains. See defaultCertificate.\n\n* The value is published to individual Route statuses so that end-users\n know where to target external DNS records.\n\ndomain must be unique among all IngressControllers, and cannot be updated.\n\nIf empty, defaults to ingress.config.openshift.io/cluster .spec.domain.\n\nThe domain value must be a valid DNS name. It must consist of lowercase alphanumeric characters, '-' or '.', and each label must start and end with an alphanumeric character and not exceed 63 characters. Maximum length of a valid DNS domain is 253 characters.\n\nThe implementation may add a prefix such as \"router-default.\" to the domain when constructing the router canonical hostname. To ensure the resulting hostname does not exceed the DNS maximum length of 253 characters, the domain length is additionally validated at the IngressController object level. For the maximum length of the domain value itself, the shortest possible variant of the prefix and the ingress controller name was considered for example \"router-a.\"",
3046830468
"type": "string"
3046930469
},
3047030470
"endpointPublishingStrategy": {

operator/v1/tests/ingresscontrollers.operator.openshift.io/AAA_ungated.yaml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,3 +563,152 @@ tests:
563563
tuningOptions:
564564
connectTimeout: "4 s"
565565
expectedError: "IngressController.operator.openshift.io \"default\" is invalid: spec.tuningOptions.connectTimeout: Invalid value: \"4 s\": spec.tuningOptions.connectTimeout in body should match '^(0|([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+)$'"
566+
- name: Should be able to create an IngressController with valid domain
567+
initial: |
568+
apiVersion: operator.openshift.io/v1
569+
kind: IngressController
570+
metadata:
571+
name: ic-spec-domain-test
572+
namespace: openshift-ingress-operator
573+
spec:
574+
domain: "this-label-has-exactly-63-characters-validating-at-the-boundary.com"
575+
expected: |
576+
apiVersion: operator.openshift.io/v1
577+
kind: IngressController
578+
metadata:
579+
name: ic-spec-domain-test
580+
namespace: openshift-ingress-operator
581+
spec:
582+
httpEmptyRequestsPolicy: Respond
583+
idleConnectionTerminationPolicy: Immediate
584+
domain: "this-label-has-exactly-63-characters-validating-at-the-boundary.com"
585+
- name: Should not be able to create an IngressController with invalid domain
586+
initial: |
587+
apiVersion: operator.openshift.io/v1
588+
kind: IngressController
589+
metadata:
590+
name: ic-spec-domain-test
591+
namespace: openshift-ingress-operator
592+
spec:
593+
domain: "*.foo.com"
594+
expectedError: "domain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
595+
- name: Should not be able to create an IngressController with domain label exceeding 63 characters
596+
initial: |
597+
apiVersion: operator.openshift.io/v1
598+
kind: IngressController
599+
metadata:
600+
name: ic-spec-domain-test
601+
namespace: openshift-ingress-operator
602+
spec:
603+
domain: "foo.this-label-exceeds-63-characters-for-the-purpose-of-testing-the-domain-validation.com"
604+
expectedError: "each DNS label must not exceed 63 characters"
605+
- name: Should not be able to create an IngressController with the domain exceeding 244 characters
606+
initial: |
607+
apiVersion: operator.openshift.io/v1
608+
kind: IngressController
609+
metadata:
610+
name: a
611+
namespace: openshift-ingress-operator
612+
spec:
613+
domain: "this-domain.has-exactly-245-characters.for-the-purpose-of-testing.the-spec-domain-field-length-validation.it-exceeds-the-limit-set-on-the-spec-domain-field.by-one-character-to-test-the-error.message-from-this-validation.otherwise-it-is-valid.com"
614+
expectedError: "Too long: may not be more than 244 bytes"
615+
- name: Should not be able to create an IngressController with the combined canonical domain exceeding 253 characters
616+
initial: |
617+
apiVersion: operator.openshift.io/v1
618+
kind: IngressController
619+
metadata:
620+
name: ic-name-containing-exactly-40-characters
621+
namespace: openshift-ingress-operator
622+
spec:
623+
domain: "this-domain.has-208-characters.which-on.its-own-would-not-exceed.the-limit-of-253-chars.but-combined-with-the-ingress-controller-name.with-40-chars.and-the-router-prefix.ends-up-as-a-too-long.canonical-domain"
624+
expectedError: "The combined 'router-' + metadata.name + '.' + .spec.domain cannot exceed 253 characters"
625+
onUpdate:
626+
- name: Should be able to update invalid domain to a valid domain
627+
initialCRDPatches:
628+
- op: remove
629+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/domain/x-kubernetes-validations
630+
- op: remove
631+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/domain/maxLength
632+
initial: |
633+
apiVersion: operator.openshift.io/v1
634+
kind: IngressController
635+
metadata:
636+
name: ic-spec-domain-test
637+
namespace: openshift-ingress-operator
638+
spec:
639+
domain: "*.foo.com"
640+
updated: |
641+
apiVersion: operator.openshift.io/v1
642+
kind: IngressController
643+
metadata:
644+
name: ic-spec-domain-test
645+
namespace: openshift-ingress-operator
646+
spec:
647+
domain: "123-foo.com"
648+
expected: |
649+
apiVersion: operator.openshift.io/v1
650+
kind: IngressController
651+
metadata:
652+
name: ic-spec-domain-test
653+
namespace: openshift-ingress-operator
654+
spec:
655+
httpEmptyRequestsPolicy: Respond
656+
idleConnectionTerminationPolicy: Immediate
657+
domain: "123-foo.com"
658+
- name: Should not be able to update already invalid domain to another invalid domain
659+
initialCRDPatches:
660+
- op: remove
661+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/domain/x-kubernetes-validations
662+
- op: remove
663+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/domain/maxLength
664+
initial: |
665+
apiVersion: operator.openshift.io/v1
666+
kind: IngressController
667+
metadata:
668+
name: ic-spec-domain-test
669+
namespace: openshift-ingress-operator
670+
spec:
671+
domain: "*.foo.com"
672+
updated: |
673+
apiVersion: operator.openshift.io/v1
674+
kind: IngressController
675+
metadata:
676+
name: ic-spec-domain-test
677+
namespace: openshift-ingress-operator
678+
spec:
679+
domain: "foo.*.com"
680+
expectedError: "domain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
681+
- name: Should be able to update other fields while retaining invalid domain due to ratcheting
682+
initialCRDPatches:
683+
- op: remove
684+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/domain/x-kubernetes-validations
685+
- op: remove
686+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/domain/maxLength
687+
initial: |
688+
apiVersion: operator.openshift.io/v1
689+
kind: IngressController
690+
metadata:
691+
name: ic-spec-domain-test
692+
namespace: openshift-ingress-operator
693+
spec:
694+
domain: "*.foo.com"
695+
updated: |
696+
apiVersion: operator.openshift.io/v1
697+
kind: IngressController
698+
metadata:
699+
name: ic-spec-domain-test
700+
namespace: openshift-ingress-operator
701+
spec:
702+
domain: "*.foo.com"
703+
replicas: 3
704+
expected: |
705+
apiVersion: operator.openshift.io/v1
706+
kind: IngressController
707+
metadata:
708+
name: ic-spec-domain-test
709+
namespace: openshift-ingress-operator
710+
spec:
711+
httpEmptyRequestsPolicy: Respond
712+
idleConnectionTerminationPolicy: Immediate
713+
domain: "*.foo.com"
714+
replicas: 3

operator/v1/types_ingress.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
//
3636
// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).
3737
// +openshift:compatibility-gen:level=1
38+
// +kubebuilder:validation:XValidation:rule="!has(self.spec.domain) || size('router-' + self.metadata.name + '.' + self.spec.domain) <= 253",message="The combined 'router-' + metadata.name + '.' + .spec.domain cannot exceed 253 characters"
3839
type IngressController struct {
3940
metav1.TypeMeta `json:",inline"`
4041

@@ -68,6 +69,22 @@ type IngressControllerSpec struct {
6869
//
6970
// If empty, defaults to ingress.config.openshift.io/cluster .spec.domain.
7071
//
72+
// The domain value must be a valid DNS name. It must consist of lowercase
73+
// alphanumeric characters, '-' or '.', and each label must start and end
74+
// with an alphanumeric character and not exceed 63 characters. Maximum
75+
// length of a valid DNS domain is 253 characters.
76+
//
77+
// The implementation may add a prefix such as "router-default." to the domain
78+
// when constructing the router canonical hostname. To ensure the resulting
79+
// hostname does not exceed the DNS maximum length of 253 characters,
80+
// the domain length is additionally validated at the IngressController object
81+
// level. For the maximum length of the domain value itself, the shortest
82+
// possible variant of the prefix and the ingress controller name was considered
83+
// for example "router-a."
84+
//
85+
// +kubebuilder:validation:MaxLength=244
86+
// +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="domain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
87+
// +kubebuilder:validation:XValidation:rule="self.split('.').all(label, size(label) <= 63)",message="each DNS label must not exceed 63 characters"
7188
// +optional
7289
Domain string `json:"domain,omitempty"`
7390

operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers.crd.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,27 @@ spec:
164164
updated.
165165
166166
If empty, defaults to ingress.config.openshift.io/cluster .spec.domain.
167+
168+
The domain value must be a valid DNS name. It must consist of lowercase
169+
alphanumeric characters, '-' or '.', and each label must start and end
170+
with an alphanumeric character and not exceed 63 characters. Maximum
171+
length of a valid DNS domain is 253 characters.
172+
173+
The implementation may add a prefix such as "router-default." to the domain
174+
when constructing the router canonical hostname. To ensure the resulting
175+
hostname does not exceed the DNS maximum length of 253 characters,
176+
the domain length is additionally validated at the IngressController object
177+
level. For the maximum length of the domain value itself, the shortest
178+
possible variant of the prefix and the ingress controller name was considered
179+
for example "router-a."
180+
maxLength: 244
167181
type: string
182+
x-kubernetes-validations:
183+
- message: domain must consist of lower case alphanumeric characters,
184+
'-' or '.', and must start and end with an alphanumeric character
185+
rule: '!format.dns1123Subdomain().validate(self).hasValue()'
186+
- message: each DNS label must not exceed 63 characters
187+
rule: self.split('.').all(label, size(label) <= 63)
168188
endpointPublishingStrategy:
169189
description: |-
170190
endpointPublishingStrategy is used to publish the ingress controller
@@ -3234,6 +3254,11 @@ spec:
32343254
type: object
32353255
type: object
32363256
type: object
3257+
x-kubernetes-validations:
3258+
- message: The combined 'router-' + metadata.name + '.' + .spec.domain cannot
3259+
exceed 253 characters
3260+
rule: '!has(self.spec.domain) || size(''router-'' + self.metadata.name +
3261+
''.'' + self.spec.domain) <= 253'
32373262
served: true
32383263
storage: true
32393264
subresources:

operator/v1/zz_generated.featuregated-crd-manifests/ingresscontrollers.operator.openshift.io/AAA_ungated.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,27 @@ spec:
165165
updated.
166166
167167
If empty, defaults to ingress.config.openshift.io/cluster .spec.domain.
168+
169+
The domain value must be a valid DNS name. It must consist of lowercase
170+
alphanumeric characters, '-' or '.', and each label must start and end
171+
with an alphanumeric character and not exceed 63 characters. Maximum
172+
length of a valid DNS domain is 253 characters.
173+
174+
The implementation may add a prefix such as "router-default." to the domain
175+
when constructing the router canonical hostname. To ensure the resulting
176+
hostname does not exceed the DNS maximum length of 253 characters,
177+
the domain length is additionally validated at the IngressController object
178+
level. For the maximum length of the domain value itself, the shortest
179+
possible variant of the prefix and the ingress controller name was considered
180+
for example "router-a."
181+
maxLength: 244
168182
type: string
183+
x-kubernetes-validations:
184+
- message: domain must consist of lower case alphanumeric characters,
185+
'-' or '.', and must start and end with an alphanumeric character
186+
rule: '!format.dns1123Subdomain().validate(self).hasValue()'
187+
- message: each DNS label must not exceed 63 characters
188+
rule: self.split('.').all(label, size(label) <= 63)
169189
endpointPublishingStrategy:
170190
description: |-
171191
endpointPublishingStrategy is used to publish the ingress controller
@@ -3217,6 +3237,11 @@ spec:
32173237
type: object
32183238
type: object
32193239
type: object
3240+
x-kubernetes-validations:
3241+
- message: The combined 'router-' + metadata.name + '.' + .spec.domain cannot
3242+
exceed 253 characters
3243+
rule: '!has(self.spec.domain) || size(''router-'' + self.metadata.name +
3244+
''.'' + self.spec.domain) <= 253'
32203245
served: true
32213246
storage: true
32223247
subresources:

0 commit comments

Comments
 (0)