Skip to content

OCPBUGS-43353: Add pattern validation for registry entries in image config#2787

Open
reedcort wants to merge 1 commit intoopenshift:masterfrom
reedcort:OCPBUGS-43353
Open

OCPBUGS-43353: Add pattern validation for registry entries in image config#2787
reedcort wants to merge 1 commit intoopenshift:masterfrom
reedcort:OCPBUGS-43353

Conversation

@reedcort
Copy link
Copy Markdown

@reedcort reedcort commented Mar 31, 2026

Summary

  • Add per-item CEL XValidation to insecureRegistries, blockedRegistries, and allowedRegistries fields in the RegistrySources struct (config/v1/types_image.go)
  • Uses the same regex pattern already used by ImageDigestMirrors.Source for consistency
  • Rejects entries with tags (e.g., :latest) or digests (e.g., @sha256:...) that would generate invalid /etc/containers/policy.json and can cause container runtime failures
  • Returns a user-friendly error message instead of dumping the raw regex
  • Adds MinLength=1 to reject empty string entries (which break node bootstrap on HCP)
  • Adds MaxItems=1024 and MaxLength=256 per item for CEL cost estimation (validated against fleet telemetry: max entry length 120, max item count 669)
  • CRD validation ratcheting automatically preserves pre-existing invalid entries on update

Background

Invalid registry entries like registry.io/myrepo:latest in spec.registrySources.blockedRegistries pass through without validation and generate an invalid /etc/containers/policy.json, which can cause container runtime failures.

Validation was initially proposed in hypershift#8070 at the Go level (webhook, controller, nodepool config). That PR was closed in favor of adding the canonical validation here at the API level, as requested by the maintainer.

Test plan

  • make update — all CRD manifests regenerated
  • make -C config/v1 test — all integration tests pass
  • make verify — passes
  • Ratcheting tests verify persisted invalid entries are preserved on update (tagged entries, empty strings)
  • onCreate tests verify invalid tagged/digest entries and empty strings are rejected
  • Valid entry tests cover hostname, hostname/path, wildcard, hostname:port/path

🤖 Generated with Claude Code

@openshift-ci-robot
Copy link
Copy Markdown

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
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Mar 31, 2026

Hello @reedcort! 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/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 31, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added per-item and per-list validation to RegistrySources fields insecureRegistries, blockedRegistries, and allowedRegistries: each array now has maxItems: 128 (kubebuilder/CRD), each item has minLength: 1 and maxLength: 512, and an x-kubernetes-validations / kubebuilder XValidation enforces a registry-scope pattern hostname[:port][/path] or *.hostname while rejecting image tags and digests. Updated Go field comments and Swagger docs to document these constraints. Extended CRD tests to cover create and update acceptance/rejection cases, including on-update scenarios and atomic list revalidation.

🚥 Pre-merge checks | ✅ 9 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Microshift Test Compatibility ❓ Inconclusive Cannot examine pull request without access to repository structure, git diff, or test files to analyze. Provide access to the actual repository files, git diff output, or test file contents to verify if new Ginkgo e2e tests using unavailable MicroShift APIs are being added.
✅ Passed checks (9 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding pattern validation for registry entries in the image config, which is the core purpose of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Stable And Deterministic Test Names ✅ Passed All 25 test names are stable and deterministic with no dynamic identifiers, timestamps, UUIDs, or node/namespace names. Test names use clear, static descriptive strings that indicate what each test validates without containing any dynamic information.
Test Structure And Quality ✅ Passed PR adds YAML-based CRD validation tests, not Ginkgo Go tests. Custom check requirements for Ginkgo patterns (It blocks, BeforeEach/AfterEach, Eventually/Consistently) do not apply.
Single Node Openshift (Sno) Test Compatibility ✅ Passed This pull request does not introduce any Ginkgo e2e tests. The changes consist of updates to Go API type definitions, generated documentation, CRD schema validation rules, and YAML-based CRD validation test configuration files. The repository is the OpenShift API definitions repository which defines API schemas and types, not end-to-end test suites. The YAML test files are declarative CRD schema validation test configurations, not Ginkgo tests. Consequently, there are no multi-node or HA cluster assumptions to evaluate.
Topology-Aware Scheduling Compatibility ✅ Passed PR modifies only API schema validation for Image configuration registry fields with CEL rules and kubebuilder constraints, no operator code changes.
Ote Binary Stdout Contract ✅ Passed The OTE Binary Stdout Contract check is not applicable; modified files contain only Go type definitions, auto-generated documentation, Kubernetes CRD manifests, and test configuration YAML with no executable code.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PR does not add any Ginkgo e2e tests; changes consist of API type definitions and CRD schema validation updates only.
Description check ✅ Passed The pull request description clearly outlines the changes: adding per-item CEL XValidation to registry fields, using a consistent regex pattern, rejecting tags/digests, adding length constraints, and explaining the motivation and test coverage.

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

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/v1/types_image.go`:
- Line 176: The XValidation:rule regex used in the kubebuilder tag for registry
hostnames in types_image.go is too permissive and must be replaced with a
stricter pattern that: disallows empty labels and consecutive dots, disallows
labels that start or end with a hyphen, allows an optional leading wildcard of
the form "*.example.com", allows an optional ":port" immediately after the
hostname (port = one or more digits), and permits optional path segments
("/repo" parts) composed of lowercase letters, digits, dot, underscore or
hyphen; update the XValidation:rule value (the kubebuilder tag string containing
the regex) to enforce these constraints (i.e., ensure each label matches
[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])? and labels are separated by single
dots, optional leading "*." allowed, optional :[0-9]+ after the hostname, then
optional (/[a-z0-9._-]+)* path segments) so valid hosts like "good.example.com",
"quay.io/ns/repo", "*.example.com", and "a.b" are accepted while invalid ones
like "example..com" or "a.-b.com" are rejected.
🪄 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), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 3199948e-925c-4a7a-8be3-c0988a0268e3

📥 Commits

Reviewing files that changed from the base of the PR and between 96f1f5a and 6ab1419.

⛔ Files ignored due to path filters (4)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**
📒 Files selected for processing (3)
  • config/v1/types_image.go
  • config/v1/zz_generated.swagger_doc_generated.go
  • payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml

Comment thread config/v1/types_image.go Outdated
@JoelSpeed
Copy link
Copy Markdown
Contributor

@reedcort These validations are restricting existing GA APIs. How can you be confident in the maximum limits you have added, and that they won't break existing users/use cases? Do you have any telemetry data that would demonstrate the existing usage of these fields?

@reedcort
Copy link
Copy Markdown
Author

@JoelSpeed I noticed that as well. I'm updating the validation to use Pattern instead, which removes the MaxItems and MaxLength constraints entirely to avoid impacting current users.

@JoelSpeed
Copy link
Copy Markdown
Contributor

I noticed that as well. I'm updating the validation to use Pattern instead, which removes the MaxItems and MaxLength constraints entirely to avoid impacting current users.

Any change you make here is going to potentially be breaking. There are existing users of this API. You need to understand/explain how this will impact existing users before we can accept any change that makes the API more restrictive.

We actually do prefer CEL to pattern btw, but we still need to answer my previous questions. What do you know about existing usage of these API fields?

@reedcort reedcort marked this pull request as draft March 31, 2026 16:55
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 31, 2026
@reedcort
Copy link
Copy Markdown
Author

Thanks, makes sense. I'll work on gathering telemetry data on the existing usage of the fields across the fleet.

@reedcort reedcort changed the title Add CEL validation for registry entries in image config OCPBUGS-43353: Add CEL validation for registry entries in image config Apr 1, 2026
@openshift-ci-robot openshift-ci-robot added jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Apr 1, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@reedcort: This pull request references Jira Issue OCPBUGS-43353, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @xiuwang

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • Add per-item CEL validation rules to insecureRegistries, blockedRegistries, and allowedRegistries fields in the RegistrySources struct (config/v1/types_image.go)
  • Each entry is validated against a regex matching valid registry scopes: hostname[:port][/path], optionally with *. wildcard prefix
  • Rejects entries with tags (e.g., :latest) or digests (e.g., @sha256:...) that would generate invalid /etc/containers/policy.json and cause CRI-O to fail
  • Adds MaxItems=512 and items:MaxLength=512 bounds required by the Kubernetes CEL cost estimator

Background

Invalid registry entries like trusted.com/myrepo:latest in spec.configuration.image.registrySources.blockedRegistries pass through without validation, generate an invalid /etc/containers/policy.json, cause CRI-O startup failure, and result in nodes silently failing to join the cluster.

Validation was initially proposed in hypershift#8070 at the Go level (webhook, controller, nodepool config). That PR was closed in favor of adding the canonical CEL validation here at the API level, as requested by the maintainer.

Test plan

  • make update — all CRD manifests regenerated
  • make -C config/v1 test — all 1761 integration tests pass
  • make verify — passes (0 lint issues, 0 kube-api-linter issues)
  • Verify on a staging cluster that invalid entries are rejected at admission

🤖 Generated with Claude Code

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 openshift-ci Bot requested a review from xiuwang April 1, 2026 15:38
@reedcort
Copy link
Copy Markdown
Author

reedcort commented Apr 2, 2026

@JoelSpeed I gathered telemetry data to answer your questions.

Telemetry

Queried CCX/Insights archive across the fleet:

Metric Count
Total clusters with registrySources data ~61,241
Clusters with tagged entries (e.g. :latest) ~108 (0.18%)

Approach

I plan to update the PR to use the same regex pattern already used by ImageDigestMirrors.Source in this repo (config/v1/types_image_digest_mirror_set.go), which supports both wildcard prefixes and Docker-style path separators (__, ---). This rejects tags while allowing all valid registry scopes (hostname[:port][/path]).

Kubernetes CRD validation ratcheting automatically handles existing invalid entries — on update, the API server suppresses validation errors for unchanged values. The ~108 clusters with existing tagged entries would be unaffected; only new invalid entries would be rejected.

One nuance worth noting: during testing I found that reg1.io/myrepo/myapp:latest (2+ path components) is technically valid in policy.json, while trusted.com/myrepo:latest is not — so the breakage from tagged entries is format-dependent and unpredictable for users. Adding this regex would reject both. Since these fields are called blockedRegistries/allowedRegistries/insecureRegistries — semantically they represent registry/repo scopes, not image references — I think this is the right behavior.

Do you think this validation belongs here in the API, or would it be better placed in the MCO / HyperShift operator instead?

@JoelSpeed
Copy link
Copy Markdown
Contributor

Thanks for doing the research. As long as we can add a test case that demonstrates the ratcheting behaviour of currently invalid values (see our tests folder readme and look for ratcheting to see examples), then I think we can proceed with adding the validations here

@reedcort reedcort changed the title OCPBUGS-43353: Add CEL validation for registry entries in image config OCPBUGS-43353: Add pattern validation for registry entries in image config Apr 2, 2026
@reedcort
Copy link
Copy Markdown
Author

reedcort commented Apr 2, 2026

/test lint
/test integration
/test verify
/test verify-client-go
/test verify-crd-schema
/test verify-crdify
/test verify-deps
/test verify-feature-promotion

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Apr 2, 2026

PR-Agent: could not fine a component named lint in a supported language in this PR.

@reedcort
Copy link
Copy Markdown
Author

reedcort commented Apr 2, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@reedcort reedcort marked this pull request as ready for review April 6, 2026 19:45
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 6, 2026
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add pattern validation for registry entries in image config

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add per-item Pattern validation to registry entry fields in RegistrySources
  - Validates insecureRegistries, blockedRegistries, allowedRegistries
  - Rejects entries with tags (:latest) or digests (@sha256:...)
• Enforce valid registry scope format: hostname[:port][/path] with optional wildcard prefix
• CRD validation ratcheting preserves pre-existing invalid entries on update
• Comprehensive test coverage for invalid/valid entries and ratcheting behavior
Diagram
flowchart LR
  A["RegistrySources Fields"] -->|Pattern Validation| B["insecureRegistries"]
  A -->|Pattern Validation| C["blockedRegistries"]
  A -->|Pattern Validation| D["allowedRegistries"]
  B -->|Reject| E["Invalid: tags/digests"]
  C -->|Reject| E
  D -->|Reject| E
  B -->|Accept| F["Valid: hostname[:port][/path]"]
  C -->|Accept| F
  D -->|Accept| F
  F -->|Wildcard Support| G["*.example.com"]
Loading

Grey Divider

File Changes

1. config/v1/types_image.go ✨ Enhancement +18/-0

Add pattern validation to registry entry fields

• Added detailed documentation comments to insecureRegistries, blockedRegistries, and
 allowedRegistries fields
• Added kubebuilder:validation:items:Pattern annotations with regex pattern to validate registry
 scope format
• Pattern enforces hostname with valid DNS labels, optional port, optional path, and optional
 wildcard prefix
• Rejects entries containing tags (:) or digests (@) that would generate invalid policy.json

config/v1/types_image.go


2. config/v1/zz_generated.swagger_doc_generated.go 📝 Documentation +3/-3

Update swagger documentation for registry fields

• Updated swagger documentation for insecureRegistries, blockedRegistries, and
 allowedRegistries
• Added validation requirements and format specifications to field descriptions
• Clarified that entries must not include tags or digests

config/v1/zz_generated.swagger_doc_generated.go


3. openapi/generated_openapi/zz_generated.openapi.go 📝 Documentation +3/-3

Update OpenAPI schema descriptions

• Updated OpenAPI schema descriptions for registry entry fields
• Added validation format and constraint information to field descriptions
• Synchronized with swagger documentation changes

openapi/generated_openapi/zz_generated.openapi.go


View more (5)
4. config/v1/tests/images.config.openshift.io/AAA_ungated.yaml 🧪 Tests +202/-0

Add comprehensive validation and ratcheting tests

• Added 7 new onCreate tests validating rejection of tagged/digest entries in all three registry
 fields
• Added 2 onCreate tests validating acceptance of valid registry entries (hostname, path,
 wildcard, port)
• Added 3 onUpdate tests verifying ratcheting preserves persisted invalid entries when other
 fields change
• Added 2 onUpdate tests verifying atomic list re-validation prevents appending to lists with
 invalid entries

config/v1/tests/images.config.openshift.io/AAA_ungated.yaml


5. config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml ⚙️ Configuration changes +20/-2

Add pattern validation to CRD manifest

• Added pattern validation to CRD manifest for allowedRegistries, blockedRegistries, and
 insecureRegistries
• Updated field descriptions with validation requirements and format specifications
• Pattern enforces valid registry scope format with DNS label constraints

config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml


6. config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml ⚙️ Configuration changes +20/-2

Add pattern validation to featuregated CRD

• Added pattern validation to featuregated CRD manifest for registry entry fields
• Updated field descriptions with validation requirements
• Synchronized with main CRD manifest changes

config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml


7. config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.yaml ⚙️ Configuration changes +20/-2

Add pattern validation to ImageStreamImportMode CRD

• Added pattern validation to ImageStreamImportMode featuregated CRD manifest
• Updated field descriptions with validation requirements
• Synchronized with main CRD manifest changes

config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.yaml


8. payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml ⚙️ Configuration changes +20/-2

Add pattern validation to payload manifest CRD

• Added pattern validation to payload manifest CRD for registry entry fields
• Updated field descriptions with validation requirements and format specifications
• Synchronized with main CRD manifest changes

payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml


Grey Divider

Qodo Logo

@reedcort
Copy link
Copy Markdown
Author

reedcort commented Apr 15, 2026

Aside from a small comment and a question, this LGTM overall.

Thanks for doing an analysis with telemetry. A 16x overhead on the max items seems a bit excessive, I wonder if using something like 128 would be enough (4x increase)?

128 works for me. If no one disagrees I can update MaxItems to 128.

@openshift-ci openshift-ci Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 15, 2026
@openshift-ci-robot openshift-ci-robot added jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. and removed jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Apr 15, 2026
@openshift-ci-robot
Copy link
Copy Markdown

@reedcort: This pull request references Jira Issue OCPBUGS-43353, which is invalid:

  • expected the bug to target either version "5.0." or "openshift-5.0.", but it targets "4.22.0" instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

Details

In response to this:

Summary

  • Add per-item CEL XValidation to insecureRegistries, blockedRegistries, and allowedRegistries fields in the RegistrySources struct (config/v1/types_image.go)
  • Uses the same regex pattern already used by ImageDigestMirrors.Source for consistency
  • Rejects entries with tags (e.g., :latest) or digests (e.g., @sha256:...) that would generate invalid /etc/containers/policy.json and can cause container runtime failures
  • Returns a user-friendly error message instead of dumping the raw regex
  • Adds MinLength=1 to reject empty string entries (which break node bootstrap on HCP)
  • Adds MaxItems=128 and MaxLength=512 per item for CEL cost estimation (validated against fleet telemetry: max entry length 245, max item count 32)
  • CRD validation ratcheting automatically preserves pre-existing invalid entries on update

Background

Invalid registry entries like registry.io/myrepo:latest in spec.registrySources.blockedRegistries pass through without validation and generate an invalid /etc/containers/policy.json, which can cause container runtime failures.

Validation was initially proposed in hypershift#8070 at the Go level (webhook, controller, nodepool config). That PR was closed in favor of adding the canonical validation here at the API level, as requested by the maintainer.

Test plan

  • make update — all CRD manifests regenerated
  • make -C config/v1 test — all integration tests pass
  • make verify — passes
  • Ratcheting tests verify persisted invalid entries are preserved on update (tagged entries, empty strings)
  • onCreate tests verify invalid tagged/digest entries and empty strings are rejected
  • Valid entry tests cover hostname, hostname/path, wildcard, hostname:port/path

🤖 Generated with Claude Code

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.

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/images.config.openshift.io/AAA_ungated.yaml (1)

15-86: Please assert the friendly CEL message in at least one negative case.

These cases only check the field path, so they prove rejection but not the main UX requirement behind switching to items:XValidation: hiding the raw regex. Pin one representative failure to the custom message substring so that regression is covered.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/v1/tests/images.config.openshift.io/AAA_ungated.yaml` around lines 15
- 86, Update one representative negative test to also assert the user-friendly
CEL message substring (not just the field path). For example, in the test named
"Should not allow creating an Image with a tagged registry entry in
blockedRegistries" (the case that sets spec.registrySources.blockedRegistries:
["registry.io/myrepo:latest"]), add an assertion field such as
expectedMessageContains: "must not contain a tag or digest" (or the actual
CEL-friendly substring emitted by the XValidation), so the test checks both the
error field path ("spec.registrySources.blockedRegistries[0]") and that the
human-facing message hides the raw regex; keep the rest of the cases unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@config/v1/tests/images.config.openshift.io/AAA_ungated.yaml`:
- Around line 15-86: Update one representative negative test to also assert the
user-friendly CEL message substring (not just the field path). For example, in
the test named "Should not allow creating an Image with a tagged registry entry
in blockedRegistries" (the case that sets
spec.registrySources.blockedRegistries: ["registry.io/myrepo:latest"]), add an
assertion field such as expectedMessageContains: "must not contain a tag or
digest" (or the actual CEL-friendly substring emitted by the XValidation), so
the test checks both the error field path
("spec.registrySources.blockedRegistries[0]") and that the human-facing message
hides the raw regex; keep the rest of the cases unchanged.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f887ede-9d04-401f-a6f3-2a2bd4694a6b

📥 Commits

Reviewing files that changed from the base of the PR and between c554ae4 and 9754d2d.

⛔ Files ignored due to path filters (5)
  • config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • config/v1/zz_generated.featuregated-crd-manifests/images.config.openshift.io/ImageStreamImportMode.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/images.config.openshift.io/AAA_ungated.yaml
  • config/v1/types_image.go
  • payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • payload-manifests/crds/0000_10_config-operator_01_images.crd.yaml

Comment thread config/v1/types_image.go
Copy link
Copy Markdown
Contributor

@everettraven everettraven left a comment

Choose a reason for hiding this comment

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

Aside from the comment from coderabbit related to the wildcard regular expression seeming to be a reasonable thing to look into, this LGTM

@everettraven
Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Apr 20, 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

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 20, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: everettraven

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

The pull request process is described 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 added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 20, 2026
@everettraven
Copy link
Copy Markdown
Contributor

Intentionally ratcheting validations and have testing and data backing that this is OK to do.

/override ci/prow/verify-crdify

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 20, 2026

@everettraven: Overrode contexts on behalf of everettraven: ci/prow/verify-crdify

Details

In response to this:

Intentionally ratcheting validations and have testing and data backing that this is OK to do.

/override ci/prow/verify-crdify

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.

@reedcort
Copy link
Copy Markdown
Author

/test e2e-aws-ovn-hypershift
/test e2e-aws-ovn-hypershift-conformance
/test e2e-aws-serial-techpreview-1of2
/test e2e-aws-serial-techpreview-2of2

@reedcort
Copy link
Copy Markdown
Author

/hold

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 21, 2026
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Apr 21, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 21, 2026

New changes are detected. LGTM label has been removed.

@reedcort
Copy link
Copy Markdown
Author

Updated limits based on fleet telemetry data from Snowflake (Starburst has been archived):

  • MaxItems: 512 → 1024. Fleet data shows a cluster with 669 insecure registry entries. 128 would have been too restrictive. 1024 provides headroom while staying within the CEL cost budget (1024 with MaxLength=512 exceeds the budget by 1.3x, but 1024 with MaxLength=256 passes).
  • MaxLength: 512 → 256. Max entry length observed in fleet is 120 characters. 256 provides ~2x headroom and keeps the CEL cost within budget at MaxItems=1024.
  • MinLength: Added MinLength=1 to reject empty string entries per @everettraven's suggestion. Includes ratcheting tests.

@reedcort
Copy link
Copy Markdown
Author

/unhold

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 21, 2026
Comment thread config/v1/types_image.go Outdated
Comment on lines +192 to +211
// +kubebuilder:validation:MaxItems=780
// +kubebuilder:validation:items:MinLength=1
// +kubebuilder:validation:items:MaxLength=512
// +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests"
BlockedRegistries []string `json:"blockedRegistries,omitempty"`
// allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied.
// Each entry must be a valid registry scope in the format hostname[:port][/path],
// optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com").
// The hostname must consist of valid DNS labels separated by dots, where each label
// contains only alphanumeric characters and hyphens and does not start or end with a hyphen.
// Entries must not be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."),
// and must be at most 512 characters in length. The list may contain at most 780 entries.
//
// Only one of BlockedRegistries or AllowedRegistries may be set.
// +optional
// +listType=atomic
// +kubebuilder:validation:MaxItems=780
// +kubebuilder:validation:items:MinLength=1
// +kubebuilder:validation:items:MaxLength=512
// +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we want these to match the insecureRegistries validations?

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.

yeah, all three should match, I made the update.

Adds CEL XValidation, MinLength, MaxLength, and MaxItems constraints
to insecureRegistries, blockedRegistries, and allowedRegistries fields
in RegistrySources to reject invalid entries (e.g., tagged or digest
references) that can cause container runtime failures.

Includes ratcheting tests to ensure clusters with pre-existing invalid
entries can still update other fields without being blocked.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 22, 2026

@reedcort: The following test 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-crdify 9dd6a39 link true /test verify-crdify

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

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants