Skip to content

Bug OCPBUGS-97953: installer: fix NetworkDeviceSpec CRD incorrectly using format: ipv6#10673

Open
ankimaha-sys wants to merge 1 commit into
openshift:mainfrom
ankimaha-sys:fix-vsphere-networkdevice-ipv6-format
Open

Bug OCPBUGS-97953: installer: fix NetworkDeviceSpec CRD incorrectly using format: ipv6#10673
ankimaha-sys wants to merge 1 commit into
openshift:mainfrom
ankimaha-sys:fix-vsphere-networkdevice-ipv6-format

Conversation

@ankimaha-sys

@ankimaha-sys ankimaha-sys commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

The NetworkDeviceSpec fields (gateway, ipAddrs, nameservers) in pkg/types/vsphere/platform.go had both +kubebuilder:validation:Format=ipv4 and +kubebuilder:validation:Format=ipv6 markers. Since controller-gen only keeps the last marker, the generated CRD schema ended up with format: ipv6, causing valid IPv4 addresses (e.g., 192.168.1.1, 8.8.8.8) to be rejected.

This PR removes the Format markers from these three fields so both IPv4 and IPv6 addresses are accepted. The field descriptions already document the expected input formats.

A Format=ip marker was considered but is not suitable because ipAddrs accepts CIDR notation (e.g., 192.168.1.100/24), which is not a valid IP address format.

Fixes #10377

Discovered via: openshift/hive#2851 (comment)

Changes

  • pkg/types/vsphere/platform.go: Remove +kubebuilder:validation:Format=ipv4 and +kubebuilder:validation:Format=ipv6 from gateway, ipAddrs, and nameservers fields in NetworkDeviceSpec
  • data/data/install.openshift.io_installconfigs.yaml: Remove generated format: ipv6 from the corresponding CRD schema fields

Verification

The generated CRD YAML was updated to match the marker changes. The pkg/asset/store/data/ copy is a hardlink to data/data/ and is updated automatically.

Summary by CodeRabbit

  • Bug Fixes
    • Improved network device CRD validation by switching to stricter CEL-based rules for networking fields.
    • Gateway can be empty, or must be a valid IP address.
    • ipAddrs now requires every entry to be a valid CIDR.
    • nameservers now requires every entry to be a valid IP address.
  • Tests
    • Added additional test coverage for IPv6 static IP validation and related error messaging.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

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

Updates vSphere NetworkDeviceSpec validation to use CEL rules for gateway, ipAddrs, and nameservers, and adds tests for IPv6, empty gateway, and invalid nameserver cases.

Changes

vSphere NetworkDeviceSpec validation

Layer / File(s) Summary
Schema rules
pkg/types/vsphere/platform.go
Gateway accepts empty or any IP, IPAddrs requires CIDR values, and Nameservers requires IP values via CEL validation.
Validation tests
pkg/types/vsphere/validation/platform_test.go
Static IP test cases cover IPv6 nameservers, invalid nameservers, empty gateway, and IPv6 CIDR ipAddrs.

Estimated code review effort: 2 (Simple) | ~10 minutes

Related issues: Fixes vSphere NetworkDeviceSpec CRD schema incorrectly uses format: ipv6 for fields that should accept both IPv4 and IPv6 (#10377)

Suggested labels: api-review, vsphere

Suggested reviewers: 2uasimojo

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The source fix matches the issue, but the generated CRD YAML is excluded so the final schema output can't be verified. Please expose or include data/data/install.openshift.io_installconfigs.yaml in review so the generated schema change can be verified.
✅ Passed checks (14 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed Changes stay within NetworkDeviceSpec validation and tests, with no unrelated edits visible.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Stable And Deterministic Test Names ✅ Passed The changed tests use static table-driven names only; no Ginkgo/It/Context titles contain dynamic values, IP literals, timestamps, or generated suffixes.
Test Structure And Quality ✅ Passed Changed tests are plain table-driven unit cases; each new case targets one validation behavior, with no cluster setup, cleanup, or waits involved.
Microshift Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; the changed test is a plain Go unit test and references no MicroShift-unsupported APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the only changed test file is a standard Go unit test with no SNO-sensitive assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed Only CRD validation and unit tests changed; no deployments, controllers, affinity, nodeSelector, PDB, or topology logic were added.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes were added. The only fmt.Printf is inside a t.Run test case, and no TestMain/init/suite hooks exist in the touched package.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Added tests are plain Go unit tests, not Ginkgo e2e, and the new cases use IPv6/local validation only.
No-Weak-Crypto ✅ Passed Touched files only adjust vSphere network validation; no MD5/SHA1/DES/RC4/3DES/ECB, custom crypto, or secret comparisons were present.
Container-Privileges ✅ Passed The PR only changes NetworkDeviceSpec validation and tests/CRD schema; targeted searches in changed files found no privileged, hostNetwork, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed No new logging was added in the PR diff; touched validation code and tests contain no sensitive-data logs.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the core fix: correcting the vSphere NetworkDeviceSpec CRD's invalid IPv6-only validation.
✨ 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.

@openshift-ci

openshift-ci Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

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

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

@openshift-ci openshift-ci Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jul 6, 2026
@openshift-ci

openshift-ci Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Hi @ankimaha-sys. Thanks for your PR.

I'm waiting for a openshift member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

// +kubebuilder:validation:Format=ipv6
// +kubebuilder:example=`192.168.1.100/24`
// +kubebuilder:example=`2001:DB8:0000:0000:244:17FF:FEB6:D37D/64`
// +kubebuilder:validation:Required

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.

Some level of validation is required, just removing and not replacing won't work here

@jcpowermac

jcpowermac commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

this instead...

// Accepts strings like "192.168.1.50/24" or "2001:db8::1/64"
// +kubebuilder:validation:XValidation:rule="isCIDR(self)",message="Must be a valid IP address and prefix length separated by a slash (e.g., 192.168.1.50/24)"
HostSubnet string `json:"hostSubnet,omitempty"`

this is from gemini, you need to test this

@ankimaha-sys ankimaha-sys force-pushed the fix-vsphere-networkdevice-ipv6-format branch from 0cb3220 to 6dd43cd Compare July 6, 2026 14:45
@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback @jcpowermac! Updated to replace the broken Format markers with CEL XValidation rules instead of removing validation entirely:

  • gateway: isIP(self) — validates plain IPv4/IPv6 addresses
  • ipAddrs: isCIDR() via self.all(x, isCIDR(x)) — validates CIDR notation (e.g. 192.168.1.100/24)
  • nameservers: isIP() via self.all(x, isIP(x)) — validates plain IPv4/IPv6 addresses

Updated the generated CRD YAML as well.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
pkg/types/vsphere/platform.go (1)

340-340: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider bounding array size for CEL cost estimation.

self.all(x, isCIDR(x))/self.all(x, isIP(x)) iterate over ipAddrs/nameservers, but neither field declares maxItems. Kubernetes' CRD Validation Rules guidance recommends setting maxItems/maxLength on all array/string fields used in CEL rules to keep the estimated cost bounded. Given NetworkDeviceSpec is nested under a list of hosts, an unbounded inner list technically compounds the estimated cost, though with the small expected list sizes here (a handful of nameservers/IPs per host) this is unlikely to hit real limits in practice.

Also applies to: 349-349

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

In `@pkg/types/vsphere/platform.go` at line 340, The CEL validation on
NetworkDeviceSpec’s ipAddrs and nameservers fields uses self.all(...) without
any array size bound, so add maxItems to both array definitions and keep the
existing XValidation rules intact. Update the relevant field declarations in
platform.go near NetworkDeviceSpec so Kubernetes can estimate CEL cost safely
while preserving the CIDR/IP checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/types/vsphere/platform.go`:
- Line 340: The CEL validation on NetworkDeviceSpec’s ipAddrs and nameservers
fields uses self.all(...) without any array size bound, so add maxItems to both
array definitions and keep the existing XValidation rules intact. Update the
relevant field declarations in platform.go near NetworkDeviceSpec so Kubernetes
can estimate CEL cost safely while preserving the CIDR/IP checks.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 9115fed7-8bcb-4730-a6c4-00db34ca051c

📥 Commits

Reviewing files that changed from the base of the PR and between 0cb3220 and 6dd43cd.

⛔ Files ignored due to path filters (1)
  • data/data/install.openshift.io_installconfigs.yaml is excluded by !data/data/install.openshift.io_installconfigs.yaml
📒 Files selected for processing (1)
  • pkg/types/vsphere/platform.go

@jcpowermac

Copy link
Copy Markdown
Contributor

/test ?

@jcpowermac

Copy link
Copy Markdown
Contributor

/test e2e-vsphere-static-ovn

@jcpowermac

Copy link
Copy Markdown
Contributor

/ok-to-test

@openshift-ci openshift-ci Bot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jul 6, 2026
@jcpowermac

Copy link
Copy Markdown
Contributor

🧹 Nitpick comments (1)

pkg/types/vsphere/platform.go (1)> 340-340: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider bounding array size for CEL cost estimation.
self.all(x, isCIDR(x))/self.all(x, isIP(x)) iterate over ipAddrs/nameservers, but neither field declares maxItems. Kubernetes' CRD Validation Rules guidance recommends setting maxItems/maxLength on all array/string fields used in CEL rules to keep the estimated cost bounded. Given NetworkDeviceSpec is nested under a list of hosts, an unbounded inner list technically compounds the estimated cost, though with the small expected list sizes here (a handful of nameservers/IPs per host) this is unlikely to hit real limits in practice.
Also applies to: 349-349

🤖 Prompt for AI Agents

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

In `@pkg/types/vsphere/platform.go` at line 340, The CEL validation on
NetworkDeviceSpec’s ipAddrs and nameservers fields uses self.all(...) without
any array size bound, so add maxItems to both array definitions and keep the
existing XValidation rules intact. Update the relevant field declarations in
platform.go near NetworkDeviceSpec so Kubernetes can estimate CEL cost safely
while preserving the CIDR/IP checks.

🤖 Prompt for all review comments with AI agents

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

Nitpick comments:
In `@pkg/types/vsphere/platform.go`:
- Line 340: The CEL validation on NetworkDeviceSpec’s ipAddrs and nameservers
fields uses self.all(...) without any array size bound, so add maxItems to both
array definitions and keep the existing XValidation rules intact. Update the
relevant field declarations in platform.go near NetworkDeviceSpec so Kubernetes
can estimate CEL cost safely while preserving the CIDR/IP checks.

ℹ️ Review info

@ankimaha-sys please review ^

@ankimaha-sys ankimaha-sys force-pushed the fix-vsphere-networkdevice-ipv6-format branch from 6dd43cd to 3094cad Compare July 6, 2026 19:12
@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

Added maxItems=10 to both ipAddrs and nameservers to bound the CEL cost estimation for self.all(...) rules.

@ankimaha-sys ankimaha-sys force-pushed the fix-vsphere-networkdevice-ipv6-format branch from 3094cad to a7a0b0a Compare July 6, 2026 19:34
@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

/retest-required

@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

/retest

Comment thread pkg/types/vsphere/platform.go Outdated
// +kubebuilder:validation:Format=ipv4
// +kubebuilder:validation:Format=ipv6
// +kubebuilder:validation:XValidation:rule="self.all(x, isIP(x))",message="each nameserver must be a valid IPv4 or IPv6 address"
// +kubebuilder:validation:MaxItems=10

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.

10 seems excessive for nameservers, and I thought there was a maximum anyway

@jcpowermac

Copy link
Copy Markdown
Contributor

@ankimaha-sys there are no unit tests, there probably should be some

@ankimaha-sys ankimaha-sys changed the title installer: fix NetworkDeviceSpec CRD incorrectly using format: ipv6 Bug OCPBUGS-97953: installer: fix NetworkDeviceSpec CRD incorrectly using format: ipv6 Jul 7, 2026
@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 7, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@ankimaha-sys: This pull request references Jira Issue OCPBUGS-97953, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

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.

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

Details

In response to this:

Summary

The NetworkDeviceSpec fields (gateway, ipAddrs, nameservers) in pkg/types/vsphere/platform.go had both +kubebuilder:validation:Format=ipv4 and +kubebuilder:validation:Format=ipv6 markers. Since controller-gen only keeps the last marker, the generated CRD schema ended up with format: ipv6, causing valid IPv4 addresses (e.g., 192.168.1.1, 8.8.8.8) to be rejected.

This PR removes the Format markers from these three fields so both IPv4 and IPv6 addresses are accepted. The field descriptions already document the expected input formats.

A Format=ip marker was considered but is not suitable because ipAddrs accepts CIDR notation (e.g., 192.168.1.100/24), which is not a valid IP address format.

Fixes #10377

Discovered via: openshift/hive#2851 (comment)

Changes

  • pkg/types/vsphere/platform.go: Remove +kubebuilder:validation:Format=ipv4 and +kubebuilder:validation:Format=ipv6 from gateway, ipAddrs, and nameservers fields in NetworkDeviceSpec
  • data/data/install.openshift.io_installconfigs.yaml: Remove generated format: ipv6 from the corresponding CRD schema fields

Verification

The generated CRD YAML was updated to match the marker changes. The pkg/asset/store/data/ copy is a hardlink to data/data/ and is updated automatically.

Made with Cursor

Summary by CodeRabbit

  • Bug Fixes
  • Improved network device CRD validation to strengthen network input checking.
  • Gateway can now be empty, or must be a valid IP address.
  • ipAddrs entries are validated as valid CIDRs (e.g., 192.168.1.100/24).
  • nameservers entries are validated as valid IP addresses.
  • Enhances correctness and helps prevent unsafe or invalid network configurations.

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.

@ankimaha-sys ankimaha-sys force-pushed the fix-vsphere-networkdevice-ipv6-format branch from 666d7a0 to fcadbcd Compare July 7, 2026 16:11
@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@ankimaha-sys: This pull request references Jira Issue OCPBUGS-97953, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

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:

/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.

@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 7, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

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

@jcpowermac

Copy link
Copy Markdown
Contributor

Request: Add a unit test that asserts the generated CRD schema for the vSphere NetworkDeviceSpec fields

The new tests in platform_test.go only exercise the Go validation path in validateHostNetworking() — that code was never broken and already handled IPv4/IPv6 correctly. The actual bug was in the CRD schema (format: ipv6 rejecting IPv4 addresses), and the actual fix is the CEL rules replacing it. Nothing in this PR tests that the CRD contains the correct validation rules.

Please add a test in pkg/types/vsphere/validation/platform_test.go (or a new crd_test.go in that package) that loads and parses the CRD YAML and asserts the NetworkDeviceSpec schema fields have the expected CEL validation rules and no leftover format constraints.

Implementation details:

  1. Load the CRD YAML from data/data/install.openshift.io_installconfigs.yaml (there's an existing example of this in pkg/explain/data_test.go:loadCRD()). Relative path from pkg/types/vsphere/validation/ would be ../../../../data/data/install.openshift.io_installconfigs.yaml.

  2. Unmarshal into apiextensionsv1.CustomResourceDefinition from k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 (already vendored).

  3. Navigate the schema tree to NetworkDeviceSpec. The path from the root openAPIV3Schema is:

    .Properties["platform"]
    .Properties["vsphere"]
    .Properties["hosts"]
    .Items.Schema.Properties["networkDevice"]
    .Properties["gateway" | "ipAddrs" | "nameservers"]
    

    Note: the CRD schema is flat (no spec wrapper) — platform is a top-level property.

  4. Assert for each field:

    • gateway: Format is empty (no format: ipv6), has exactly 1 XValidation rule with Rule: "self == '' || isIP(self)" and a non-empty Message.
    • ipAddrs: Format is empty, has exactly 1 XValidation rule with Rule: "self.all(x, isCIDR(x))", and MaxItems is int64(10).
    • nameservers: Format is empty, has exactly 1 XValidation rule with Rule: "self.all(x, isIP(x))", and MaxItems is int64(3).
  5. Use require/assert from github.com/stretchr/testify (already used in the existing test file).

Why this matters: The original bug was controller-gen silently keeping only the last of two duplicate Format markers. A test that asserts the CRD schema output would have caught that. Without this test, a future marker change could silently regress the CRD again, and the Go-side tests would not notice because they test a completely separate validation path.

Additional note on maxItems: The PR adds maxItems: 10 to ipAddrs in the CRD via +kubebuilder:validation:MaxItems=10, but the Go validation in validateHostNetworking() has no corresponding limit for ipAddrs (it only limits nameservers to 3). This means the CRD and Go validation can diverge — the CRD rejects >10 ipAddrs but the installer's own validation accepts any count. Consider adding a Go-side check for consistency, or at minimum document the intentional difference.

The NetworkDeviceSpec gateway, ipAddrs, and nameservers fields had both
+kubebuilder:validation:Format=ipv4 and Format=ipv6 markers. Since
controller-gen only keeps the last marker, the generated CRD schema
used format: ipv6, causing valid IPv4 addresses to be rejected.

Remove the format markers from these fields so both IPv4 and IPv6
addresses are accepted.

Fixes: openshift#10377
Signed-off-by: Ankit Mahajan <ankimaha@redhat.com>
@ankimaha-sys ankimaha-sys force-pushed the fix-vsphere-networkdevice-ipv6-format branch from fcadbcd to e0d242e Compare July 7, 2026 20:00
@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

Thanks @jcpowermac! Addressed both points:

  1. Fixed nameservers maxItems from 10 to 3, matching the existing Go validation limit in validateHostNetworking().
  2. Added CRD schema test (TestCRDNetworkDeviceSpec in crd_test.go) that loads the generated CRD YAML and asserts:
    • gateway: no format constraint, CEL rule self == '' || isIP(self)
    • ipAddrs: no format constraint, CEL rule self.all(x, isCIDR(x)), maxItems=10
    • nameservers: no format constraint, CEL rule self.all(x, isIP(x)), maxItems=3

This ensures any future marker regression in the CRD schema will be caught by tests.

Force-pushed with the squashed commit. go generate and go test both pass locally.

@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

/retest

@openshift-ci

openshift-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

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

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-ovn e0d242e link true /test e2e-aws-ovn
ci/prow/e2e-vsphere-ovn-devpreview e0d242e link false /test e2e-vsphere-ovn-devpreview

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.

assert.Equal(t, int64(3), *ns.MaxItems)
}
})
}

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.

The current tests only verify the CRD schema structure (that the CEL rule string is "self.all(x, isCIDR(x))", that format is empty, etc.). They never feed actual IP addresses or CIDRs through validation, so they would pass even if the CEL rules silently accepted garbage — or rejected valid input, which is the exact bug this PR fixes.

Add behavioral validation tests that exercise the CEL rules with real values. This confirms the fix end-to-end: valid IPv4 and IPv6 addresses are accepted, and invalid strings are rejected.

What to add

Add a new test function (e.g. TestCRDNetworkDeviceCELValidation) in the same file that uses apiextensions-apiserver's CEL evaluation to test the rules extracted from the CRD schema. At minimum, cover these cases:

gateway (rule: self == '' || isIP(self)):

Input Expected
"" pass
"192.168.1.1" pass
"2001:db8::1" pass
"not-an-ip" fail
"192.168.1.0/24" fail (CIDR, not bare IP)

ipAddrs (rule: self.all(x, isCIDR(x))):

Input Expected
["192.168.1.100/24"] pass
["2001:db8::1/64"] pass
["192.168.1.100/24", "2001:db8::1/64"] pass (mixed families)
["192.168.1.1"] fail (bare IP, no prefix length)
["not-a-cidr"] fail

nameservers (rule: self.all(x, isIP(x))):

Input Expected
["8.8.8.8"] pass
["2001:4860:4860::8888"] pass
["8.8.8.8", "2001:4860:4860::8888"] pass (mixed families)
["not-an-ip"] fail
["8.8.8.8/32"] fail (CIDR, not bare IP)

Implementation guidance

Use k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel to compile and evaluate the XValidation rules against the field's JSONSchemaProps. The cel.NewValidator or cel.Compile functions accept the schema and return a validator you can call with test values. Wrap the cases in a table-driven test. The existing loadCRD and networkDeviceSchema helpers can be reused to extract the schema and rules.

If the CEL evaluation dependency is too heavy, an acceptable alternative is to shell out to kubectl apply --dry-run=server against a kind cluster, but the in-process CEL approach is preferred since it requires no external dependencies and matches the existing test style.

🤖 Prompt for AI Agents

In pkg/types/vsphere/validation/crd_test.go, add a new TestCRDNetworkDeviceCELValidation test function that evaluates the CEL XValidation rules from the CRD schema against actual IP addresses and CIDRs. Use the k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel package to compile and run the rules in-process. Reuse the existing loadCRD and networkDeviceSchema helpers to extract the schema. Structure as a table-driven test with subtests for each field (gateway, ipAddrs, nameservers). For each field, test both valid inputs (IPv4, IPv6, mixed dual-stack) and invalid inputs (malformed strings, wrong format like CIDR where bare IP is expected and vice versa). Assert that valid inputs produce zero validation errors and invalid inputs produce at least one. See the test case tables in this comment for the minimum required coverage.

@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

/retest-failed

@ankimaha-sys

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed feedback @jcpowermac! I looked into adding behavioral CEL tests as you described.

The CEL evaluation packages (github.com/google/cel-go and k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel) are not currently vendored in the installer. Adding them would pull in a significant dependency chain just for this test.

A few options:

  1. Vendor the CEL deps in this PR — adds the behavioral tests but increases the vendor diff significantly.
  2. Keep the structural CRD test for now, add behavioral CEL tests as a follow-up once the CEL deps are vendored (could be useful for other CRD validation tests too).
  3. Add Go-equivalent behavioral tests using net.ParseIP/net.ParseCIDR to validate the same inputs — doesn't test the actual CEL rules but confirms the validation logic is correct.

What approach would you prefer?

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

Labels

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. ok-to-test Indicates a non-member PR verified by an org member that is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vsphere NetworkDeviceSpec: CRD schema incorrectly uses format: ipv6 for fields that should accept both IPv4 and IPv6

3 participants