Skip to content

OCPBUGS-66211: fix(vendor): bump openshift/api dependency to current master - #7345

Merged
openshift-merge-bot[bot] merged 6 commits into
openshift:mainfrom
csrwng:bump-openshift-api
Dec 17, 2025
Merged

OCPBUGS-66211: fix(vendor): bump openshift/api dependency to current master#7345
openshift-merge-bot[bot] merged 6 commits into
openshift:mainfrom
csrwng:bump-openshift-api

Conversation

@csrwng

@csrwng csrwng commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

This updates the OpenShift API dependencies to the current master branch versions as of 2025-12-04.

Key dependency changes:

  • github.com/openshift/api: v0.0.0-20251204193610-68ce3d906ec8
  • Updated all related OpenShift API modules to matching versions
  • Updated code generation tools in hack/tools/go.mod to v0.34.1

Code changes made to accommodate API updates:

  • Fixed etcd v3.6.4 compatibility in pkg/etcdcli/etcdcli.go
  • Updated OpenShift authentication API usage in auth tests
  • Migrated client-go testing utilities to new managedfields API
  • Updated structured-merge-diff from v4 to v6 in client code
  • Fixed etcd integration test API changes
  • Regenerated client code using updated tools
  • Fixed CEL API deprecation by migrating from cel.Declarations to cel.Variable
  • Added nolint suppressions for backward compatibility with deprecated APIs

🤖 Generated with Claude Code

@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 Dec 5, 2025
@openshift-ci

openshift-ci Bot commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds Makefile cleanup steps for SelfManagedHA CRD YAMLs, updates Go module dependencies, renames a feature gate, tightens OIDC/issuer validations and required fields, and extends many HostedCluster/HostedControlPlane CRD manifests with AWS networkLoadBalancer.subnets and eipAllocations plus cross-field and scope validations.

Changes

