Skip to content

Use regex instead of format help for KMS secret name validation - #2966

Open
JoelSpeed wants to merge 2 commits into
openshift:masterfrom
JoelSpeed:fix-kms-secret-name-cel
Open

Use regex instead of format help for KMS secret name validation#2966
JoelSpeed wants to merge 2 commits into
openshift:masterfrom
JoelSpeed:fix-kms-secret-name-cel

Conversation

@JoelSpeed

Copy link
Copy Markdown
Contributor

The current validation using the format library is breaking HyperShift integration testing, this will be functionally equivalent but not rely on the library which came later

CC @ardaguclu

@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

openshift-ci Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Hello @JoelSpeed! 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.

@openshift-ci openshift-ci Bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jul 31, 2026
@qodo-for-rh-openshift

Copy link
Copy Markdown

PR Summary by Qodo

Replace CEL format-based DNS1123 validation with regex for KMS/Vault refs

🐞 Bug fix ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Replace CEL format.dns1123Subdomain() validation with portable regex matching.
• Fix HyperShift integration failures caused by unavailable CEL format library.
• Regenerate CRD manifests so published schemas match the new validation rule.
Diagram

graph TD
  A["KMSEncryption API types"] --> B["Kubebuilder XValidation"] --> C["Generated CRDs (config)"] --> D["Payload CRDs"] --> E["API server CEL"] --> F["Resource admission"]
  subgraph Legend
    direction LR
    _code["Source code"] ~~~ _cfg["Manifest"] ~~~ _svc(["Runtime validation"])
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Require CEL format library availability
  • ➕ Keeps intent aligned with higher-level DNS1123 helper
  • ➕ Avoids maintaining a custom regex
  • ➖ Breaks older API servers/HyperShift environments lacking the format library
  • ➖ Couples validation to specific CEL feature availability
2. Use OpenAPI `pattern` instead of XValidation
  • ➕ Shifts validation to widely supported OpenAPI schema keywords
  • ➕ Avoids CEL feature/version dependencies
  • ➖ May not express identical constraints depending on tooling/CRD generation path
  • ➖ Requires reworking existing XValidation usage and regeneration expectations

Recommendation: Keep the regex-based self.matches(...) XValidation. It avoids dependency on newer CEL format helpers (the reported breakage) while preserving equivalent DNS1123 subdomain constraints, and it cleanly propagates through regenerated CRDs.

Files changed (8) +24 / -24

Bug fix (1) +3 / -3
types_kmsencryption.goSwap DNS1123 CEL format validation to regex for Vault reference fields +3/-3

Swap DNS1123 CEL format validation to regex for Vault reference fields

• Replaces 'format.dns1123Subdomain().validate(self)' XValidation rules with a portable 'self.matches(...)' regex for Vault secret name, configmap name, and TLS serverName fields. This preserves the DNS1123-like constraint without relying on the CEL format library.

config/v1/types_kmsencryption.go

Other (7) +21 / -21
0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yamlRegenerate CustomNoUpgrade apiservers CRD with regex-based CEL rules +3/-3

Regenerate CustomNoUpgrade apiservers CRD with regex-based CEL rules

• Updates the CRD schema rule strings to use 'self.matches(...)' instead of 'format.dns1123Subdomain()' for affected fields, matching the updated kubebuilder markers.

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml

0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yamlRegenerate DevPreviewNoUpgrade apiservers CRD with regex-based CEL rules +3/-3

Regenerate DevPreviewNoUpgrade apiservers CRD with regex-based CEL rules

• Updates the generated CEL rule expressions to regex matching to avoid the CEL format helper dependency.

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml

0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yamlRegenerate TechPreviewNoUpgrade apiservers CRD with regex-based CEL rules +3/-3

Regenerate TechPreviewNoUpgrade apiservers CRD with regex-based CEL rules

• Replaces format-based DNS1123 validation rules with regex-based 'self.matches(...)' in the generated schema.

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml

KMSEncryption.yamlUpdate featuregated KMSEncryption CRD to use regex-based CEL validation +3/-3

Update featuregated KMSEncryption CRD to use regex-based CEL validation

• Aligns the featuregated KMSEncryption CRD manifest with the new regex-based XValidation rules to ensure consistent validation across feature gates.

config/v1/zz_generated.featuregated-crd-manifests/apiservers.config.openshift.io/KMSEncryption.yaml

0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yamlUpdate payload CustomNoUpgrade CRD with regex-based CEL rules +3/-3

Update payload CustomNoUpgrade CRD with regex-based CEL rules

• Propagates the regex-based CEL validation rules into the payload CRD so clusters enforce the portable rule at runtime.

payload-manifests/crds/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml

0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yamlUpdate payload DevPreviewNoUpgrade CRD with regex-based CEL rules +3/-3

Update payload DevPreviewNoUpgrade CRD with regex-based CEL rules

• Updates the payload CRD schema rule strings to the regex-based form for compatibility with environments lacking the format library.

payload-manifests/crds/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml

0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yamlUpdate payload TechPreviewNoUpgrade CRD with regex-based CEL rules +3/-3

Update payload TechPreviewNoUpgrade CRD with regex-based CEL rules

• Ensures the TechPreview payload CRD uses 'self.matches(...)' for DNS1123-like validation consistent with the API types.

payload-manifests/crds/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This change replaces CEL format-based validation with explicit regular expressions. It updates Vault secret names, ConfigMap names, and TLS server names in Go types and three generated APIServer CRDs. It also updates ingress label-value and label-key validation in Go types and three generated Ingress CRDs. Label keys retain the 253-character maximum.

Suggested reviewers: deads2k, everettraven, leo6leo

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: replacing format-based KMS secret name validation with regex validation.
Description check ✅ Passed The description explains the validation change and its purpose of avoiding HyperShift integration test failures.
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 The commit changes only validation source and CRD manifests; it adds or changes no test files or Ginkgo title declarations.
Test Structure And Quality ✅ Passed The PR changes only validation annotations and generated CRD manifests; it adds or modifies no Ginkgo test code, so the listed test-quality checks are not applicable.
Microshift Test Compatibility ✅ Passed The commit changes only ingress validation code and generated CRDs; it adds no Ginkgo e2e tests or test paths, so MicroShift test compatibility checks do not apply.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The pull request adds no Ginkgo e2e tests or test paths; it changes one type file and generated CRD manifests only.
Topology-Aware Scheduling Compatibility ✅ Passed The two-commit PR changes only Go validation annotations and generated CRDs; the diff adds no replicas, affinity, topology spread, node selectors, tolerations, or PDB scheduling constraints.
Ote Binary Stdout Contract ✅ Passed The PR changes only CEL validation annotations and generated YAML; it adds no OTE binary, main/suite setup, or process-level stdout write.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The patch changes validation declarations and generated CRD YAML only; it adds no Ginkgo e2e tests, IPv4 assumptions, or external connectivity.
No-Weak-Crypto ✅ Passed The pull request changes only CEL validation expressions and generated CRDs; no MD5, SHA1, DES, RC4, Blowfish, ECB, custom crypto, or secret comparisons were added.
Container-Privileges ✅ Passed The PR changes only label-validation code and CRD schemas. Added lines contain no privileged, hostPID, hostNetwork, hostIPC, SYS_ADMIN, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed The PR changes only CEL validation annotations and generated CRD rules; the added-line review found no logging calls or sensitive data output.
✨ 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.

@openshift-ci
openshift-ci Bot requested review from deads2k and everettraven July 31, 2026 14:04
@qodo-for-rh-openshift

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@ardaguclu

Copy link
Copy Markdown
Member

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 31, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-hypershift
/test e2e-aws-ovn-hypershift-conformance
/test e2e-aws-ovn-techpreview
/test e2e-aws-serial-1of2
/test e2e-aws-serial-2of2
/test e2e-aws-serial-techpreview-1of2
/test e2e-aws-serial-techpreview-2of2
/test e2e-azure
/test e2e-gcp
/test e2e-upgrade
/test e2e-upgrade-out-of-change
/test minor-e2e-upgrade-minor

@ardaguclu

Copy link
Copy Markdown
Member

/approve

@openshift-ci

openshift-ci Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: ardaguclu
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

@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 3, 2026
@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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`:
- Line 281: Update the XValidation rule on the ingress label-key field in
config/v1/types_ingress.go so each DNS prefix label and the name segment are
length-validated independently, enforcing the qualified-name limits while
allowing a valid 253-character prefix plus “/x”; then regenerate all three CRDs.
Apply the generated schema changes to
payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml:122-123,
payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml:122-123,
and
payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml:122-123,
and add boundary tests covering valid and invalid segment lengths.
- Line 174: Make the LabelValue XValidation regex optional so empty values pass
while preserving rejection of invalid non-empty values and trailing separators;
update the validation in config/v1/types_ingress.go:174, regenerate the affected
config/v1/zz_generated* CRDs, and update the corresponding schemas in
payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml:93,
payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml:93,
and
payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml:93.
Add regression coverage for empty, one-character, valid, and trailing-separator
LabelValue inputs.
🪄 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: cc9f98bb-1b58-48ca-9793-d1b3bd9082f7

📥 Commits

Reviewing files that changed from the base of the PR and between e5a6b6c and 910203b.

⛔ Files ignored due to path filters (4)
  • 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-DevPreviewNoUpgrade.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/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
📒 Files selected for processing (4)
  • config/v1/types_ingress.go
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml

// 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)"
// +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9]([a-zA-Z0-9._-]*[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

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
python - <<'PY'
from pathlib import Path
import re

files = [
    "config/v1/types_ingress.go",
    "payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml",
    "payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml",
    "payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml",
]
expected = "self.matches('^([a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?)?$')"

for filename in files:
    assert expected in Path(filename).read_text(), filename

pattern = re.compile(r"^([a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?)?$")
assert pattern.fullmatch("")
assert pattern.fullmatch("a")
assert pattern.fullmatch("a.b")
assert not pattern.fullmatch("a-")
PY

Repository: openshift/api

Length of output: 268


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for file in \
  config/v1/types_ingress.go \
  payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml \
  payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml \
  payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml
do
  echo "===== $file ====="
  case "$file" in
    *.go) sed -n '160,182p' "$file" ;;
    *.yaml) sed -n '84,100p' "$file" ;;
  esac
done

echo "===== matching ingress label rules ====="
rg -n -C 2 "label values|self\.matches\('\^\[a-zA-Z0-9\]" \
  config/v1/types_ingress.go payload-manifests/crds

echo "===== relevant source context ====="
sed -n '130,190p' config/v1/types_ingress.go

Repository: openshift/api

Length of output: 16795


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

files = [
    Path("config/v1/types_ingress.go"),
    Path("payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml"),
    Path("payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml"),
    Path("payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml"),
]
old = "self.matches('^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$')"
new = "self.matches('^([a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?)?$')"

print("Rule occurrences:")
for path in files:
    text = path.read_text()
    print(f"{path}: old={text.count(old)}, proposed={text.count(new)}")

old_pattern = re.compile(r"^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$")
new_pattern = re.compile(r"^([a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?)?$")
values = ["", "a", "a.b", "a-b", "a_", "a-", ".a", "a.", "a--b", "a" * 63, "a" * 64]

print("\nInput behavior:")
for value in values:
    print(repr(value), "old=", bool(old_pattern.fullmatch(value)), "proposed=", bool(new_pattern.fullmatch(value)))

print("\nLabelValue references:")
for path in Path(".").rglob("*"):
    if path.is_file() and path.suffix in {".go", ".yaml", ".yml"}:
        try:
            text = path.read_text()
        except UnicodeDecodeError:
            continue
        if "LabelValue" in text:
            print(path)
PY

Repository: openshift/api

Length of output: 5632


🏁 Script executed:

#!/bin/bash
set -euo pipefail

old="self.matches('^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$')"

echo "===== all tracked occurrences of the current rule ====="
git grep -n -F "$old" -- \
  'config/v1/types_ingress.go' \
  'config/v1/zz_generated*' \
  'payload-manifests/crds/*ingresses*.yaml' || true

echo "===== LabelValue declaration and field usage ====="
rg -n -C 4 'type LabelValue|string\(LabelValue\)|LabelValue|ComponentRouteLabels|RouteLabels' \
  config/v1 --glob '*.go' --glob '*.yaml'

echo "===== generated schema locations ====="
for file in config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_ingresses-*.crd.yaml \
            config/v1/zz_generated.featuregated-crd-manifests/ingresses.config.openshift.io/IngressComponentRouteLabels.yaml
do
  if [ -f "$file" ]; then
    echo "===== $file ====="
    rg -n -C 5 'label values|self\.matches|labels defines additional labels' "$file"
  fi
done

echo "===== focused tests mentioning ingress labels or LabelValue ====="
rg -n -i -C 3 'LabelValue|component route labels|route labels|empty label|label value' \
  config tests --glob '*.go' --glob '*.yaml' --glob '*.yml' | head -240 || true

Repository: openshift/api

Length of output: 16722


Allow empty LabelValue values in all generated CRDs.

The current validation rejects "", although the type documentation and Kubernetes label rules permit empty values. Make the complete non-empty regex alternative optional, regenerate the affected CRDs under config/v1/zz_generated* and payload-manifests/crds, and add regression coverage for empty, one-character, valid, and trailing-separator values.

📍 Affects 4 files
  • config/v1/types_ingress.go#L174-L174 (this comment)
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml#L93-L93
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml#L93-L93
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml#L93-L93
🤖 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` at line 174, Make the LabelValue XValidation
regex optional so empty values pass while preserving rejection of invalid
non-empty values and trailing separators; update the validation in
config/v1/types_ingress.go:174, regenerate the affected config/v1/zz_generated*
CRDs, and update the corresponding schemas in
payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml:93,
payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml:93,
and
payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml:93.
Add regression coverage for empty, one-character, valid, and trailing-separator
LabelValue inputs.

// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=8
// +kubebuilder:validation:XValidation:rule="self.all(key, !format.qualifiedName().validate(key).hasValue())",message="label keys must be valid qualified names, consisting of an optional DNS subdomain prefix of up to 253 characters followed by a slash and a name segment of 1-63 characters, that consists only of alphanumeric characters, dashes, underscores, and dots, and must start and end with an alphanumeric character"
// +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._-]*[a-zA-Z0-9])?$') && key.size() <= 253)",message="label keys must be valid qualified names, consisting of an optional DNS subdomain prefix of up to 253 characters followed by a slash and a name segment of 1-63 characters, that consists only of alphanumeric characters, dashes, underscores, and dots, and must start and end with an alphanumeric character"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
files=(
  config/v1/types_ingress.go
  payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml
  payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml
  payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml
)

if rg -n --fixed-strings 'key.size() <= 253' "${files[@]}"; then
  echo "The total-key length check is still present." >&2
  exit 1
fi

python - <<'PY'
prefix = ".".join(["a" * 63, "b" * 63, "c" * 63, "d" * 61])
assert len(prefix) == 253
assert len(prefix + "/x") == 255
assert len("a" * 64) == 64
print("Qualified-name boundary fixtures are ready for API-server validation tests.")
PY

Repository: openshift/api

Length of output: 1184


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- source and generated rules ---'
sed -n '270,288p' config/v1/types_ingress.go
for f in \
  payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml \
  payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml \
  payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml
do
  echo "--- $f ---"
  sed -n '115,128p' "$f"
done

echo '--- related validation and tests ---'
rg -n -S 'key\.size\(\)|qualified name|QualifiedName|label keys|types_ingress|Ingress' \
  config payload-manifests --glob '*.go' --glob '*.yaml' --glob '*_test.go' \
  | head -200

Repository: openshift/api

Length of output: 43807


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import re

# The Go annotation and CRDs express this same logical regex after escaping.
pattern = re.compile(
    r'^([a-z0-9]([a-z0-9\-]*[a-z0-9])?'
    r'(\.[a-z0-9]([a-z0-9\-]*[a-z0-9])?)*\/)?'
    r'[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$'
)

def current_accepts(key):
    return bool(pattern.fullmatch(key)) and len(key) <= 253

cases = {
    "64-character name": "n" * 64,
    "64-character DNS label": ("a" * 64) + "/x",
    "253-character prefix plus /x":
        ".".join(["a" * 63, "b" * 63, "c" * 63, "d" * 61]) + "/x",
    "valid 63-character name": "n" * 63,
    "valid 63-character DNS label": ("a" * 63) + "/x",
}
for name, key in cases.items():
    print(f"{name}: key_length={len(key)} regex={bool(pattern.fullmatch(key))} current_rule={current_accepts(key)}")
PY

Repository: openshift/api

Length of output: 496


Validate qualified-name segments independently.

The rule accepts 64-character name and DNS-label segments and rejects a valid 253-character prefix followed by /x. Bound each prefix label and the name segment separately, then regenerate all three CRDs and add boundary tests.

📍 Affects 4 files
  • config/v1/types_ingress.go#L281-L281 (this comment)
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml#L122-L123
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml#L122-L123
  • payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml#L122-L123
🤖 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` at line 281, Update the XValidation rule on the
ingress label-key field in config/v1/types_ingress.go so each DNS prefix label
and the name segment are length-validated independently, enforcing the
qualified-name limits while allowing a valid 253-character prefix plus “/x”;
then regenerate all three CRDs. Apply the generated schema changes to
payload-manifests/crds/0000_10_config-operator_01_ingresses-CustomNoUpgrade.crd.yaml:122-123,
payload-manifests/crds/0000_10_config-operator_01_ingresses-DevPreviewNoUpgrade.crd.yaml:122-123,
and
payload-manifests/crds/0000_10_config-operator_01_ingresses-TechPreviewNoUpgrade.crd.yaml:122-123,
and add boundary tests covering valid and invalid segment lengths.

@openshift-ci

openshift-ci Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@JoelSpeed: 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/e2e-aws-ovn-hypershift-conformance e5a6b6c link true /test e2e-aws-ovn-hypershift-conformance
ci/prow/integration 910203b link true /test integration
ci/prow/verify-hypershift-integration 910203b link true /test verify-hypershift-integration

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.

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

Labels

size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants