From 6d5edf7db86976fafbd93c50c05b7880871e7055 Mon Sep 17 00:00:00 2001 From: Leo6Leo <36619969+Leo6Leo@users.noreply.github.com> Date: Wed, 6 May 2026 15:13:24 -0400 Subject: [PATCH 1/2] CONSOLE-5163: Add labels field to Ingress componentRoutes Add a labels field (map[string]string) to ComponentRouteSpec in the Ingress config API. This allows cluster admins to specify labels on component routes that IngressControllers use for route selection and sharding. --- .../AAA_ungated.yaml | 88 +++++++++++++++++++ config/v1/types_ingress.go | 6 ++ ...0_10_config-operator_01_ingresses.crd.yaml | 8 ++ config/v1/zz_generated.deepcopy.go | 11 ++- .../AAA_ungated.yaml | 8 ++ .../v1/zz_generated.swagger_doc_generated.go | 1 + .../generated_openapi/zz_generated.openapi.go | 16 ++++ ...0_10_config-operator_01_ingresses.crd.yaml | 8 ++ 8 files changed, 145 insertions(+), 1 deletion(-) diff --git a/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml b/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml index 3d966de4eb1..ae62ee1ecc2 100644 --- a/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml @@ -54,3 +54,91 @@ tests: spec: domain: apps.example.com appsDomain: custom.example.com + - name: Should be able to create an Ingress with componentRoutes containing labels + initial: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console + namespace: openshift-console + hostname: console.example.com + labels: + ingress: shard-console + expected: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console + namespace: openshift-console + hostname: console.example.com + labels: + ingress: shard-console + - name: Should be able to add labels to componentRoutes on update + initial: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console + namespace: openshift-console + hostname: console.example.com + updated: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console + namespace: openshift-console + hostname: console.example.com + labels: + ingress: shard-console + expected: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console + namespace: openshift-console + hostname: console.example.com + labels: + ingress: shard-console + - name: Should be able to create an Ingress with multiple componentRoutes with labels + initial: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console-2 + namespace: openshift-console + hostname: console.internal.corp.example.com + labels: + ingress: shard-console2 + - name: console-3 + namespace: openshift-console + hostname: console.private.corp.example.com + labels: + ingress: shard-console3 + expected: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console-2 + namespace: openshift-console + hostname: console.internal.corp.example.com + labels: + ingress: shard-console2 + - name: console-3 + namespace: openshift-console + hostname: console.private.corp.example.com + labels: + ingress: shard-console3 diff --git a/config/v1/types_ingress.go b/config/v1/types_ingress.go index 26e0ebf2184..57ea5c0b67d 100644 --- a/config/v1/types_ingress.go +++ b/config/v1/types_ingress.go @@ -245,6 +245,12 @@ type ComponentRouteSpec struct { // the Secret specification for a serving certificate will not be needed. // +optional ServingCertKeyPairSecret SecretNameReference `json:"servingCertKeyPairSecret"` + + // labels defines additional labels to be applied to the route created + // for the component. These labels are used by the IngressController to + // determine which routes it should manage. + // +optional + Labels map[string]string `json:"labels,omitempty"` } // ComponentRouteStatus contains information allowing configuration of a route's hostname and serving certificate. diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml index 603d58d6d8d..3d05083caa9 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml @@ -75,6 +75,14 @@ spec: the route. pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ type: string + labels: + additionalProperties: + type: string + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. + type: object name: description: |- name is the logical name of the route to customize. diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index 1cb3cceaef4..d744a50f093 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -1492,6 +1492,13 @@ func (in *ComponentOverride) DeepCopy() *ComponentOverride { func (in *ComponentRouteSpec) DeepCopyInto(out *ComponentRouteSpec) { *out = *in out.ServingCertKeyPairSecret = in.ServingCertKeyPairSecret + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } @@ -3671,7 +3678,9 @@ func (in *IngressSpec) DeepCopyInto(out *IngressSpec) { if in.ComponentRoutes != nil { in, out := &in.ComponentRoutes, &out.ComponentRoutes *out = make([]ComponentRouteSpec, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.RequiredHSTSPolicies != nil { in, out := &in.RequiredHSTSPolicies, &out.RequiredHSTSPolicies diff --git a/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml b/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml index a613cf562ce..5951dc7a8eb 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml @@ -76,6 +76,14 @@ spec: the route. pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ type: string + labels: + additionalProperties: + type: string + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. + type: object name: description: |- name is the logical name of the route to customize. diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 02900dbab8d..711a239c87e 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -2151,6 +2151,7 @@ var map_ComponentRouteSpec = map[string]string{ "name": "name is the logical name of the route to customize.\n\nThe namespace and name of this componentRoute must match a corresponding entry in the list of status.componentRoutes if the route is to be customized.", "hostname": "hostname is the hostname that should be used by the route.", "servingCertKeyPairSecret": "servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. If the custom hostname uses the default routing suffix of the cluster, the Secret specification for a serving certificate will not be needed.", + "labels": "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage.", } func (ComponentRouteSpec) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 6f65ddbfdf0..a3c4a9c6dd3 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -11870,6 +11870,22 @@ func schema_openshift_api_config_v1_ComponentRouteSpec(ref common.ReferenceCallb Ref: ref("github.com/openshift/api/config/v1.SecretNameReference"), }, }, + "labels": { + SchemaProps: spec.SchemaProps{ + Description: "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, Required: []string{"namespace", "name", "hostname"}, }, diff --git a/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml index 603d58d6d8d..3d05083caa9 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml @@ -75,6 +75,14 @@ spec: the route. pattern: ^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$|^(([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})[\.]){0,}([a-z0-9][-a-z0-9]{0,61}[a-z0-9]|[a-z0-9]{1,63})$ type: string + labels: + additionalProperties: + type: string + description: |- + labels defines additional labels to be applied to the route created + for the component. These labels are used by the IngressController to + determine which routes it should manage. + type: object name: description: |- name is the logical name of the route to customize. From 1fde3f0cf6804dbc897630f37b252622f44dd331 Mon Sep 17 00:00:00 2001 From: Leo6Leo <36619969+Leo6Leo@users.noreply.github.com> Date: Tue, 12 May 2026 16:17:37 -0400 Subject: [PATCH 2/2] CONSOLE-5163: Add labels field to Ingress componentRoutes Add a labels field (map[string]string) to ComponentRouteSpec in the Ingress config API. This allows cluster admins to specify labels on component routes that IngressControllers use for route selection and sharding. The field includes: - +mapType=granular for proper strategic merge patch behavior - CEL validation for Kubernetes label key/value format compliance - MaxProperties=8 to bound the number of labels - Unit tests for valid labels, empty labels, and invalid key/value rejection --- .../AAA_ungated.yaml | 145 +++++++++++++----- config/v1/types_ingress.go | 8 + ...0_10_config-operator_01_ingresses.crd.yaml | 13 ++ .../AAA_ungated.yaml | 13 ++ .../v1/zz_generated.swagger_doc_generated.go | 2 +- .../generated_openapi/zz_generated.openapi.go | 7 +- ...0_10_config-operator_01_ingresses.crd.yaml | 13 ++ 7 files changed, 160 insertions(+), 41 deletions(-) diff --git a/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml b/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml index ae62ee1ecc2..0f5567d5617 100644 --- a/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml @@ -23,38 +23,63 @@ tests: kind: Ingress spec: domain: apps.example.com - onUpdate: - - name: Should not be able to change domain once set + - name: Should be able to create an Ingress with componentRoutes containing labels initial: | apiVersion: config.openshift.io/v1 kind: Ingress spec: domain: apps.example.com - updated: | - apiVersion: config.openshift.io/v1 - kind: Ingress - spec: - domain: test.example.com - expectedError: "domain is immutable once set" - - name: Should be able to update other fields without changing domain - initial: | + componentRoutes: + - name: console + namespace: openshift-console + hostname: console.example.com + labels: + ingress: shard-console + expected: | apiVersion: config.openshift.io/v1 kind: Ingress spec: domain: apps.example.com - updated: | + componentRoutes: + - name: console + namespace: openshift-console + hostname: console.example.com + labels: + ingress: shard-console + - name: Should be able to create an Ingress with multiple componentRoutes with labels + initial: | apiVersion: config.openshift.io/v1 kind: Ingress spec: domain: apps.example.com - appsDomain: custom.example.com + componentRoutes: + - name: console-2 + namespace: openshift-console + hostname: console.internal.corp.example.com + labels: + ingress: shard-console2 + - name: console-3 + namespace: openshift-console + hostname: console.private.corp.example.com + labels: + ingress: shard-console3 expected: | apiVersion: config.openshift.io/v1 kind: Ingress spec: domain: apps.example.com - appsDomain: custom.example.com - - name: Should be able to create an Ingress with componentRoutes containing labels + componentRoutes: + - name: console-2 + namespace: openshift-console + hostname: console.internal.corp.example.com + labels: + ingress: shard-console2 + - name: console-3 + namespace: openshift-console + hostname: console.private.corp.example.com + labels: + ingress: shard-console3 + - name: Should be able to create componentRoutes with empty labels map initial: | apiVersion: config.openshift.io/v1 kind: Ingress @@ -64,8 +89,7 @@ tests: - name: console namespace: openshift-console hostname: console.example.com - labels: - ingress: shard-console + labels: {} expected: | apiVersion: config.openshift.io/v1 kind: Ingress @@ -75,9 +99,7 @@ tests: - name: console namespace: openshift-console hostname: console.example.com - labels: - ingress: shard-console - - name: Should be able to add labels to componentRoutes on update + - name: Should reject componentRoutes with invalid label key initial: | apiVersion: config.openshift.io/v1 kind: Ingress @@ -87,7 +109,11 @@ tests: - name: console namespace: openshift-console hostname: console.example.com - updated: | + labels: + "!!!bad": value + expectedError: "label keys must be valid Kubernetes label keys" + - name: Should reject componentRoutes with invalid label value + initial: | apiVersion: config.openshift.io/v1 kind: Ingress spec: @@ -97,8 +123,10 @@ tests: namespace: openshift-console hostname: console.example.com labels: - ingress: shard-console - expected: | + ingress: "invalid value with spaces!" + expectedError: "label values must be valid Kubernetes label values" + - name: Should reject componentRoutes with more than 8 labels + initial: | apiVersion: config.openshift.io/v1 kind: Ingress spec: @@ -108,37 +136,76 @@ tests: namespace: openshift-console hostname: console.example.com labels: - ingress: shard-console - - name: Should be able to create an Ingress with multiple componentRoutes with labels + label1: value1 + label2: value2 + label3: value3 + label4: value4 + label5: value5 + label6: value6 + label7: value7 + label8: value8 + label9: value9 + expectedError: "Too many properties" + onUpdate: + - name: Should not be able to change domain once set + initial: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + updated: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: test.example.com + expectedError: "domain is immutable once set" + - name: Should be able to update other fields without changing domain + initial: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + updated: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + appsDomain: custom.example.com + expected: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + appsDomain: custom.example.com + - name: Should be able to add labels to componentRoutes on update initial: | apiVersion: config.openshift.io/v1 kind: Ingress spec: domain: apps.example.com componentRoutes: - - name: console-2 + - name: console namespace: openshift-console - hostname: console.internal.corp.example.com - labels: - ingress: shard-console2 - - name: console-3 + hostname: console.example.com + updated: | + apiVersion: config.openshift.io/v1 + kind: Ingress + spec: + domain: apps.example.com + componentRoutes: + - name: console namespace: openshift-console - hostname: console.private.corp.example.com + hostname: console.example.com labels: - ingress: shard-console3 + ingress: shard-console expected: | apiVersion: config.openshift.io/v1 kind: Ingress spec: domain: apps.example.com componentRoutes: - - name: console-2 - namespace: openshift-console - hostname: console.internal.corp.example.com - labels: - ingress: shard-console2 - - name: console-3 + - name: console namespace: openshift-console - hostname: console.private.corp.example.com + hostname: console.example.com labels: - ingress: shard-console3 + ingress: shard-console diff --git a/config/v1/types_ingress.go b/config/v1/types_ingress.go index 57ea5c0b67d..9c6c1e0e3c5 100644 --- a/config/v1/types_ingress.go +++ b/config/v1/types_ingress.go @@ -249,7 +249,15 @@ type ComponentRouteSpec struct { // labels defines additional labels to be applied to the route created // for the component. These labels are used by the IngressController to // determine which routes it should manage. + // Label keys and values must conform to Kubernetes label conventions: + // keys must be 1-63 characters (with optional prefix up to 253 characters), + // and values must be 0-63 characters, consisting of alphanumeric characters, + // '-', '_', or '.', and must start and end with an alphanumeric character. // +optional + // +mapType=granular + // +kubebuilder:validation:MaxProperties=8 + // +kubebuilder:validation:XValidation:rule="self.all(key, key.matches('^([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_.]{0,61}[A-Za-z0-9])?)$'))",message="label keys must be valid Kubernetes label keys" + // +kubebuilder:validation:XValidation:rule="self.all(key, self[key].matches('^(([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9])?$'))",message="label values must be valid Kubernetes label values (at most 63 characters, alphanumeric, '-', '_', or '.', must start and end with alphanumeric)" Labels map[string]string `json:"labels,omitempty"` } diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml index 3d05083caa9..5ea4291fc5b 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml @@ -82,7 +82,20 @@ spec: labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage. + Label keys and values must conform to Kubernetes label conventions: + keys must be 1-63 characters (with optional prefix up to 253 characters), + and values must be 0-63 characters, consisting of alphanumeric characters, + '-', '_', or '.', and must start and end with an alphanumeric character. + maxProperties: 8 type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid Kubernetes label keys + rule: self.all(key, key.matches('^([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_.]{0,61}[A-Za-z0-9])?)$')) + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: self.all(key, self[key].matches('^(([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9])?$')) name: description: |- name is the logical name of the route to customize. diff --git a/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml b/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml index 5951dc7a8eb..1d15590ca11 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml @@ -83,7 +83,20 @@ spec: labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage. + Label keys and values must conform to Kubernetes label conventions: + keys must be 1-63 characters (with optional prefix up to 253 characters), + and values must be 0-63 characters, consisting of alphanumeric characters, + '-', '_', or '.', and must start and end with an alphanumeric character. + maxProperties: 8 type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid Kubernetes label keys + rule: self.all(key, key.matches('^([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_.]{0,61}[A-Za-z0-9])?)$')) + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: self.all(key, self[key].matches('^(([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9])?$')) name: description: |- name is the logical name of the route to customize. diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 711a239c87e..6503cdec5fd 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -2151,7 +2151,7 @@ var map_ComponentRouteSpec = map[string]string{ "name": "name is the logical name of the route to customize.\n\nThe namespace and name of this componentRoute must match a corresponding entry in the list of status.componentRoutes if the route is to be customized.", "hostname": "hostname is the hostname that should be used by the route.", "servingCertKeyPairSecret": "servingCertKeyPairSecret is a reference to a secret of type `kubernetes.io/tls` in the openshift-config namespace. The serving cert/key pair must match and will be used by the operator to fulfill the intent of serving with this name. If the custom hostname uses the default routing suffix of the cluster, the Secret specification for a serving certificate will not be needed.", - "labels": "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage.", + "labels": "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage. Label keys and values must conform to Kubernetes label conventions: keys must be 1-63 characters (with optional prefix up to 253 characters), and values must be 0-63 characters, consisting of alphanumeric characters, '-', '_', or '.', and must start and end with an alphanumeric character.", } func (ComponentRouteSpec) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index a3c4a9c6dd3..0c9bb3b08a5 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -11871,8 +11871,13 @@ func schema_openshift_api_config_v1_ComponentRouteSpec(ref common.ReferenceCallb }, }, "labels": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-map-type": "granular", + }, + }, SchemaProps: spec.SchemaProps{ - Description: "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage.", + Description: "labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage. Label keys and values must conform to Kubernetes label conventions: keys must be 1-63 characters (with optional prefix up to 253 characters), and values must be 0-63 characters, consisting of alphanumeric characters, '-', '_', or '.', and must start and end with an alphanumeric character.", Type: []string{"object"}, AdditionalProperties: &spec.SchemaOrBool{ Allows: true, diff --git a/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml index 3d05083caa9..5ea4291fc5b 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml @@ -82,7 +82,20 @@ spec: labels defines additional labels to be applied to the route created for the component. These labels are used by the IngressController to determine which routes it should manage. + Label keys and values must conform to Kubernetes label conventions: + keys must be 1-63 characters (with optional prefix up to 253 characters), + and values must be 0-63 characters, consisting of alphanumeric characters, + '-', '_', or '.', and must start and end with an alphanumeric character. + maxProperties: 8 type: object + x-kubernetes-map-type: granular + x-kubernetes-validations: + - message: label keys must be valid Kubernetes label keys + rule: self.all(key, key.matches('^([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_.]{0,61}[A-Za-z0-9])?)$')) + - message: label values must be valid Kubernetes label values + (at most 63 characters, alphanumeric, '-', '_', or '.', + must start and end with alphanumeric) + rule: self.all(key, self[key].matches('^(([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9])?$')) name: description: |- name is the logical name of the route to customize.