Skip to content

CONSOLE-5163: Add labels field to Ingress componentRoutes#2845

Open
Leo6Leo wants to merge 4 commits into
openshift:masterfrom
Leo6Leo:CONSOLE-5163
Open

CONSOLE-5163: Add labels field to Ingress componentRoutes#2845
Leo6Leo wants to merge 4 commits into
openshift:masterfrom
Leo6Leo:CONSOLE-5163

Conversation

@Leo6Leo
Copy link
Copy Markdown

@Leo6Leo Leo6Leo commented May 15, 2026

Summary

Add a labels field (map[string]string) to ComponentRouteSpec in the Ingress config API (config/v1). This allows cluster admins to specify labels on component routes that IngressControllers use for route selection and sharding.

Motivation

When running multiple IngressControllers (e.g., for internal vs. external traffic), each controller uses route labels/selectors to determine which routes it manages. Currently, componentRoutes entries have no way to specify labels, so component routes (like the console) always land on the default IngressController. This makes it impossible to route console traffic through a specific shard without manual post-creation patching.

Changes

  • Add labels field to ComponentRouteSpec with: - +optional, +mapType=granular for proper strategic merge patch
  • maxProperties=8 upper bound
  • CEL validation enforcing Kubernetes label key/value format
  • Regenerated CRD manifests, OpenAPI, deepcopy, and swagger docs
  • Unit tests covering valid labels, empty map, invalid key/value rejection, maxProperties overflow, and update scenarios

Example

spec:
    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

Leo6Leo added 2 commits May 12, 2026 15:17
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.
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
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 15, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented May 15, 2026

@Leo6Leo: This pull request references CONSOLE-5163 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

Add a labels field (map[string]string) to ComponentRouteSpec in the Ingress config API (config/v1). This allows cluster admins to specify labels on component routes that IngressControllers use for route selection and sharding.

Motivation

When running multiple IngressControllers (e.g., for internal vs. external traffic), each controller uses route labels/selectors to determine which routes it manages. Currently, componentRoutes entries have no way to specify labels, so component routes (like the console) always land on the default IngressController. This makes it impossible to route console traffic through a specific shard without manual post-creation patching.

Changes

  • Add labels field to ComponentRouteSpec with: - +optional, +mapType=granular for proper strategic merge patch
  • maxProperties=8 upper bound
  • CEL validation enforcing Kubernetes label key/value format
  • Regenerated CRD manifests, OpenAPI, deepcopy, and swagger docs
  • Unit tests covering valid labels, empty map, invalid key/value rejection, maxProperties overflow, and update scenarios

Example

spec:
   componentRoutes:
   - name: [console-2](https://redhat.atlassian.net/browse/console-2)
     namespace: openshift-console
     hostname: console.internal.corp.example.com
     labels:
       ingress: shard-console2
   - name: [console-3](https://redhat.atlassian.net/browse/console-3)
     namespace: openshift-console
     hostname: console.private.corp.example.com
     labels:
       ingress: shard-console3

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 15, 2026

Hello @Leo6Leo! Some important instructions when contributing to openshift/api:
API design plays an important part in the user experience of OpenShift and as such API PRs are subject to a high level of scrutiny to ensure they follow our best practices. If you haven't already done so, please review the OpenShift API Conventions and ensure that your proposed changes are compliant. Following these conventions will help expedite the api review process for your PR.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

📝 Walkthrough

Walkthrough

This PR introduces label support for component-managed Routes by adding an optional Labels field to ComponentRouteSpec, guarded by the IngressComponentRouteLabels feature gate. The field accepts 1–8 labels with Kubernetes-qualified keys (excluding reserved kubernetes.io/ and k8s.io/ prefixes) and standard-constrained values. The change includes a feature gate definition with metadata, comprehensive test coverage for creation and update operations validating label handling and constraints, and supporting updates to the CRD manifest annotation and features documentation table.

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Microshift Test Compatibility ⚠️ Warning New tests use Ingress API (config.openshift.io/v1), unavailable on MicroShift, without [apigroup:config.openshift.io] protection tag in generated test suite name. Add [apigroup:config.openshift.io] tag to IngressComponentRouteLabels test suite name, or guard tests with [Skipped:MicroShift] label in test configuration.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: adding a labels field to Ingress componentRoutes.
Description check ✅ Passed The description clearly explains the purpose, motivation, and implementation details of adding the labels field to ComponentRouteSpec.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All 12 test cases in IngressComponentRouteLabels.yaml use stable, deterministic test names with no dynamic content (generated suffixes, timestamps, UUIDs, node/namespace names, or IP addresses).
Test Structure And Quality ✅ Passed Test YAML follows repo patterns. Ginkgo generator provides: single responsibility per test, setup/cleanup, timeouts, assertion messages, repo consistency.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests were added in this PR; only YAML CRD test configuration files were added, which are not subject to the SNO compatibility check.
Topology-Aware Scheduling Compatibility ✅ Passed PR only modifies API types and CRDs (config/v1/types_ingress.go), not deployment manifests or operator/controller code. No scheduling constraints introduced; purely metadata API extension.
Ote Binary Stdout Contract ✅ Passed No fmt.Print/klog/log.SetOutput calls in process-level code. Feature gate initialization uses pure builder pattern methods with no stdout side effects.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PR adds YAML CRD schema validation tests only, not Ginkgo e2e tests. Check for IPv6/disconnected network compatibility does not apply.
No-Weak-Crypto ✅ Passed PR adds labels field to ComponentRouteSpec with validation. No weak crypto, custom implementations, or insecure comparisons found in modified files.
Container-Privileges ✅ Passed PR modifies API schemas and feature gates only. No container security configurations (privileged, hostPID, hostNetwork, hostIPC, SYS_ADMIN, allowPrivilegeEscalation) found.
No-Sensitive-Data-In-Logs ✅ Passed PR adds a Labels field to ComponentRouteSpec with no logging infrastructure, custom serialization, or validation handlers that could expose sensitive data in logs.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

Error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented
The command is terminated due to an error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented


Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label May 15, 2026
@openshift-ci openshift-ci Bot requested review from JoelSpeed and everettraven May 15, 2026 20:14
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 15, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign deads2k for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config/v1/types_ingress.go`:
- Around line 249-260: The comment for the Labels field is missing the behavior
when omitted and doesn't document the MaxProperties=8 kubebuilder constraint;
update the comment for the Labels (the map with +optional, +mapType=granular and
+kubebuilder:validation:MaxProperties=8) to state that the field is optional,
what happens when it is omitted (e.g., no additional labels will be applied to
the created route), and explicitly document the MaxProperties=8 limit (maximum
of 8 user-supplied labels) along with the existing label key/value validation
rules so all kubebuilder markers are reflected in the field documentation.
- Around line 249-261: Add an OpenShift feature-gate annotation above the new
Labels field so the stable API field is gated; specifically, add a
kubebuilder/openShift annotation like
"+openshift:enable:FeatureGate=MyFeatureGate" immediately before the "Labels
map[string]string `json:\"labels,omitempty\"`" declaration in types_ingress.go
(replace MyFeatureGate with the chosen gate name, e.g., IngressLabels) so the
new Labels field is activated only when that feature gate is enabled.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: b6586099-0cdf-4a7c-bbfb-fe467ed6e955

📥 Commits

Reviewing files that changed from the base of the PR and between 73d7ca9 and 1fde3f0.

⛔ Files ignored due to path filters (5)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
📒 Files selected for processing (3)
  • config/v1/tests/ingresses.config.openshift.io/AAA_ungated.yaml
  • config/v1/types_ingress.go
  • payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml

Comment thread config/v1/types_ingress.go
Comment thread config/v1/types_ingress.go
Copy link
Copy Markdown
Member

@saschagrunert saschagrunert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this, the use case for label-based route sharding makes sense. See inline comments for details.

Comment thread config/v1/types_ingress.go Outdated
// '-', '_', or '.', and must start and end with an alphanumeric character.
// +optional
// +mapType=granular
// +kubebuilder:validation:MaxProperties=8
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the rationale for limiting to 8 labels? Please document the reasoning.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The limit of 8 was chosen as a practical upper bound — in typical route sharding scenarios, IngressController selectors only need 1-2 labels, so 8 seemed generous while preventing unbounded growth. That said, there is no strong technical justification for this specific number.

Would you prefer we remove the limit entirely, or do you have a recommended ceiling for map fields like this? Happy to adjust. @saschagrunert

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 is fine. Maps need a bound for CEL cost estimation and to prevent unbounded growth. For route sharding where 1-2 labels is typical, 8 is generous enough. No need to change it.

Comment thread config/v1/types_ingress.go Outdated
Comment on lines +259 to +260
// +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)"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using CEL Kubernetes library functions (format.qualifiedName() for keys, format.labelValue() for values) instead of hand-rolled regexes. They are more maintainable, cover the full Kubernetes label spec (including the 253-char prefix limit the current regex misses), and provide better error messages.

Also consider whether keys with reserved prefixes (kubernetes.io/, k8s.io/) should be rejected, since those are reserved for system use.

// +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"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two issues here:

  1. FeatureGate required. New fields on stable (compatibility-level-1) APIs must be behind a FeatureGate. Add a gate in features/features.go and mark this field with +openshift:enable:FeatureGate=<GateName>.

  2. make lint fails. Add +kubebuilder:validation:MinProperties=1 to prevent semantically meaningless labels: {}.

kind: Ingress
spec:
domain: apps.example.com
- name: Should be able to create an Ingress with componentRoutes containing labels
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the FeatureGate is added, these tests should move to a gate-specific file (e.g., ComponentRouteLabels.yaml) instead of AAA_ungated.yaml.

Also, please add the following test cases:

  • Label key with DNS prefix (e.g., example.com/my-label: value), since the prefix path is the most complex part of the key regex
  • Keys and values at the maximum allowed length (63 characters) to verify boundary behavior
  • Update to remove labels (labels present -> no labels)
  • Update to change an existing label's value

Leo6Leo and others added 2 commits May 27, 2026 14:40
Co-authored-by: Sascha Grunert <sgrunert@redhat.com>
@openshift-ci openshift-ci Bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 27, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
config/v1/tests/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml (1)

7-183: ⚡ Quick win

Add an explicit labels: {} rejection test.

This suite validates most constraints, but it does not lock in the MinProperties=1 behavior for an explicitly empty labels map.

🧪 Suggested test addition
   onCreate:
+    - name: Should reject componentRoutes with empty labels map
+      initial: |
+        apiVersion: config.openshift.io/v1
+        kind: Ingress
+        spec:
+          domain: apps.example.com
+          componentRoutes:
+            - name: console
+              namespace: openshift-console
+              hostname: console.example.com
+              labels: {}
+      expectedError: "Too few properties"

As per coding guidelines, **/tests/**/*.yaml: “Add validation tests for new stable APIs in <group>/<version>/tests/<crd-name>/ directories.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@config/v1/tests/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml`
around lines 7 - 183, Add a new onCreate test case that ensures an explicitly
empty labels map is rejected: add a test named like "Should reject
componentRoutes with empty labels map" under onCreate (alongside the other
componentRoutes label tests) whose initial manifest includes labels: {} for the
componentRoute and which sets expectedError to the validator message for
MinProperties=1 (e.g. "Too few properties" or the project’s standard "Too few
properties" string). Place it near the other negative label tests (e.g. after
the "Should reject componentRoutes with invalid label value") so the suite
asserts that labels: {} is invalid.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config/v1/types_ingress.go`:
- Around line 253-262: Update the field comment for the labels map to document
the kubebuilder validation markers: state that when the labels field is present
it must be a non-empty map (labels: {} is invalid) due to
+kubebuilder:validation:MinProperties=1, and note the maximum of 8 entries
enforced by +kubebuilder:validation:MaxProperties=8; keep the existing guidance
about Kubernetes-reserved prefixes and the FeatureGate
(+openshift:enable:FeatureGate=IngressComponentRouteLabels) and mark the field
as optional.

---

Nitpick comments:
In
`@config/v1/tests/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml`:
- Around line 7-183: Add a new onCreate test case that ensures an explicitly
empty labels map is rejected: add a test named like "Should reject
componentRoutes with empty labels map" under onCreate (alongside the other
componentRoutes label tests) whose initial manifest includes labels: {} for the
componentRoute and which sets expectedError to the validator message for
MinProperties=1 (e.g. "Too few properties" or the project’s standard "Too few
properties" string). Place it near the other negative label tests (e.g. after
the "Should reject componentRoutes with invalid label value") so the suite
asserts that labels: {} is invalid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: cafd3e64-cebb-4ddf-81fb-31f009795a25

📥 Commits

Reviewing files that changed from the base of the PR and between b5a6dab and 0935778.

⛔ Files ignored due to path filters (9)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/zz_generated*
  • config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
📒 Files selected for processing (5)
  • config/v1/tests/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml
  • config/v1/types_ingress.go
  • features.md
  • features/features.go
  • payload-manifests/crds/0000_10_config-operator_01_ingresses.crd.yaml

Comment on lines +253 to +262
// When omitted, no additional labels are applied to the component route.
// Label keys and values must conform to Kubernetes label conventions.
// Keys with the "kubernetes.io/" and "k8s.io/" prefixes are reserved
// for Kubernetes use and may not be specified.
// A maximum of 8 labels may be specified.
// +openshift:enable:FeatureGate=IngressComponentRouteLabels
// +optional
// +mapType=granular
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=8
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Document the non-empty map requirement for labels.

Line 261 enforces MinProperties=1, but the field comment does not state that labels: {} is invalid when the field is set.

✏️ Suggested doc update
  // When omitted, no additional labels are applied to the component route.
+ // When specified, labels must contain at least one key/value pair.
  // Label keys and values must conform to Kubernetes label conventions.

As per coding guidelines, **/types*.go: “All kubebuilder validation markers must be documented in the field's comment.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// When omitted, no additional labels are applied to the component route.
// Label keys and values must conform to Kubernetes label conventions.
// Keys with the "kubernetes.io/" and "k8s.io/" prefixes are reserved
// for Kubernetes use and may not be specified.
// A maximum of 8 labels may be specified.
// +openshift:enable:FeatureGate=IngressComponentRouteLabels
// +optional
// +mapType=granular
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=8
// When omitted, no additional labels are applied to the component route.
// When specified, labels must contain at least one key/value pair.
// Label keys and values must conform to Kubernetes label conventions.
// Keys with the "kubernetes.io/" and "k8s.io/" prefixes are reserved
// for Kubernetes use and may not be specified.
// A maximum of 8 labels may be specified.
// +openshift:enable:FeatureGate=IngressComponentRouteLabels
// +optional
// +mapType=granular
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=8
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/v1/types_ingress.go` around lines 253 - 262, Update the field comment
for the labels map to document the kubebuilder validation markers: state that
when the labels field is present it must be a non-empty map (labels: {} is
invalid) due to +kubebuilder:validation:MinProperties=1, and note the maximum of
8 entries enforced by +kubebuilder:validation:MaxProperties=8; keep the existing
guidance about Kubernetes-reserved prefixes and the FeatureGate
(+openshift:enable:FeatureGate=IngressComponentRouteLabels) and mark the field
as optional.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 27, 2026

@Leo6Leo: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/verify-crd-schema 0935778 link true /test verify-crd-schema
ci/prow/integration 0935778 link true /test integration
ci/prow/verify 0935778 link true /test verify

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Copy link
Copy Markdown
Member

@saschagrunert saschagrunert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates, good progress addressing the earlier feedback. A few remaining items.

Comment thread features/features.go
reportProblemsToJiraComponent("Management Console").
contactPerson("leoli").
productScope(ocpSpecific).
enhancementPR("https://github.com/openshift/enhancements/pull/XXXX").
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Placeholder URL. This needs a real enhancement PR before merge.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just got a "go ahead" from our team's architect, so I will draft a enhancement soon and update the PR link whenever it is available.

// +kubebuilder:validation:MaxProperties=8
// +kubebuilder:validation:XValidation:rule="self.all(key, !format.qualifiedName().validate(key).hasValue())",message="label keys must be valid Kubernetes qualified names"
// +kubebuilder:validation:XValidation:rule="self.all(key, !key.startsWith('kubernetes.io/') && !key.startsWith('k8s.io/'))",message="label keys must not use reserved prefixes kubernetes.io/ or k8s.io/"
// +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)"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use format.labelValue() instead of the hand-rolled regex, consistent with how you use format.qualifiedName() for keys:

Suggested change
// +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)"
// +kubebuilder:validation:XValidation:rule="self.all(key, !format.labelValue().validate(self[key]).hasValue())",message="label values must be valid Kubernetes label values (at most 63 characters, alphanumeric, '-', '_', or '.', must start and end with alphanumeric)"

// Label keys and values must conform to Kubernetes label conventions.
// Keys with the "kubernetes.io/" and "k8s.io/" prefixes are reserved
// for Kubernetes use and may not be specified.
// A maximum of 8 labels may be specified.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The godoc should also document MinProperties=1 (that an empty map is not valid when the field is set). Something like:

Suggested change
// A maximum of 8 labels may be specified.
// When specified, labels must contain at least one entry, up to a maximum of 8.

include.release.openshift.io/ibm-cloud-managed: "true"
include.release.openshift.io/self-managed-high-availability: "true"
release.openshift.io/bootstrap-required: "true"
release.openshift.io/feature-set: Default
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks manually edited. With the FeatureGate splitting the CRD into feature-set variants under zz_generated.crd-manifests/, running make update (which calls hack/update-payload-crds.sh) should produce separate payload-manifest files per feature set (like authentications does). Run the full make update and let the script handle this.

label8: value8
label9: value9
expectedError: "Too many properties"
onUpdate:
Copy link
Copy Markdown
Member

@saschagrunert saschagrunert May 28, 2026

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:

  • Empty string value (ingress: "") accepted (valid per K8s label spec, non-obvious edge case)
  • Key name part over 63 characters rejected (tests format.qualifiedName() enforcement)
  • Value with valid characters in invalid position (e.g., -starts-with-dash) rejected
  • Non-reserved prefix accepted (e.g., openshift.io/my-label), confirms the reserved check is not overly broad

The MinProperties/MaxProperties boundary tests are basic OpenAPI and do not need separate test cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants