-
Notifications
You must be signed in to change notification settings - Fork 615
CONSOLE-5163: Add labels field to Ingress componentRoutes #2845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Leo6Leo
wants to merge
15
commits into
openshift:master
Choose a base branch
from
Leo6Leo:CONSOLE-5163
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
6d5edf7
CONSOLE-5163: Add labels field to Ingress componentRoutes
Leo6Leo 1fde3f0
CONSOLE-5163: Add labels field to Ingress componentRoutes
Leo6Leo b5a6dab
Update config/v1/types_ingress.go
Leo6Leo 0935778
Implement @saschagrunert 's review comments
Leo6Leo 2c69bb1
Apply suggestions from code review
Leo6Leo 091391a
Address the second round of review comments
Leo6Leo a58bd90
fix the failing ci
Leo6Leo 2090d43
CONSOLE-5163: Replace CEL regex with type-level validation
Leo6Leo 0e5ff48
Enhance ComponentRouteSpec labels validation documentation
Leo6Leo 97f9faf
make update
Leo6Leo a9dae67
Merge upstream/master into CONSOLE-5163
Leo6Leo 6740a1b
Apply suggestions from code review
Leo6Leo afa3235
fix the review comments and run make update
Leo6Leo ea90be0
Merge remote-tracking branch 'upstream/master' into CONSOLE-5163
Leo6Leo 628b8ca
Update enhancement PR URL for IngressComponentRouteLabels feature gate
Leo6Leo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
351 changes: 351 additions & 0 deletions
351
config/v1/tests/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,351 @@ | ||
| apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this | ||
| name: "Ingress" | ||
| crdName: ingresses.config.openshift.io | ||
| featureGates: | ||
| - IngressComponentRouteLabels | ||
| tests: | ||
| onCreate: | ||
| - 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 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 | ||
| - name: Should be able to create componentRoutes with a DNS-prefixed label key | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| example.com/my-label: value | ||
| expected: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| example.com/my-label: value | ||
| - name: Should be able to create componentRoutes with max-length label value | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| my-label: abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0 | ||
| expected: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| my-label: abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0 | ||
| - name: Should reject componentRoutes with invalid label value | ||
| 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: "invalid value with spaces!" | ||
| expectedError: "Invalid value" | ||
| - name: Should accept componentRoutes with empty string label value | ||
| 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: "" | ||
| 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: "" | ||
| - name: Should accept componentRoutes with non-reserved prefix like openshift.io | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| openshift.io/my-label: value | ||
| expected: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| openshift.io/my-label: value | ||
| - name: Should reject componentRoutes with invalid label key | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| "!!!bad": value | ||
| expectedError: "label keys must be valid qualified names" | ||
| - name: Should reject componentRoutes with reserved kubernetes.io/ label prefix | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| kubernetes.io/name: value | ||
| expectedError: "kubernetes.io/ and k8s.io/ prefixed label keys are reserved" | ||
| - name: Should reject componentRoutes with reserved k8s.io/ label prefix | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| k8s.io/name: value | ||
| expectedError: "kubernetes.io/ and k8s.io/ prefixed label keys are reserved" | ||
| - name: Should reject componentRoutes with label key name over 63 characters | ||
| initial: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| labels: | ||
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: value | ||
| expectedError: "label keys must be valid qualified names" | ||
| - name: Should reject componentRoutes with label value starting with dash | ||
| 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: "-starts-with-dash" | ||
| expectedError: "Invalid value" | ||
| - name: Should reject componentRoutes with more than 8 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: | ||
| label1: value1 | ||
| label2: value2 | ||
| label3: value3 | ||
| label4: value4 | ||
| label5: value5 | ||
| label6: value6 | ||
| label7: value7 | ||
| label8: value8 | ||
| label9: value9 | ||
| expectedError: "must have at most 8 items" | ||
| onUpdate: | ||
| - 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 change an existing label value 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 | ||
| labels: | ||
| ingress: shard-old | ||
| 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-new | ||
| 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-new | ||
| - name: Should be able to remove labels from 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 | ||
| labels: | ||
| ingress: shard-console | ||
| updated: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
| expected: | | ||
| apiVersion: config.openshift.io/v1 | ||
| kind: Ingress | ||
| spec: | ||
| domain: apps.example.com | ||
| componentRoutes: | ||
| - name: console | ||
| namespace: openshift-console | ||
| hostname: console.example.com | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,6 +68,7 @@ type IngressSpec struct { | |
| // +listType=map | ||
| // +listMapKey=namespace | ||
| // +listMapKey=name | ||
| // +kubebuilder:validation:MaxItems=250 | ||
| ComponentRoutes []ComponentRouteSpec `json:"componentRoutes,omitempty"` | ||
|
|
||
| // requiredHSTSPolicies specifies HSTS policies that are required to be set on newly created or updated routes | ||
|
|
@@ -164,6 +165,13 @@ const ( | |
| Classic AWSLBType = "Classic" | ||
| ) | ||
|
|
||
| // LabelValue is the value part of a Kubernetes label. | ||
| // A label value must be 0-63 characters, consisting of alphanumeric characters, | ||
| // '-', '_', or '.', and must start and end with an alphanumeric character. | ||
| // +kubebuilder:validation:MaxLength=63 | ||
| // +kubebuilder:validation:XValidation:rule="!format.labelValue().validate(self).hasValue()",message="label values must be valid Kubernetes label values (at most 63 characters, alphanumeric, '-', '_', or '.', must start and end with alphanumeric)" | ||
| type LabelValue string | ||
|
|
||
| // ConsumingUser is an alias for string which we add validation to. Currently only service accounts are supported. | ||
| // +kubebuilder:validation:Pattern="^system:serviceaccount:[a-z0-9]([-a-z0-9]*[a-z0-9])?:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" | ||
| // +kubebuilder:validation:MinLength=1 | ||
|
|
@@ -245,6 +253,24 @@ 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. Changing labels may cause the | ||
| // route to be reassigned to a different IngressController. | ||
| // When omitted, no additional labels are applied to the component route. | ||
| // Label keys and values must conform to Kubernetes label conventions. | ||
| // Label keys must be valid qualified names per Kubernetes label conventions. | ||
| // Keys with the "kubernetes.io/" and "k8s.io/" prefixes are reserved and may not be used. | ||
| // When specified, labels must contain at least one entry, up to a maximum of 8. | ||
| // +openshift:enable:FeatureGate=IngressComponentRouteLabels | ||
| // +optional | ||
| // +mapType=granular | ||
| // +kubebuilder:validation:MinProperties=1 | ||
| // +kubebuilder:validation:MaxProperties=8 | ||
|
Leo6Leo marked this conversation as resolved.
coderabbitai[bot] marked this conversation as resolved.
|
||
| // +kubebuilder:validation:XValidation:rule="self.all(key, !format.qualifiedName().validate(key).hasValue())",message="label keys must be valid qualified names" | ||
| // +kubebuilder:validation:XValidation:rule="self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/'))",message="kubernetes.io/ and k8s.io/ prefixed label keys are reserved and may not be used" | ||
| Labels map[string]LabelValue `json:"labels,omitempty"` | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no key validation at the CRD level. Users can submit invalid keys (e.g. // +kubebuilder:validation:XValidation:rule="self.all(key, !format.qualifiedName().validate(key).hasValue())",message="label keys must be valid qualified names"
// +kubebuilder:validation:XValidation:rule="self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/'))",message="kubernetes.io/ and k8s.io/ prefixed label keys are reserved and may not be used" |
||
| } | ||
|
|
||
| // ComponentRouteStatus contains information allowing configuration of a route's hostname and serving certificate. | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests cover basic CRUD and some negatives but the CEL validations need more coverage. Please add:
ingress: "") accepted (valid per K8s label spec, non-obvious edge case)format.qualifiedName()enforcement)-starts-with-dash) rejectedopenshift.io/my-label), confirms the reserved check is not overly broadThe MinProperties/MaxProperties boundary tests are basic OpenAPI and do not need separate test cases.