Cohort / File(s) Change Summary
Build & Dependency
Makefile, api/go.mod
Makefile: after moving final CRDs to install folder, adds cleanup commands to remove hostedclusters-SelfManagedHA-*.yaml and hostedcontrolplanes-SelfManagedHA-*.yaml before generating additional CRDs. api/go.mod: bumps many k8s/openshift-related modules and updates indirect dependencies.
Feature gates
api/hypershift/v1beta1/featuregates/featureGate-Hypershift-Default.yaml, api/hypershift/v1beta1/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml, api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml
Renames DynamicResourceAllocationHyperShiftOnlyDynamicResourceAllocation in feature gate lists; removes IngressControllerLBSubnetsAWS and SetEIPForNLBIngressController entries from generated manifests.
HostedCluster CRD manifests
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/*.yaml (e.g., AAA_ungated.yaml, AutoNodeKarpenter.yaml, ClusterVersionOperatorConfiguration.yaml, ExternalOIDC*.yaml, GCPPlatform.yaml, ImageStreamImportMode.yaml, KMSEncryptionProvider.yaml, NetworkDiagnosticsConfig.yaml, OpenStack.yaml, etc.)
Adds networkLoadBalancer.subnets (object with ids/names) and networkLoadBalancer.eipAllocations (array of EIP IDs) with per-item formats, maxItems 10, uniqueness rules, and x-kubernetes-validations enforcing parity between subnet counts and EIP allocations for ids/names/both. Adds scope-based validation forbidding eipAllocations when scope is Internal. Updates tlsSecurityProfile descriptions and fixes typos (overridenoverridden). ExternalOIDC variants: tighten issuerURL validations and make claimMappings and username required; adjust other cardinalities/lengths.
HostedControlPlane CRD manifests
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/*.yaml (e.g., AAA_ungated.yaml, AutoNodeKarpenter.yaml, ClusterVersionOperatorConfiguration.yaml, ExternalOIDC*.yaml, GCPPlatform.yaml, ImageStreamImportMode.yaml, KMSEncryptionProvider.yaml, NetworkDiagnosticsConfig.yaml, OpenStack.yaml, etc.)
Mirrors HostedCluster changes: adds subnets and eipAllocations with identical validation patterns and cross-field rules; forbids eipAllocations when scope is Internal; updates tlsSecurityProfile descriptions and fixes typos. ExternalOIDC variants: make claimMappings and username required, add issuerURL URL/length validations, reduce some cardinalities and tighten expression lengths.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas to focus during review:

  • Representative CRD files (e.g., AAA_ungated.yaml, one ExternalOIDC variant, one HostedControlPlane variant) to verify x-kubernetes-validations correctly express parity across ids/names/both cases.
  • Scope-based forbiddance rules for eipAllocations (ensure correct scoping and no unintended blocking of valid External/Internal combinations).
  • api/go.mod dependency upgrades for potential API or build compatibility issues.
  • OIDC/issuer changes: confirm required-field promotions (claimMappings, username) and tightened issuerURL validations align with consumers.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@openshift-ci-robot openshift-ci-robot added 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 Dec 5, 2025
@openshift-ci-robot

Copy link
Copy Markdown

@csrwng: This pull request references Jira Issue OCPBUGS-66211, 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.21.0) matches configured target version for branch (4.21.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

No GitHub users were found matching the public email listed for the QA contact in Jira (yli2@redhat.com), skipping review request.

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

Details

In response to this:

What this PR does / why we need it:

This updates the OpenShift API dependencies to the current master branch versions as of 2025-12-04.

Key dependency changes:

  • github.com/openshift/api: v0.0.0-20251204193610-68ce3d906ec8
  • Updated all related OpenShift API modules to matching versions
  • Updated code generation tools in hack/tools/go.mod to v0.34.1

Code changes made to accommodate API updates:

  • Fixed etcd v3.6.4 compatibility in pkg/etcdcli/etcdcli.go
  • Updated OpenShift authentication API usage in auth tests
  • Migrated client-go testing utilities to new managedfields API
  • Updated structured-merge-diff from v4 to v6 in client code
  • Fixed etcd integration test API changes
  • Regenerated client code using updated tools
  • Fixed CEL API deprecation by migrating from cel.Declarations to cel.Variable
  • Added nolint suppressions for backward compatibility with deprecated APIs

🤖 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 commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: csrwng

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 approved Indicates a PR has been approved by an approver from all required OWNERS files. area/api Indicates the PR includes changes for the API area/ci-tooling Indicates the PR includes changes for CI or tooling area/cli Indicates the PR includes changes for CLI area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/control-plane-pki-operator Indicates the PR includes changes for the control plane PKI operator - in an OCP release area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/kubevirt PR/issue for KubeVirt (KubevirtPlatform) platform area/testing Indicates the PR includes changes for e2e testing and removed do-not-merge/needs-area labels Dec 5, 2025
@csrwng

csrwng commented Dec 5, 2025

Copy link
Copy Markdown
Contributor Author

/test verify
/test unit
/test e2e-aws-minimal

@jparrill

jparrill commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

/assign @jparrill

@jparrill

jparrill commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

Unit and Verify are failing, once solved just let me know for tagging @csrwng :)

@csrwng
csrwng force-pushed the bump-openshift-api branch from fe95ca5 to 08ab4ed Compare December 5, 2025 21:54
@csrwng

csrwng commented Dec 5, 2025

Copy link
Copy Markdown
Contributor Author

/test verify
/test unit
/test e2e-aws-minimal

@openshift-ci openshift-ci Bot added area/platform/aws PR/issue for AWS (AWSPlatform) platform area/platform/azure PR/issue for Azure (AzurePlatform) platform area/platform/gcp PR/issue for GCP (GCPPlatform) platform area/platform/none PR/issue for None (NonePlatform) platform - user-supplied infrastructure area/platform/openstack PR/issue for OpenStack (OpenStackPlatform) platform area/platform/powervs PR/issue for PowerVS (PowerVSPlatform) platform labels Dec 5, 2025
@openshift-ci-robot

Copy link
Copy Markdown

@csrwng: This PR has been marked as verified by e2e test.

Details

In response to this:

/verified by e2e test

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.

@bryan-cox

Copy link
Copy Markdown
Member

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Dec 16, 2025
@bryan-cox

Copy link
Copy Markdown
Member

/jira refresh

@openshift-ci-robot

Copy link
Copy Markdown

@bryan-cox: This pull request references Jira Issue OCPBUGS-66211, which is valid.

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 POST, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @wewang58

Details

In response to this:

/jira refresh

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.

@csrwng

csrwng commented Dec 16, 2025

Copy link
Copy Markdown
Contributor Author

/label priority/ci-critical

@openshift-ci
openshift-ci Bot requested a review from wewang58 December 16, 2025 15:48
@openshift-ci

openshift-ci Bot commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

@csrwng: The label(s) /label priority/ci-critical cannot be applied. These labels are supported: acknowledge-critical-fixes-only, platform/aws, platform/azure, platform/baremetal, platform/google, platform/libvirt, platform/openstack, ga, tide/merge-method-merge, tide/merge-method-rebase, tide/merge-method-squash, px-approved, docs-approved, qe-approved, ux-approved, no-qe, downstream-change-needed, rebase/manual, cluster-config-api-changed, run-integration-tests, approved, backport-risk-assessed, bugzilla/valid-bug, cherry-pick-approved, jira/valid-bug, ok-to-test, stability-fix-approved, staff-eng-approved. Is this label configured under labels -> additional_labels or labels -> restricted_labels in plugin.yaml?

Details

In response to this:

/label priority/ci-critical

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.

@muraee

muraee commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

/lgtm

@muraee

muraee commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

/priority ci-critical

@openshift-ci

openshift-ci Bot commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

@muraee: The label(s) priority/ci-critical cannot be applied, because the repository doesn't have them.

Details

In response to this:

/priority ci-critical

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml (1)

6471-6477: Typo in acceptedRisks description (“menition”)

Minor doc issue: “menition” should be “mention”.

-                            acceptedRisks records risks which were accepted to initiate the update.
-                            For example, it may menition an Upgradeable=False or missing signature
+                            acceptedRisks records risks which were accepted to initiate the update.
+                            For example, it may mention an Upgradeable=False or missing signature
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml (1)

6548-6554: Minor typo in acceptedRisks description

“menition” on Line 6552 should be “mention” in user‑facing status text:

-                            For example, it may menition an Upgradeable=False or missing signature
+                            For example, it may mention an Upgradeable=False or missing signature
♻️ Duplicate comments (29)
api/hypershift/v1beta1/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml (1)

26-26: Feature gate rename looks correct.

The rename from DynamicResourceAllocation to HyperShiftOnlyDynamicResourceAllocation follows the HyperShift-specific naming convention. This change must be accompanied by updates to the Go code and testdata files as flagged in the previous review comment.

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml (1)

3095-3230: Harden eipAllocations validation and require explicit subnets when EIPs are set

Two issues around the new AWS NLB eipAllocations wiring:

  1. The item-level CEL validation risks runtime errors:

    • self.split("-", 2)[1] will fail if the value lacks a - (still possible given only length constraints).
    • This can surface as a CEL evaluation error instead of a clean validation failure.
  2. eipAllocations can be set while subnets is omitted (auto-discovery), making the “must match number of subnets used” requirement unenforceable and likely unsupported.

Recommend:

  • Replace the two startsWith/split rules with a single anchored regex that fully describes the EIP allocation ID, avoiding indexing:
-                                              x-kubernetes-validations:
-                                              - message: eipAllocations should start
-                                                  with 'eipalloc-'
-                                                rule: self.startsWith('eipalloc-')
-                                              - message: eipAllocations must be 'eipalloc-'
-                                                  followed by exactly 17 hexadecimal
-                                                  characters (0-9, a-f, A-F)
-                                                rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')
+                                              x-kubernetes-validations:
+                                              - message: eipAllocations must be of the form 'eipalloc-' followed by exactly 17 hexadecimal characters (0-9, a-f, A-F)
+                                                rule: self.matches('^eipalloc-[0-9a-fA-F]{17}$')
  • Add a guard at the networkLoadBalancer level so EIPs cannot be configured without explicit subnets (rely on the existing per-subnet “at least one id or name” rule to enforce non-emptiness):
                                       type: object
-                                        x-kubernetes-validations:
-                                        - message: number of subnets must be equal
+                                        x-kubernetes-validations:
+                                        - message: subnets must be specified when eipAllocations is set
+                                          rule: '!has(self.eipAllocations) || has(self.subnets)'
+                                        - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)
                                             && has(self.subnets.names) && has(self.eipAllocations)
                                             ? size(self.subnets.ids + self.subnets.names)
                                             == size(self.eipAllocations) : true'

The existing scope-based prohibition for eipAllocations when scope is Internal looks correct and can remain as-is.

Also applies to: 3378-3383

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml (1)

3094-3233: Harden eipAllocations CEL validation to avoid split() index errors.

The item-level rule:

- message: eipAllocations must be 'eipalloc-'
    followed by exactly 17 hexadecimal
    characters (0-9, a-f, A-F)
  rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')

can throw a CEL index‑out‑of‑bounds error if the value is 26 chars long but contains no - (the prior startsWith('eipalloc-') rule will fail, but this rule is still evaluated). That yields a generic admission error instead of the intended validation message.

You can express the same constraint more safely with a single anchored regex over the whole string and drop the split():

           x-kubernetes-validations:
-          - message: eipAllocations should start
-              with 'eipalloc-'
-            rule: self.startsWith('eipalloc-')
-          - message: eipAllocations must be 'eipalloc-'
-              followed by exactly 17 hexadecimal
-              characters (0-9, a-f, A-F)
-            rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')
+          - message: eipAllocations must match ^eipalloc-[0-9a-fA-F]{17}$
+            rule: self.matches('^eipalloc-[0-9a-fA-F]{17}$')

The surrounding cross-field checks (subnets vs eipAllocations counts) and the scope != Internal constraint for AWS NLBs look correct.

Also applies to: 3378-3383

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml (1)

3247-3381: Tighten NLB eipAllocations/subnets contract and simplify EIP validation

Two points here:

  1. eipAllocations allowed without subnets (ambiguous config)
    The docs say the number of EIPs must match the number of subnets, but nothing currently prevents specifying eipAllocations with no subnets at all. That leaves behavior ambiguous (index-based mapping to auto-discovered subnets) and diverges from the documented contract.

    Consider adding a presence constraint at the networkLoadBalancer level so that non-empty eipAllocations require subnets:

     networkLoadBalancer:
       ...
     -  type: object
  • x-kubernetes-validations:
    
  • type: object
    
  • x-kubernetes-validations:
    
  • - message: subnets must be specified when eipAllocations are set
    
  •   rule: '!has(self.eipAllocations) || self.eipAllocations.size() == 0 || has(self.subnets)'
    - message: number of subnets must be equal
        to number of eipAllocations
      rule: 'has(self.subnets) && has(self.subnets.ids)
    
    
    (Adjust exact insertion point as needed to keep this alongside the existing parity rules.)
    
    
  1. EIP item CEL rule can be made safer and clearer
    The second validation on individual eipAllocations uses self.split("-", 2)[1] which will error for malformed values without '-', yielding a lower-signal CEL error. You can express the full constraint with a single regex instead:

     items:
       description: |-
         EIPAllocation is an ID for an Elastic IP (EIP) address ...
  • maxLength: 26
    
  • minLength: 26
    
  • type: string
    
  • x-kubernetes-validations:
    
  • - message: eipAllocations should start
    
  •     with 'eipalloc-'
    
  •   rule: self.startsWith('eipalloc-')
    
  • - message: eipAllocations must be 'eipalloc-'
    
  •     followed by exactly 17 hexadecimal
    
  •     characters (0-9, a-f, A-F)
    
  •   rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')
    
  • type: string
    
  • x-kubernetes-validations:
    
  • - message: eipAllocations must be 'eipalloc-' followed by exactly 17 hexadecimal characters (0-9, a-f, A-F)
    
  •   rule: self.matches('^eipalloc-[0-9a-fA-F]{17}$')
    
    
    (You can keep or drop the explicit `minLength`/`maxLength` as preferred; the pattern already enforces length.)
    
    

These changes align the schema more closely with the documented semantics and avoid brittle CEL expressions.

Also applies to: 3530-3535

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml (1)

3195-3330: Consider requiring explicit subnets whenever eipAllocations is set

Right now eipAllocations can be non-empty while subnets is omitted (auto-discovery). In that case, the “EIP count must match subnet count” guarantee can’t be enforced at admission and misconfigurations will only surface at reconcile/provisioning time.

If the intent is to only support EIPs when the user pins subnets explicitly, consider adding an extra validation at the networkLoadBalancer object level such as:

 networkLoadBalancer:
   type: object
-  x-kubernetes-validations:
+  x-kubernetes-validations:
+  - message: subnets must be specified when eipAllocations is set
+    rule: '!has(self.eipAllocations) || has(self.subnets)'
   - message: number of subnets must be equal
     to number of eipAllocations
     rule: 'has(self.subnets) && has(self.subnets.ids)
       && has(self.subnets.names) && has(self.eipAllocations)
       ? size(self.subnets.ids + self.subnets.names)
       == size(self.eipAllocations) : true'
   ...

If auto-discovered subnets + EIPs is a supported configuration and the controller validates parity itself, this can be left as-is.

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml (2)

3103-3238: CEL validation bug: split("-", 2) on eipAllocations will break CRD validation.

The item-level rule:

rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')

uses a 2-argument split in CEL, which is not supported in Kubernetes CRD validation and will cause the CRD’s CEL expressions to fail to compile. This can prevent applying or updating the CRD.

You already have length and prefix constraints; replace the suffix check with substring to avoid split entirely:

-                                              - message: eipAllocations must be 'eipalloc-'
-                                                  followed by exactly 17 hexadecimal
-                                                  characters (0-9, a-f, A-F)
-                                                rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')
+                                              - message: eipAllocations must be 'eipalloc-'
+                                                  followed by exactly 17 hexadecimal
+                                                  characters (0-9, a-f, A-F)
+                                                rule: self.substring(9).matches('^[0-9a-fA-F]{17}$')

This keeps the invariant “eipalloc- + 17 hex chars” while using CEL operations that are known to work in CRD validations.


6414-6419: User-facing typo in acceptedRisks description (“menition” → “mention”).

The description still contains menition instead of mention; this shows up in user documentation.

-                          acceptedRisks records risks which were accepted to initiate the update.
-                          For example, it may menition an Upgradeable=False or missing signature
+                          acceptedRisks records risks which were accepted to initiate the update.
+                          For example, it may mention an Upgradeable=False or missing signature
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml (1)

1111-1133: Use url(self).getQuery().size() == 0 instead of == {} for CEL map emptiness.

url(self).getQuery() returns a map; comparing directly to {} is less robust than checking .size() == 0 and can behave inconsistently across CEL/Kubernetes versions. Using .size() == 0 is the safer and more idiomatic way to assert “no query parameters”.

Prefer updating the generator/template that emits these validations so all similar URL rules use .getQuery().size() == 0, then regenerate this file.

-                                  - message: must not have a query
-                                    rule: isURL(self) && url(self).getQuery() == {}
+                                  - message: must not have a query
+                                    rule: isURL(self) && url(self).getQuery().size() == 0
#!/bin/bash
set -euo pipefail

# Find remaining CEL validations that still compare url(self).getQuery() directly to {}
rg -n "url\(self\)\.getQuery\(\) == {}" --type yaml
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml (2)

3142-3275: Tighten NLB EIP validations: require subnets when using eipAllocations and avoid fragile split() usage

Two points here:

  1. eipAllocations allowed without any subnets
    All three “counts must be equal” rules short-circuit to true when self.subnets is absent, so a user can set eipAllocations alone and still pass validation. If the ingress/operator logic assumes explicit subnets whenever EIPs are specified (common for AWS NLB SubnetMapping with EIPs), this becomes a runtime failure instead of a CRD validation failure. Consider adding an explicit guard that any presence of eipAllocations requires at least one subnet ID or name.

  2. Fragile CEL expression using split("-", 2)[1]
    The per-item rule self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$') can raise CEL evaluation errors for malformed values that don’t contain -, leading to less clear admission errors. A single regex over the full string is safer and clearer.

Suggested change for the item validation:

-                                            x-kubernetes-validations:
-                                            - message: eipAllocations should start
-                                                with 'eipalloc-'
-                                              rule: self.startsWith('eipalloc-')
-                                            - message: eipAllocations must be 'eipalloc-'
-                                                followed by exactly 17 hexadecimal
-                                                characters (0-9, a-f, A-F)
-                                              rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')
+                                            x-kubernetes-validations:
+                                            - message: eipAllocations must match ^eipalloc-[0-9a-fA-F]{17}$
+                                              rule: self.matches('^eipalloc-[0-9a-fA-F]{17}$')

And an additional NLB-level validation to force subnets when EIPs are set:

-                                        x-kubernetes-validations:
+                                        x-kubernetes-validations:
+                                        - message: subnets must be specified when eipAllocations is set
+                                          rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)

The new load-balancer–scope-level guard forbidding eipAllocations when scope is Internal is correct and matches the documented restriction.

Also applies to: 3425-3430


6444-6447: Typo in acceptedRisks description (“menition” → “mention”)

The user-facing text still says “it may menition an Upgradeable=False…”. Please correct to “may mention” in this description block.

-                            For example, it may menition an Upgradeable=False or missing signature
+                            For example, it may mention an Upgradeable=False or missing signature
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml (1)

3177-3265: Require explicit subnets when eipAllocations is set for AWS NLBs

Right now networkLoadBalancer.eipAllocations can be provided while networkLoadBalancer.subnets is omitted. All three parity validations short‑circuit when has(self.subnets) is false, so such configurations pass schema validation even though the description states that the number of EIPs must match the subnets used.

This can lead to misconfigured NLBs that are accepted by the API but cannot be reconciled as intended. Add a CEL guard at the networkLoadBalancer level to require at least one subnet ID or name whenever eipAllocations is set.

Suggested patch (schema context shortened for clarity):

                                       networkLoadBalancer:
                                         description: |-
                                           networkLoadBalancerParameters holds configuration parameters for an AWS
                                           network load balancer. Present only if type is NLB.
                                         properties:
                                           eipAllocations:
                                             ...
                                           subnets:
                                             ...
                                         type: object
-                                        x-kubernetes-validations:
+                                        x-kubernetes-validations:
+                                        - message: subnets must be specified when eipAllocations is set
+                                          rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)
                                             && has(self.subnets.names) && has(self.eipAllocations)
                                             ? size(self.subnets.ids + self.subnets.names)
                                             == size(self.eipAllocations) : true'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)
                                             && !has(self.subnets.names) && has(self.eipAllocations)
                                             ? size(self.subnets.ids) == size(self.eipAllocations)
                                             : true'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.names)
                                             && !has(self.subnets.ids) && has(self.eipAllocations)
                                             ? size(self.subnets.names) == size(self.eipAllocations)
                                             : true'

This keeps auto‑discovery behavior intact for the common case (no EIPs, no explicit subnets), while enforcing the stronger invariant only when EIPs are requested.

Also applies to: 3267-3405, 3554-3559

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml (1)

3170-3305: Potential validation gap: eipAllocations allowed without explicit subnets

networkLoadBalancer.eipAllocations can be set while networkLoadBalancer.subnets is omitted (auto-discovery). All three count‑equality rules are guarded with has(self.subnets), so they don’t fire in that case. This contradicts the description (“number of EIP allocations must match the number of subnets that are used for the load balancer”) and is likely to fail later at reconciliation/provisioning time if the discovered subnet count doesn’t match the EIP list.

Consider adding a top‑level validation on networkLoadBalancer that requires explicit subnets (with at least one id or name) whenever eipAllocations is provided, e.g.:

   networkLoadBalancer:
     properties:
       eipAllocations:
         ...
       subnets:
         ...
     type: object
     x-kubernetes-validations:
+    - message: subnets must be specified when eipAllocations are specified
+      rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
     - message: number of subnets must be equal
       to number of eipAllocations
       rule: 'has(self.subnets) && has(self.subnets.ids)
         && has(self.subnets.names) && has(self.eipAllocations)
         ? size(self.subnets.ids + self.subnets.names)
         == size(self.eipAllocations) : true'
     ...

This keeps auto‑discovery behavior for the common case (no EIPs), but rejects misconfigured “EIPs without explicit subnets” combinations up front. If the underlying Ingress operator does intentionally support EIPs with subnet auto‑discovery, you can ignore this suggestion.

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml (2)

3241-3376: Consider requiring explicit subnets when eipAllocations is set

Right now eipAllocations can be set without subnets, so all the “subnets == eipAllocations” validations are skipped (the has(self.subnets) guards short‑circuit to true). That means a user can configure EIPs while relying on auto-discovered subnets, and the schema cannot enforce the documented constraint “The number of EIP allocations must match the number of subnets that are used for the load balancer.”

If the intent is to make that constraint meaningful at admission time (and avoid hard‑to‑diagnose runtime failures), consider adding a CEL guard on the same networkLoadBalancer object to force explicit subnets whenever eipAllocations is present, e.g.:

                                       x-kubernetes-validations:
+                                      - message: subnets must be specified when eipAllocations is set
+                                        rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
                                       - message: number of subnets must be equal
                                         to number of eipAllocations
                                         rule: 'has(self.subnets) && has(self.subnets.ids)
                                           && has(self.subnets.names) && has(self.eipAllocations)
                                           ? size(self.subnets.ids + self.subnets.names)
                                           == size(self.eipAllocations) : true'

(Same idea applies to the other two parity rules; they’re fine once subnets is guaranteed present and nonempty.)


6580-6584: Minor docstring typo and clarity in acceptedRisks

There’s still a small typo and slightly ambiguous phrasing in the acceptedRisks description:

-                            acceptedRisks records risks which were accepted to initiate the update.
-                            For example, it may menition an Upgradeable=False or missing signature
-                            that was overridden via desiredUpdate.force, or an update that was
+                            acceptedRisks records risks which were accepted to initiate the update.
+                            For example, it may mention an Upgradeable=False condition or a missing
+                            signature that was overridden via desiredUpdate.force, or an update that was

Optional, but this would read more cleanly in docs.

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml (2)

3214-3350: AWS NLB eipAllocations/subnets/scope validations are mostly solid; consider tightening EIP–subnet coupling

  • Per‑item validation on eipAllocations is now safe (prefix check + fixed length make split("-", 2)[1] non‑erroneous) and enforces the intended eipalloc-<17 hex> format.
  • Cross‑field rules correctly ensure the number of explicit subnets (ids+names) equals the number of eipAllocations when both are present, and the new load balancer–scope rule cleanly forbids eipAllocations for scope: Internal.

One behavioral gap remains: it’s still possible to set eipAllocations without explicitly specifying subnets, despite the description requiring the counts to match. That leaves mismatches to be caught only at reconciliation time.

If you want this invariant enforced at the CRD layer, you can add an extra validation on the NLB block so that EIPs are only allowed when subnets (ids or names) are specified:

-                                        type: object
-                                        x-kubernetes-validations:
+                                        type: object
+                                        x-kubernetes-validations:
+                                        - message: eipAllocations requires explicitly specified subnets
+                                          rule: '!has(self.eipAllocations) || (has(self.subnets) && (has(self.subnets.ids) || has(self.subnets.names)))'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)
                                             && has(self.subnets.names) && has(self.eipAllocations)
                                             ? size(self.subnets.ids + self.subnets.names)
                                             == size(self.eipAllocations) : true'

6553-6557: Fix typo in user‑facing acceptedRisks description

Line 6555 has a small typo: "may menition""may mention". Suggest:

-                            For example, it may menition an Upgradeable=False or missing signature
+                            For example, it may mention an Upgradeable=False or missing signature
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml (2)

3213-3347: NLB EIP/subnet constraints look solid; consider also requiring subnets when EIPs are set

The new schema does a good job of:

  • Validating EIP IDs (eipalloc- + 17 hex chars, max 10, unique).
  • Validating subnet IDs/names and enforcing uniqueness and a combined limit of 10.
  • Enforcing 1:1 parity between eipAllocations and subnets for all combinations of ids/names.
  • Forbidding eipAllocations when scope is Internal.

One remaining gap is that the CRD still allows eipAllocations to be set while subnets is completely omitted (auto-discovery case). If the controller truly supports “EIPs + auto-discovered subnets” and validates parity at runtime, this is fine. If instead you expect users to always provide an explicit subnet list when pinning EIPs, you could tighten the schema with an additional validation:

 networkLoadBalancer:
   type: object
-  x-kubernetes-validations:
+  x-kubernetes-validations:
+  - message: subnets must be specified when eipAllocations are set
+    rule: '!has(self.eipAllocations) || has(self.subnets)'
   - message: number of subnets must be equal
     to number of eipAllocations

Treating this as optional, depending on the intended UX for EIP + auto-discovery.

Also applies to: 3496-3501


6583-6588: Fix lingering typo in acceptedRisks description (“menition” → “mention”)

User-facing description still says “menition”; suggest correcting to “mention”:

-                            For example, it may menition an Upgradeable=False or missing signature
+                            For example, it may mention an Upgradeable=False or missing signature
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml (2)

3368-3741: AWS NLB eipAllocations still allowed without subnets—add validation to require subnets when EIPs are set

Even after adding count‑equality checks, a user can still specify providerParameters.aws.networkLoadBalancer.eipAllocations with no networkLoadBalancer.subnets. That contradicts the doc (“number of EIP allocations must match the number of subnets that are used for the load balancer”) and is unlikely to be supported by the NLB implementation, since each EIP must map to a specific subnet.

Recommend adding a x-kubernetes-validations rule under networkLoadBalancer to require at least one subnet ID or name whenever eipAllocations is present, e.g.:

                                       x-kubernetes-validations:
+                                      - message: subnets must be specified when eipAllocations is set
+                                        rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
                                       - message: number of subnets must be equal
                                           to number of eipAllocations
                                         rule: 'has(self.subnets) && has(self.subnets.ids)

This keeps the existing count‑equality checks but prevents unusable configurations with EIPs and no subnets.


6923-6929: Fix minor typo in acceptedRisks description (“menition” → “mention”)

User‑facing text under status.versionStatus.history[*].acceptedRisks still says “menition”; suggest correcting spelling:

-                            For example, it may menition an Upgradeable=False or missing signature
+                            For example, it may mention an Upgradeable=False or missing signature
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml (1)

3362-3375: EIP allocation validation: avoid split(...)[1] index; use a single regex on the full string

Using self.split("-", 2)[1] risks CEL index-out-of-range evaluation errors whenever a value is missing a - (or otherwise malformed). That turns bad input into an evaluation error instead of a clean false, and is more brittle than necessary. A single regex against the whole value is simpler and safer, while still enforcing the exact same constraint.

Consider tightening the rule like this:

-                                            items:
-                                              description: |-
-                                                EIPAllocation is an ID for an Elastic IP (EIP) address that can be allocated to an ELB in the AWS environment.
-                                                Values must begin with `eipalloc-` followed by exactly 17 hexadecimal (`[0-9a-fA-F]`) characters.
-                                              maxLength: 26
-                                              minLength: 26
-                                              type: string
-                                              x-kubernetes-validations:
-                                              - message: eipAllocations should start
-                                                  with 'eipalloc-'
-                                                rule: self.startsWith('eipalloc-')
-                                              - message: eipAllocations must be 'eipalloc-'
-                                                  followed by exactly 17 hexadecimal
-                                                  characters (0-9, a-f, A-F)
-                                                rule: self.split("-", 2)[1].matches('[0-9a-fA-F]{17}$')
+                                            items:
+                                              description: |-
+                                                EIPAllocation is an ID for an Elastic IP (EIP) address that can be allocated to an ELB in the AWS environment.
+                                                Values must match ^eipalloc-[0-9a-fA-F]{17}$.
+                                              maxLength: 26
+                                              minLength: 26
+                                              type: string
+                                              x-kubernetes-validations:
+                                              - message: eipAllocations must match ^eipalloc-[0-9a-fA-F]{17}$
+                                                rule: self.matches('^eipalloc-[0-9a-fA-F]{17}$')

This keeps the length invariant but expresses prefix and hex-suffix in one place without any indexing.

To check for similar patterns elsewhere in the repo:

#!/bin/bash
# Find other EIP-related CEL rules using split() that may need the same fix
rg -n "eipalloc-|EIPAllocation" -C3
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml (2)

1158-1174: Fix issuerURL CEL: replace find() with matches() / contains()

The issuerURL validations still use self.find('#(.+)$') and self.find('@'), which are not part of the Kubernetes CEL environment and will cause the CRD to be rejected when applied. Use supported string predicates instead (and a safer query check):

   issuerURL:
@@
-                                  - message: must not have a query
-                                    rule: isURL(self) && url(self).getQuery() == {}
-                                  - message: must not have a fragment
-                                    rule: self.find('#(.+)$') == ''
-                                  - message: must not have user info
-                                    rule: self.find('@') == ''
+                                  - message: must not have a query
+                                    rule: isURL(self) && url(self).getQuery().size() == 0
+                                  - message: must not have a fragment
+                                    rule: !self.matches('.*#.+$')
+                                  - message: must not have user info
+                                    rule: !self.contains('@')

3702-3840: Require explicit subnets when eipAllocations is set on AWS NLB

You added good parity checks between subnets and eipAllocations, but they only run when subnets is explicitly specified. A user can still set eipAllocations with no subnets, which passes CRD validation even though the description says “The number of EIP allocations must match the number of subnets that are used for the load balancer.”

Add a guard so that whenever eipAllocations is set, subnets (ids or names) must also be explicitly non-empty:

                                       networkLoadBalancer:
@@
-                                        type: object
-                                        x-kubernetes-validations:
+                                        type: object
+                                        x-kubernetes-validations:
+                                        - message: subnets must be specified when eipAllocations is set
+                                          rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)
                                             && has(self.subnets.names) && has(self.eipAllocations)
                                             ? size(self.subnets.ids + self.subnets.names)
                                             == size(self.eipAllocations) : true'
@@
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.names)
                                             && !has(self.subnets.ids) && has(self.eipAllocations)
                                             ? size(self.subnets.names) == size(self.eipAllocations)
                                             : true'

Consider mirroring this rule in any other HostedCluster CRD variants that expose the same networkLoadBalancer schema.

Also applies to: 3989-3994

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml (1)

3200-3338: Still a validation gap: eipAllocations allowed without explicit subnets

As written, x-kubernetes-validations only enforce count equality when self.subnets is present. If a user sets eipAllocations but omits subnets (auto-discovery), all three rules short‑circuit to true, so the CRD admits configurations where the statement “the number of EIP allocations must match the number of subnets that are used for the load balancer” cannot be enforced at admission time. That likely pushes failures to reconciliation/provisioning.

Consider adding a guard that forces explicit subnets (with at least one id or name) whenever eipAllocations is set, for example:

-                                        x-kubernetes-validations:
+                                        x-kubernetes-validations:
+                                        - message: eipAllocations requires subnets to be set with ids or names
+                                          rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)
                                             && has(self.subnets.names) && has(self.eipAllocations)
                                             ? size(self.subnets.ids + self.subnets.names)
                                             == size(self.eipAllocations) : true'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.ids)
                                             && !has(self.subnets.names) && has(self.eipAllocations)
                                             ? size(self.subnets.ids) == size(self.eipAllocations)
                                             : true'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations
                                           rule: 'has(self.subnets) && has(self.subnets.names)
                                             && !has(self.subnets.ids) && has(self.eipAllocations)
                                             ? size(self.subnets.names) == size(self.eipAllocations)
                                             : true'

This keeps the existing equality checks but prevents eipAllocations with auto‑discovered subnets, which cannot be validated here.

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml (1)

3468-3545: CEL: list concatenation via self.ids + self.names / self.subnets.ids + self.subnets.names is invalid and will break CRD validation

Kubernetes CEL does not support + on lists, so rules like size(self.ids + self.names) and size(self.subnets.ids + self.subnets.names) will fail to type‑check. That makes the CRD (and any update touching these validations) invalid and effectively blocks admission. This was already flagged in a previous review and is still present here in:

  • aws.classicLoadBalancer.subnets.x-kubernetes-validations[0].rule
  • aws.networkLoadBalancer.subnets.x-kubernetes-validations[0].rule
  • aws.networkLoadBalancer.x-kubernetes-validations[0].rule (EIP parity with subnets)

Use the sum of list sizes instead of list concatenation.

Suggested patch:

@@
-                                            x-kubernetes-validations:
-                                            - message: the total number of subnets
-                                                cannot exceed 10
-                                              rule: 'has(self.ids) && has(self.names)
-                                                ? size(self.ids + self.names) <= 10
-                                                : true'
+                                            x-kubernetes-validations:
+                                            - message: the total number of subnets
+                                                cannot exceed 10
+                                              rule: 'has(self.ids) && has(self.names)
+                                                ? (size(self.ids) + size(self.names))
+                                                <= 10 : true'
@@
-                                            x-kubernetes-validations:
-                                            - message: the total number of subnets
-                                                cannot exceed 10
-                                              rule: 'has(self.ids) && has(self.names)
-                                                ? size(self.ids + self.names) <= 10
-                                                : true'
+                                            x-kubernetes-validations:
+                                            - message: the total number of subnets
+                                                cannot exceed 10
+                                              rule: 'has(self.ids) && has(self.names)
+                                                ? (size(self.ids) + size(self.names))
+                                                <= 10 : true'
@@
-                                        - message: number of subnets must be equal
-                                            to number of eipAllocations
-                                          rule: 'has(self.subnets) && has(self.subnets.ids)
-                                            && has(self.subnets.names) && has(self.eipAllocations)
-                                            ? size(self.subnets.ids + self.subnets.names)
-                                            == size(self.eipAllocations) : true'
+                                        - message: number of subnets must be equal
+                                            to number of eipAllocations
+                                          rule: 'has(self.subnets) && has(self.subnets.ids)
+                                            && has(self.subnets.names) && has(self.eipAllocations)
+                                            ? (size(self.subnets.ids) + size(self.subnets.names))
+                                            == size(self.eipAllocations) : true'

To double‑check after applying this, you can run kubectl apply -f <crd.yaml> (or the equivalent in CI) against a recent Kubernetes/OpenShift API server and confirm the CRD is accepted with no CEL compile errors.

Also applies to: 3590-3686

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml (1)

3112-3247: Consider requiring explicit subnets when eipAllocations is set

The parity checks between subnets and eipAllocations work when subnets is present, but the CRD still allows eipAllocations to be set with no explicit subnets, while the description says “number of EIP allocations must match the number of subnets used”. With auto-discovered subnets, that constraint can only be enforced at runtime and may lead to confusing failures.

If the intent is to only support EIPs when subnets are explicitly configured, a small CEL guard at networkLoadBalancer level would tighten the spec:

 networkLoadBalancer:
   type: object
   x-kubernetes-validations:
+  - message: eipAllocations requires explicit subnets configuration
+    rule: '!has(self.eipAllocations) || has(self.subnets)'
   - message: number of subnets must be equal
     to number of eipAllocations
     rule: 'has(self.subnets) && has(self.subnets.ids)
       && has(self.subnets.names) && has(self.eipAllocations)
       ? size(self.subnets.ids + self.subnets.names)
       == size(self.eipAllocations) : true'

If auto-discovery + EIPs is intentionally supported and validated elsewhere, then the current schema is acceptable.

api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml (2)

6415-6421: Fix typo in acceptedRisks description (“menition” → “mention”).

User‑facing text still contains the typo previously flagged; suggest correcting it:

-                            For example, it may menition an Upgradeable=False or missing signature
+                            For example, it may mention an Upgradeable=False or missing signature

3031-3250: Still missing: require explicit subnets when configuring NLB eipAllocations.

The new schema and count-parity validations for Classic/NLB subnets and eipAllocations look good, but eipAllocations can still be set without any subnets block at all. In that case, all three parity rules short‑circuit to true, so invalid configs like “EIPs set, relying on auto‑discovered subnets” are admitted, which can later fail during reconciliation/provisioning. This is the same gap called out in the earlier review on this file.

Add a networkLoadBalancer‑level x‑validation to require at least one subnet id or name whenever eipAllocations is present, e.g.:

                                       type: object
-                                       x-kubernetes-validations:
+                                       x-kubernetes-validations:
+                                       - message: subnets must be specified when eipAllocations is set
+                                         rule: '!has(self.eipAllocations) || (has(self.subnets) && ((has(self.subnets.ids) && self.subnets.ids.size() > 0) || (has(self.subnets.names) && self.subnets.names.size() > 0)))'
                                        - message: number of subnets must be equal
                                          to number of eipAllocations
                                          rule: 'has(self.subnets) && has(self.subnets.ids)
                                            && has(self.subnets.names) && has(self.eipAllocations)
                                            ? size(self.subnets.ids + self.subnets.names)
                                            == size(self.eipAllocations) : true'
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml (1)

3191-3330: NLB eipAllocations/subnets parity validations look good; consider also requiring subnets when eipAllocations is set

The new schema and CEL validations for AWS NLB:

  • Enforce EIP ID shape and length.
  • Enforce uniqueness in eipAllocations, ids, and names.
  • Ensure total ids + names ≤ 10 and at least one subnet when subnets is present.
  • Enforce 1:1 parity between subnets and eipAllocations for the three cases (ids+names, ids only, names only).

One behavioral detail: configs with eipAllocations but no explicit subnets (i.e., relying on auto-discovered subnets) still pass, because all parity rules guard on has(self.subnets). If the intent is that EIP mapping is only supported when subnets are explicitly specified (and not with auto-discovery), you may want an additional guard at the networkLoadBalancer level:

-                                        x-kubernetes-validations:
+                                        x-kubernetes-validations:
+                                        - message: subnets must be specified when eipAllocations is set
+                                          rule: '!has(self.eipAllocations) || has(self.subnets)'
                                         - message: number of subnets must be equal
                                             to number of eipAllocations

If auto-discovery + eipAllocations is an intentional and supported combination, then the current shape is fine; in that case, no change is required, but it might be worth double-checking controller behavior against this schema.

🧹 Nitpick comments (1)
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml (1)

3385-3481: NLB subnets / eipAllocations parity and scope checks mostly align with the docs, but allow EIPs without explicit subnets

The new rules correctly enforce:

  • duplicate-free ids/names with combined <= 10 subnets,
  • len(subnets) == len(eipAllocations) in all combinations of ids/names when both are present, and
  • forbidding eipAllocations when scope == Internal.

However, the schema currently permits eipAllocations to be set while omitting subnets entirely; that relies on controller-side logic to reconcile EIP count with auto-discovered subnets, even though the description states “The number of EIP allocations must match the number of subnets that are used for the load balancer.”

If you intend to require explicit subnets whenever eipAllocations is set, consider an additional guard such as:

x-kubernetes-validations:
  - message: eipAllocations require subnets to be explicitly specified
    rule: '!has(self.eipAllocations) || has(self.subnets)'

Also applies to: 3630-3635

Comment on lines +3157 to +3168
description: AWSSubnetName is a
reference to an AWS subnet name.
maxLength: 256
minLength: 1
type: string
x-kubernetes-validations:
- message: subnet name cannot contain
a comma
rule: '!self.contains('','')'
- message: subnet name cannot start
with 'subnet-'
rule: '!self.startsWith(''subnet-'')'

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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check if the file exists and examine the relevant sections
if [ -f "api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml" ]; then
  echo "=== Lines 3157-3168 ===" 
  sed -n '3157,3168p' "api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml" | cat -n
  echo ""
  echo "=== Lines 3278-3289 ===" 
  sed -n '3278,3289p' "api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml" | cat -n
else
  echo "File not found - searching for similar generated files..."
  find . -name "*OpenStack.yaml" -type f 2>/dev/null | head -5
fi

Repository: openshift/hypershift

Length of output: 287


🏁 Script executed:

# Search for the specific CEL rule pattern to find all occurrences
echo "=== Searching for contains('','') pattern ===" 
rg "contains\('',''\)" --type yaml -A 1 -B 1

Repository: openshift/hypershift

Length of output: 287


🌐 Web query:

CEL (Common Expression Language) string contains method syntax validation

💡 Result:

Short answer: CEL uses a string instance method syntax x.contains(y) (and also x.startsWith(y), x.endsWith(y)); you can also use the infix operator "in" for membership tests on lists. The contains form expects x and y to be strings (returns a boolean) and matches when y is a substring of x. Example: "hello world".contains("world") == true. [1][2][3]

Notes for validation:

  • Use the instance-method form: .contains(). [2][3]
  • Both operands must be string-typed (or cast to string) for substring checks. [2][6]
  • For list membership use: item in list. [1][3]

Sources:
[1] Kubernetes CEL overview and examples (string/CIDR libraries).
[2] Google Cloud CEL matcher language reference (x.contains, startsWith, endsWith).
[3] CEL examples showing "one-more-group".contains("more").


🌐 Web query:

CEL Kubernetes validation rules string.contains comma example

💡 Result:

Example: use the string contains method in a CEL validation expression to check for a comma.

ValidatingAdmissionPolicy / CRD validation rule example (check that spec.tags contains a comma):

  • Rule (CEL): self.spec.tags.contains(",")

  • As a CRD x-kubernetes-validations example:

    rule: |
    self.spec.tags.contains(",")
    message: 'spec.tags must include a comma-separated list.'

Or as a ValidatingAdmissionPolicy validation expression:

spec:
validations:
- expression: 'object.spec.tags.contains(",")'
messageExpression: '"spec.tags must contain a comma."'

Notes:

  • Kubernetes CEL supports string methods such as contains; CEL regex helpers (find/findAll/matches) are also available if you need more complex checks. (kubernetes.io)

If you want, I can show a full CRD snippet or a regex-based alternative (e.g., to require at least two items).

Citations:


Fix CEL rule for "subnet name cannot contain a comma" in both classic/NLB schemas

The current rule !self.contains('','') is invalid CEL syntax: the contains() method expects a single string argument, not two. This will cause validation to fail or be skipped.

Change both occurrences (classic and network NLB AWSSubnetName validators) to:

-                                                  - message: subnet name cannot contain
-                                                      a comma
-                                                    rule: '!self.contains('','')'
+                                                  - message: subnet name cannot contain
+                                                      a comma
+                                                    rule: "!self.contains(',')"

And similarly for the names validator under networkLoadBalancer.subnets.

Also applies to: 3278-3289

🤖 Prompt for AI Agents
In
api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
around lines 3157-3168 (and similarly the block at 3278-3289), the CEL rule for
"subnet name cannot contain a comma" is invalid because it uses contains with
two arguments; replace the invalid rule with a single-argument contains check
(negated) so it becomes a valid CEL expression that tests for a comma (i.e., use
!self.contains(',') in both the AWSSubnetName validators and the names validator
under networkLoadBalancer.subnets), preserving surrounding YAML quoting/escaping
as needed.

@openshift-ci-robot

Copy link
Copy Markdown

/retest-required

Remaining retests: 0 against base HEAD 400c97a and 2 for PR HEAD a854d0b in total

@openshift-ci-robot

Copy link
Copy Markdown

/retest-required

Remaining retests: 0 against base HEAD 2b5822c and 1 for PR HEAD a854d0b in total

@csrwng

csrwng commented Dec 16, 2025

Copy link
Copy Markdown
Contributor Author

/override ci/prow/okd-scos-images

@openshift-ci

openshift-ci Bot commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

@csrwng: Overrode contexts on behalf of csrwng: ci/prow/okd-scos-images

Details

In response to this:

/override ci/prow/okd-scos-images

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.

@csrwng

csrwng commented Dec 16, 2025

Copy link
Copy Markdown
Contributor Author

The okd-scos-images failure does not look like it's related to this bump

@openshift-ci-robot

Copy link
Copy Markdown

/retest-required

Remaining retests: 0 against base HEAD 4d0a522 and 0 for PR HEAD a854d0b in total

@csrwng

csrwng commented Dec 16, 2025

Copy link
Copy Markdown
Contributor Author

/override ci/prow/okd-scos-images

@openshift-ci

openshift-ci Bot commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

@csrwng: Overrode contexts on behalf of csrwng: ci/prow/okd-scos-images

Details

In response to this:

/override ci/prow/okd-scos-images

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.

@openshift-ci-robot

Copy link
Copy Markdown

/hold

Revision a854d0b was retested 3 times: holding

@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 Dec 16, 2025
@csrwng

csrwng commented Dec 17, 2025

Copy link
Copy Markdown
Contributor Author

/hold cancel
/override ci/prow/e2e-aws-4-21

The e2e-aws-4-21 job passed earlier today for this PR. However, recent runs have either failed to build a proper release or failed in a network policy check.

@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 Dec 17, 2025
@openshift-ci

openshift-ci Bot commented Dec 17, 2025

Copy link
Copy Markdown
Contributor

@csrwng: Overrode contexts on behalf of csrwng: ci/prow/e2e-aws-4-21

Details

In response to this:

/hold cancel
/override ci/prow/e2e-aws-4-21

The e2e-aws-4-21 job passed earlier today for this PR. However, recent runs have either failed to build a proper release or failed in a network policy check.

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.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 88e53d2 into openshift:main Dec 17, 2025
22 checks passed
@openshift-ci-robot

Copy link
Copy Markdown

@csrwng: Jira Issue OCPBUGS-66211: Some pull requests linked via external trackers have merged:

The following pull request, linked via external tracker, has not merged:

All associated pull requests must be merged or unlinked from the Jira bug in order for it to move to the next state. Once unlinked, request a bug refresh with /jira refresh.

Jira Issue OCPBUGS-66211 has not been moved to the MODIFIED state.

This PR is marked as verified. If the remaining PRs listed above are marked as verified before merging, the issue will automatically be moved to VERIFIED after all of the changes from the PRs are available in an accepted nightly payload.

Details

In response to this:

What this PR does / why we need it:

This updates the OpenShift API dependencies to the current master branch versions as of 2025-12-04.

Key dependency changes:

  • github.com/openshift/api: v0.0.0-20251204193610-68ce3d906ec8
  • Updated all related OpenShift API modules to matching versions
  • Updated code generation tools in hack/tools/go.mod to v0.34.1

Code changes made to accommodate API updates:

  • Fixed etcd v3.6.4 compatibility in pkg/etcdcli/etcdcli.go
  • Updated OpenShift authentication API usage in auth tests
  • Migrated client-go testing utilities to new managedfields API
  • Updated structured-merge-diff from v4 to v6 in client code
  • Fixed etcd integration test API changes
  • Regenerated client code using updated tools
  • Fixed CEL API deprecation by migrating from cel.Declarations to cel.Variable
  • Added nolint suppressions for backward compatibility with deprecated APIs

🤖 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 commented Dec 17, 2025

Copy link
Copy Markdown
Contributor

@csrwng: 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/okd-scos-images a854d0b link unknown /test okd-scos-images
ci/prow/e2e-aws-4-21 a854d0b link unknown /test e2e-aws-4-21

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

acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. approved Indicates a PR has been approved by an approver from all required OWNERS files. area/api Indicates the PR includes changes for the API area/ci-tooling Indicates the PR includes changes for CI or tooling area/cli Indicates the PR includes changes for CLI area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/control-plane-pki-operator Indicates the PR includes changes for the control plane PKI operator - in an OCP release area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/aws PR/issue for AWS (AWSPlatform) platform area/platform/azure PR/issue for Azure (AzurePlatform) platform area/platform/gcp PR/issue for GCP (GCPPlatform) platform area/platform/kubevirt PR/issue for KubeVirt (KubevirtPlatform) platform area/platform/none PR/issue for None (NonePlatform) platform - user-supplied infrastructure area/platform/openstack PR/issue for OpenStack (OpenStackPlatform) platform area/platform/powervs PR/issue for PowerVS (PowerVSPlatform) platform area/testing Indicates the PR includes changes for e2e testing jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants