Skip to content

Conversation

@ricky-rav
Copy link

@ricky-rav ricky-rav commented Oct 17, 2025

Related openshift enhancement: openshift/enhancements#1859

@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 Oct 17, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 17, 2025

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

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 17, 2025

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

@openshift-ci openshift-ci bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Oct 17, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 17, 2025

[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 joelspeed 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

@JoelSpeed
Copy link
Contributor

@ricky-rav Is this ready for an initial round of API review?

@ricky-rav
Copy link
Author

ricky-rav commented Oct 22, 2025

@ricky-rav Is this ready for an initial round of API review?

No no, it was just a draft for myself to keep track of the API changes in an enhancement I'm writing. I think @pliurh is taking over the API part of the feature.

@openshift-ci openshift-ci bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Nov 17, 2025
@ricky-rav ricky-rav changed the title [WIP] API for no-overlay mode in OVN-Kubernetes [WIP] API changes and feature gate for OVN-Kubernetes no-overlay mode Nov 17, 2025
@ricky-rav ricky-rav changed the title [WIP] API changes and feature gate for OVN-Kubernetes no-overlay mode CORENET-6390: API changes and feature gate for OVN-Kubernetes no-overlay mode Nov 17, 2025
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Nov 17, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 17, 2025

@ricky-rav: This pull request references CORENET-6390 which is a valid jira issue.

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

Details

In response to this:

Using this as draft for the related openshift enhancement: openshift/enhancements#1859

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.

@ricky-rav ricky-rav force-pushed the no_overlay_api branch 2 times, most recently from 905c086 to 00fcda8 Compare November 24, 2025 11:10
@coderabbitai
Copy link

coderabbitai bot commented Nov 24, 2025

📝 Walkthrough

Walkthrough

Adds the NoOverlayMode feature gate and registers FeatureGateNoOverlayMode. Introduces API types and enums: TransportOption, SNATOption, RoutingOption, BGPTopology, NoOverlayOptions, BGPManagedConfig (with constants and fields), and updates OVNKubernetesConfig with DefaultNetworkTransport, DefaultNetworkNoOverlayOptions, and BGPManagedConfig including validation and immutability rules. Generates OpenAPI, swagger, and deepcopy artifacts. Adds a CRD test manifest exercising create/update validations for NoOverlayMode. Updates payload feature-gate manifests: NoOverlayMode enabled in TechPreviewNoUpgrade for Hypershift and SelfManagedHA; added as disabled in Default, DevPreviewNoUpgrade, and OKD profiles; features.md row added.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding API changes and a feature gate for OVN-Kubernetes no-overlay mode, which aligns with the actual changeset modifications.
Description check ✅ Passed The description provides a reference to the related OpenShift enhancement PR, which is relevant context for the changeset focused on no-overlay mode API changes.

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

✨ Finishing touches
  • 📝 Generate docstrings

Warning

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

🔧 golangci-lint (2.5.0)

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


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

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 24, 2025
@ricky-rav ricky-rav force-pushed the no_overlay_api branch 2 times, most recently from 8192eb2 to d973281 Compare November 25, 2025 09:52
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 25, 2025
@ricky-rav ricky-rav force-pushed the no_overlay_api branch 3 times, most recently from 90914d8 to 73d3699 Compare November 27, 2025 16:01
@ricky-rav
Copy link
Author

/test all

@ricky-rav
Copy link
Author

/test all

@yuqi-zhang
Copy link
Contributor

Just wanted to check back in, is this something you're actively pursuing and ready for review? https://issues.redhat.com/browse/CORENET-5652 seems to not be targetting 4.22 at this time.

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 6, 2026
@ricky-rav
Copy link
Author

Just wanted to check back in, is this something you're actively pursuing and ready for review? https://issues.redhat.com/browse/CORENET-5652 seems to not be targetting 4.22 at this time.

We're targeting 4.22 for this effort. We plan to do first a round of reviews from team members and then we'll ask you or Joel to chime in. Thanks!

@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 7, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml:
- Around line 148-174: The test expects bgpManagedConfig to be fully immutable
but the API only makes BGPManagedConfig.BGPTopology immutable; to fix this add a
field-level onUpdate XValidation on OVNKubernetesConfig.bgpManagedConfig
(similar to the existing NoOverlayOptions immutability validation) that compares
self to oldSelf and returns the message "bgpManagedConfig field is immutable" so
any change (including ASNumber) is rejected; update the CRD validation for
OVNKubernetesConfig to include that XValidation and re-run tests.

In @operator/v1/types_network.go:
- Around line 993-1013: Tests expect the entire bgpManagedConfig field to be
immutable but the current type BGPManagedConfig only enforces immutability on
the BGPTopology field via the XValidation on BGPTopology; update the API to
match tests by adding a struct-level XValidation rule on BGPManagedConfig (e.g.,
an XValidation with rule "self == oldSelf" and a clear message) to make the
whole bgpManagedConfig immutable once set, or alternatively align the tests to
only require BGPTopology immutability—modify either the BGPManagedConfig
definition (add struct-level immutability) or the tests to match the existing
field-level behavior.
- Around line 482-508: The BGPManagedConfig field on OVNKubernetesConfig is
currently mutable but tests expect it to be immutable; add the same struct-level
XValidation used for DefaultNetworkNoOverlayOptions to BGPManagedConfig to
enforce set-once semantics: add a kubebuilder XValidation rule on the
BGPManagedConfig field with rule="!oldSelf.hasValue() || self ==
oldSelf.value()", message="bgpManagedConfig field is immutable", and
optionalOldSelf=true, keeping the existing +optional and json tag for
BGPManagedConfig so the API prevents post-creation changes to the
BGPManagedConfig object.
🧹 Nitpick comments (1)
operator/v1/types_network.go (1)

972-991: Required fields marked with omitempty are acceptable but slightly counterintuitive

NoOverlayOptions marks OutboundSNAT and Routing as:

  • +required and enum-constrained, but
  • JSON-tagged with omitempty.

Because the CRD declares these properties as required, clients must send them; the server will reject absent fields regardless of omitempty, so behavior is correct. However, the omitempty on required fields can be surprising to readers and generated clients.

Optional (style) tweak if you want stricter alignment between Go tags and schema:

-OutboundSNAT SNATOption `json:"outboundSNAT,omitempty"`
+OutboundSNAT SNATOption `json:"outboundSNAT"`
...
-Routing RoutingOption `json:"routing,omitempty"`
+Routing RoutingOption `json:"routing"`

Not strictly necessary, just a clarity improvement.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between aae5635 and a8bd5b5.

⛔ Files ignored due to path filters (6)
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.featuregated-crd-manifests/networks.operator.openshift.io/NoOverlayMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
📒 Files selected for processing (17)
  • features.md
  • features/features.go
  • openapi/generated_openapi/zz_generated.openapi.go
  • openapi/openapi.json
  • operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml
  • operator/v1/types_network.go
  • operator/v1/zz_generated.deepcopy.go
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • operator/v1/zz_generated.swagger_doc_generated.go
  • payload-manifests/featuregates/featureGate-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
🧰 Additional context used
🧬 Code graph analysis (3)
features/features.go (1)
config/v1/types_feature.go (1)
  • TechPreviewNoUpgrade (45-45)
operator/v1/zz_generated.swagger_doc_generated.go (1)
operator/v1/types_network.go (2)
  • BGPManagedConfig (994-1014)
  • NoOverlayOptions (973-991)
operator/v1/zz_generated.deepcopy.go (2)
operator/v1/types_network.go (2)
  • BGPManagedConfig (994-1014)
  • NoOverlayOptions (973-991)
operator/v1/zz_generated.swagger_doc_generated.go (2)
  • BGPManagedConfig (1678-1680)
  • NoOverlayOptions (1915-1917)
🔇 Additional comments (29)
payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml (1)

38-40: LGTM! NoOverlayMode correctly added to disabled list.

The feature gate is properly positioned alphabetically and correctly disabled in the DevPreviewNoUpgrade feature set, as NoOverlayMode is scoped to TechPreviewNoUpgrade.

payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml (1)

186-188: LGTM! NoOverlayMode correctly added to disabled list.

The feature gate is properly positioned and correctly disabled in the Default feature set.

payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml (1)

188-190: LGTM! NoOverlayMode correctly added to disabled list.

The feature gate is properly positioned and correctly disabled in the OKD feature set.

payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml (1)

50-52: LGTM! NoOverlayMode correctly added to disabled list.

The feature gate is properly positioned and correctly disabled in the Hypershift DevPreviewNoUpgrade feature set.

operator/v1/zz_generated.featuregated-crd-manifests.yaml (1)

333-333: LGTM! NoOverlayMode correctly added to networks.operator.openshift.io FeatureGates.

The feature gate is properly registered for the network operator CRD and alphabetically positioned.

payload-manifests/featuregates/featureGate-Hypershift-Default.yaml (1)

189-191: NoOverlayMode correctly disabled in Hypershift default set

Adding NoOverlayMode to the disabled list for the Hypershift default feature set matches the intent of keeping this TechPreview-only gate off by default. Ordering and structure are consistent with surrounding entries.

payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml (1)

277-279: NoOverlayMode correctly enabled for SelfManagedHA TechPreviewNoUpgrade

Enabling NoOverlayMode only in the SelfManagedHA TechPreviewNoUpgrade feature set is consistent with treating this as a TechPreview gate. Placement and JSON structure match existing entries.

payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml (1)

191-193: NoOverlayMode appropriately disabled in Hypershift OKD feature set

Explicitly adding NoOverlayMode to the disabled list for the Hypershift OKD feature set keeps this TechPreview-only feature off outside TechPreview profiles and is consistent with other gate entries.

operator/v1/zz_generated.deepcopy.go (1)

393-407: DeepCopy implementations for no‑overlay/BGP types are consistent with value‑only structs

  • BGPManagedConfig and NoOverlayOptions only contain scalar/enum fields, so the generated DeepCopyInto methods using *out = *in are correct and complete.
  • In OVNKubernetesConfig.DeepCopyInto, copying DefaultNetworkNoOverlayOptions and BGPManagedConfig via direct assignment is appropriate given these are non-pointer value types without nested reference fields.

Overall, the deepcopy behavior for the new no‑overlay/BGP configuration fields looks correct and matches existing generated patterns.

Also applies to: 3684-3698, 4193-4194

features.md (1)

18-18: NoOverlayMode feature matrix entry matches manifest wiring

Documenting NoOverlayMode as enabled only for TechPreviewNoUpgrade on Hypershift and SelfManagedHA aligns with the corresponding feature gate manifests and the TechPreview‑only intent. Formatting and placement are consistent with existing rows.

payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml (1)

280-282: LGTM - NoOverlayMode feature gate correctly enabled.

The NoOverlayMode entry is properly formatted and placed in alphabetical order within the enabled feature gates list. This correctly enables the feature for the TechPreviewNoUpgrade feature set, consistent with the feature gate definition in features/features.go.

features/features.go (1)

198-204: Feature gate definition follows established patterns; verify the enhancement PR reference.

The NoOverlayMode feature gate is correctly structured with appropriate JIRA component (Networking/ovn-kubernetes), contact person, and conservative enablement scope (TechPreviewNoUpgrade). The code follows the established builder pattern and is well-positioned among other networking features.

However, the enhancement PR link (https://github.com/openshift/enhancements/pull/1859) could not be verified in public OpenShift repositories. While OVN-Kubernetes no-overlay mode is a documented feature appearing in OKEP-5296 (BGP) and OKEP-5224 (Connecting UDNs) with API support, confirm that the referenced PR number is correct or update the link to the appropriate OpenShift enhancement proposal.

openapi/generated_openapi/zz_generated.openapi.go (4)

976-976: LGTM!

The schema mappings for BGPManagedConfig and NoOverlayOptions are correctly added in alphabetical order, following the existing pattern.

Also applies to: 1115-1115


49341-49367: LGTM!

The BGPManagedConfig schema correctly defines:

  • asNumber as optional with int64 format (sufficient for the 1-4294967295 range)
  • bgpTopology as required

The enum validation for bgpTopology ("FullMesh") is appropriately handled via CEL or markers in the source types rather than OpenAPI enum constraints.


56727-56753: LGTM!

The NoOverlayOptions schema correctly defines both outboundSNAT and routing as required string fields. The allowed value constraints documented in the descriptions are validated through CEL rules in the source types.


57744-57769: LGTM!

The OVNKubernetesConfig schema updates are correctly generated:

  • New fields (defaultNetworkTransport, defaultNetworkNoOverlayOptions, bgpManagedConfig) follow existing patterns
  • Reference types use appropriate Default and Ref constructs
  • Dependencies are updated to include BGPManagedConfig and NoOverlayOptions

The conditional requirement logic (e.g., defaultNetworkNoOverlayOptions required when defaultNetworkTransport is "NoOverlay") is handled via CEL validation in the source type definitions.

operator/v1/types_network.go (3)

400-405: Maintainer note for future default is clear and scoped to GA

The comment succinctly documents why defaultNetworkTransport does not yet declare a CRD default and what to do when NoOverlayMode graduates. No change needed.


408-412: Feature-gated cross-field validations look correct and enforce required wiring

The FeatureGateAwareXValidation rules correctly express:

  • defaultNetworkNoOverlayOptions required when defaultNetworkTransport == 'NoOverlay'.
  • bgpManagedConfig required when defaultNetworkNoOverlayOptions.routing == 'Managed'.
  • defaultNetworkTransport and defaultNetworkNoOverlayOptions cannot be removed once set.

The boolean logic is straightforward and matches the test expectations for creation/immutability. No changes needed here.


940-971: New transport/SNAT/routing/BGP enums are coherent and ready for reuse

The new TransportOption, SNATOption, RoutingOption, and BGPTopology types with their constants are self-explanatory and line up with the CRD validation enums. This gives a clear, type-safe surface for future controller code. No changes needed.

operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml (2)

7-106: Create-path tests for NoOverlayMode align well with the API

  • Geneve case: explicitly setting defaultNetworkTransport: Geneve and expecting ipsecConfig.mode: Disabled matches the documented defaulting behavior.
  • Error when defaultNetworkTransport: NoOverlay without defaultNetworkNoOverlayOptions matches the first FeatureGateAwareXValidation.
  • NoOverlay + routing: Unmanaged case correctly does not expect bgpManagedConfig and still expects ipsecConfig.mode: Disabled.
  • Error when routing: Managed but bgpManagedConfig absent matches the second FeatureGateAwareXValidation.
  • Managed routing with bgpManagedConfig.bgpTopology: FullMesh and no asNumber expecting asNumber: 64512 confirms the default on ASNumber is wired correctly.

These cases provide good coverage of the primary invariants for the new fields.


107-147: Update tests correctly enforce immutability for transport and NoOverlayOptions

  • Changing defaultNetworkTransport from Geneve to NoOverlay is expected to fail with "defaultNetworkTransport is immutable once set" and matches the field-level XValidation on DefaultNetworkTransport.
  • Modifying defaultNetworkNoOverlayOptions.outboundSNAT while leaving other fields intact is expected to fail with "defaultNetworkNoOverlayOptions is immutable once set" and matches the struct-level XValidation.

These onUpdate tests are in sync with the API behavior.

operator/v1/zz_generated.swagger_doc_generated.go (3)

1672-1680: BGPManagedConfig Swagger docs accurately reflect the type definition

The descriptions for asNumber and bgpTopology here match the Go comments and validation constraints (range, default, enum, and immutability of bgpTopology). This keeps API documentation consistent; no changes needed.


1909-1917: NoOverlayOptions Swagger docs are consistent with the Go type and semantics

The generated text for outboundSNAT and routing mirrors the comments and enums in NoOverlayOptions and clearly explains the behavior in no-overlay mode. Looks good.


1919-1935: OVNKubernetesConfig Swagger docs correctly describe new fields

The additions to map_OVNKubernetesConfig:

  • Describe defaultNetworkTransport including allowed values and current default of Geneve.
  • Clarify when defaultNetworkNoOverlayOptions and bgpManagedConfig are required and what they configure.

This matches the type comments and feature semantics in types_network.go. No further adjustments needed.

openapi/openapi.json (5)

10377-10377: LGTM!

The updated description for policyType is comprehensive and clearly documents the allowed values and their semantics.


28614-28618: Schema missing default value for asNumber.

The description states "When omitted, this defaults to 64512", but the schema lacks a corresponding default field. This could cause confusion about where the defaulting occurs.

Since this is a generated file, verify whether the source Go type includes the +default=64512 marker, or if defaulting is intentionally handled at the controller level. If the latter, consider clarifying the description to say "defaults to 64512 at runtime" for accuracy.


32996-33013: LGTM!

The NoOverlayOptions schema correctly defines required fields with clear documentation of allowed values and their semantics.


33530-33539: Verify default: {} on fields referencing objects with required subfields.

Both bgpManagedConfig and defaultNetworkNoOverlayOptions have "default": {}, but their referenced types have required fields (bgpTopology for BGPManagedConfig; outboundSNAT and routing for NoOverlayOptions).

The descriptions indicate these fields are optional ("When omitted, this means..."), but the empty default could cause validation failures if an empty object {} is instantiated and then validated against the required subfields.

Please verify this is the intended behavior in the source Go types (likely using +optional and omitempty without +default={} for truly optional struct pointers), or confirm that the controller handles defaulting appropriately.


33540-33543: LGTM!

The defaultNetworkTransport field correctly documents the allowed values and platform default behavior when omitted.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @openapi/openapi.json:
- Around line 33535-33539: The schema sets an invalid empty default for
defaultNetworkNoOverlayOptions which references
com.github.openshift.api.operator.v1.NoOverlayOptions (which requires
outboundSNAT and routing); remove the "default": {} entry from the
defaultNetworkNoOverlayOptions definition so the field is truly optional (or
alternatively replace it with a schema-valid object containing outboundSNAT and
routing), updating the OpenAPI fragment that defines
defaultNetworkNoOverlayOptions accordingly.
- Around line 28607-28624: The BGPManagedConfig schema is missing validation:
update the "com.github.openshift.api.operator.v1.BGPManagedConfig" properties so
that "asNumber" includes "minimum": 1, "maximum": 4294967295 and "default":
64512, and "bgpTopology" includes an "enum": ["FullMesh"] to enforce the
documented allowed value; ensure you add these keys to the existing property
objects for asNumber and bgpTopology (referencing the asNumber and bgpTopology
property entries).
- Around line 33540-33543: The schema for the property defaultNetworkTransport
currently allows any string even though the description limits values to
"NoOverlay" and "Geneve"; add an enum constraint to the defaultNetworkTransport
schema (alongside its "type": "string") with values ["NoOverlay","Geneve"] so
validation enforces only those two options while leaving the existing
description intact.
- Around line 33530-33534: Remove the invalid "default": {} on the
bgpManagedConfig property so it no longer supplies an empty object that fails
schema validation against
definitions/com.github.openshift.api.operator.v1.BGPManagedConfig; locate the
bgpManagedConfig entry in the OpenAPI JSON and delete the "default" key (leaving
the description and $ref intact) so omission correctly represents "user does not
configure BGP".
- Around line 32996-33013: The NoOverlayOptions schema is missing enum
constraints for its string fields; update the properties for outboundSNAT and
routing within the NoOverlayOptions object to include the respective enum
arrays: add "enum": ["Enabled","Disabled"] to the outboundSNAT property and
"enum": ["Managed","Unmanaged"] to the routing property so the schema enforces
the allowed values described in their descriptions.
🧹 Nitpick comments (1)
operator/v1/types_network.go (1)

502-508: New NoOverlay/BGP types are well‑designed; consider an optional FRR guard

TransportOption, SNATOption, RoutingOption, BGPTopology, NoOverlayOptions, and BGPManagedConfig are all consistent with the documented behavior and the Swagger/OpenAPI surface (enums, defaults, and BGP topology immutability).

One optional enhancement to consider: add a higher‑level (probably NetworkSpec‑scoped) FeatureGateAwareXValidation that requires AdditionalRoutingCapabilities.providers to include FRR whenever you rely on managed BGP routing (e.g., default network in no‑overlay mode with routing == "Managed"). That would surface misconfiguration at the API boundary rather than leaving all such errors to CNO, and would mirror the existing guard you have for routeAdvertisements.

Also applies to: 940-1013

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between a8bd5b5 and 6d4e2d4.

⛔ Files ignored due to path filters (6)
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.featuregated-crd-manifests/networks.operator.openshift.io/NoOverlayMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
📒 Files selected for processing (17)
  • features.md
  • features/features.go
  • openapi/generated_openapi/zz_generated.openapi.go
  • openapi/openapi.json
  • operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml
  • operator/v1/types_network.go
  • operator/v1/zz_generated.deepcopy.go
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • operator/v1/zz_generated.swagger_doc_generated.go
  • payload-manifests/featuregates/featureGate-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
🚧 Files skipped from review as they are similar to previous changes (9)
  • features/features.go
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • operator/v1/zz_generated.deepcopy.go
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
  • operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • features.md
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
🧰 Additional context used
🧬 Code graph analysis (2)
operator/v1/zz_generated.swagger_doc_generated.go (1)
operator/v1/types_network.go (2)
  • BGPManagedConfig (994-1014)
  • NoOverlayOptions (973-991)
operator/v1/types_network.go (1)
operator/v1/zz_generated.swagger_doc_generated.go (2)
  • NoOverlayOptions (1915-1917)
  • BGPManagedConfig (1678-1680)
🔇 Additional comments (13)
payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml (1)

38-40: LGTM - NoOverlayMode feature gate addition is correctly implemented across all profiles.

The addition of NoOverlayMode to the disabled feature gates list in the SelfManagedHA-DevPreviewNoUpgrade profile is properly structured and maintains alphabetical ordering. Verification confirms that all feature gate manifests have been consistently updated:

  • NoOverlayMode is correctly placed in the disabled list for DevPreviewNoUpgrade, Default, and OKD profiles
  • NoOverlayMode is correctly placed in the enabled list for TechPreviewNoUpgrade variant

This aligns with the expected rollout strategy across all profile variants (both SelfManagedHA and Hypershift).

openapi/generated_openapi/zz_generated.openapi.go (5)

976-976: LGTM: Schema registrations.

The new schema registrations for BGPManagedConfig and NoOverlayOptions are correctly added to the GetOpenAPIDefinitions map.

Also applies to: 1115-1115


57769-57769: LGTM: Dependencies correctly updated.

The Dependencies list correctly includes the new BGPManagedConfig and NoOverlayOptions schemas.


56727-56753: The NoOverlayOptions source types already have correct enum validation tags.

The source types in operator/v1/types_network.go already include the proper kubebuilder validation annotations:

  • outboundSNAT has +kubebuilder:validation:Enum=Enabled;Disabled
  • routing has +kubebuilder:validation:Enum=Managed;Unmanaged

However, the generated OpenAPI schema at lines 56734-56747 is missing the corresponding Enum constraints in the spec. The fields only specify Type: []string{"string"} without enum values.

Regenerate the OpenAPI schema to ensure the kubebuilder validation tags are translated into Enum fields in the generated spec.

Likely an incorrect or invalid review comment.


49341-49367: Generated OpenAPI schema is missing validation constraints for BGPManagedConfig fields.

The source Go types in operator/v1/types_network.go already contain proper kubebuilder validation markers:

  • asNumber: +kubebuilder:validation:Minimum=1 and +kubebuilder:validation:Maximum=4294967295
  • bgpTopology: +kubebuilder:validation:Enum=FullMesh

However, the generated OpenAPI schema at lines 49341-49367 does not include these constraints:

  • asNumber lacks Minimum and Maximum fields
  • bgpTopology lacks an Enum field

The constraints need to be reflected in the generated schema. Verify that the schema generation process properly translates kubebuilder validation markers to OpenAPI constraint fields. If the generation is working correctly, regenerate this file using the appropriate code generation commands.


57744-57764: Enum constraint and conditional requirements are already properly implemented in the source code.

The source code at operator/v1/types_network.go already includes:

  • +kubebuilder:validation:Enum=NoOverlay;Geneve for DefaultNetworkTransport
  • Feature-gated XValidation rules enforcing the conditional requirements:
    • defaultNetworkNoOverlayOptions is required when defaultNetworkTransport is "NoOverlay"
    • bgpManagedConfig is required when defaultNetworkNoOverlayOptions.Routing is "Managed"
  • Comprehensive test coverage in operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml

However, the generated OpenAPI schema does not reflect the Enum constraint from the TransportOption type alias, which appears to be a code generation limitation with how kubebuilder handles Enum validation on string type aliases.

Likely an incorrect or invalid review comment.

operator/v1/zz_generated.swagger_doc_generated.go (3)

1672-1680: BGPManagedConfig Swagger docs match the type semantics

The asNumber and bgpTopology descriptions align with the validation (range, default, and immutability) and the Go type docs; nothing to change here.


1909-1917: NoOverlayOptions Swagger documentation is consistent with the API

The descriptions for outboundSNAT and routing correctly reflect the allowed enum values, requiredness, and behavioral notes from NoOverlayOptions in types_network.go.


1919-1936: OVNKubernetesConfig doc entries correctly describe new no‑overlay/BGP fields

The strings for defaultNetworkTransport, defaultNetworkNoOverlayOptions, and bgpManagedConfig match the struct comments and CEL validation rules (including when each is required and current defaults), so the generated Swagger surface looks coherent.

operator/v1/types_network.go (2)

400-405: Maintainer note about DefaultNetworkTransport default is appropriate

The comment clearly explains why a schema-level default isn’t set yet and how to update it when NoOverlayMode graduates to GA; it documents intent without affecting current behavior.


408-412: NoOverlayMode cross‑field validation and immutability look correct

The FeatureGateAwareXValidation rules and field‑level XValidation on DefaultNetworkTransport / DefaultNetworkNoOverlayOptions correctly enforce:

  • defaultNetworkNoOverlayOptions is present when defaultNetworkTransport == "NoOverlay".
  • bgpManagedConfig is present when defaultNetworkNoOverlayOptions.routing == "Managed".
  • defaultNetworkTransport and defaultNetworkNoOverlayOptions cannot be removed after being set, and defaultNetworkTransport is immutable once non‑empty.

This matches the field comments and keeps the TechPreview NoOverlay API well‑constrained.

Also applies to: 482-500

openapi/openapi.json (2)

33530-33543: Runtime validation for conditional requirements is properly implemented.

The documented conditional requirements are enforced through feature-gated CEL validation rules in operator/v1/types_network.go (lines 408-409):

  1. defaultNetworkNoOverlayOptions is validated as required when defaultNetworkTransport is 'NoOverlay'
  2. bgpManagedConfig is validated as required when defaultNetworkNoOverlayOptions.routing is 'Managed'

Both rules use OpenShift's FeatureGateAwareXValidation framework with the NoOverlayMode feature gate and provide clear error messages for violations. No further action needed.


10377-10377: Clarify intent of unrelated policyType description update.

This description update for the policyType field concerns signature policy verification (sigstore/Fulcio/Rekor), not OVN-Kubernetes networking. Verify whether this change is part of your PR scope or a merge artifact.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @openapi/openapi.json:
- Around line 28599-28602: The schema for the property bgpTopology is missing an
enum constraint despite the description limiting values to "FullMesh"; update
the bgpTopology schema (property name: bgpTopology) to include an enum:
["FullMesh"] while keeping type: "string" and the existing description so
OpenAPI validation only accepts the allowed value.
- Around line 32988-32991: The "routing" property schema is missing an enum
constraint even though the description restricts values to "Managed" and
"Unmanaged"; update the OpenAPI schema for the routing field (the "routing"
property definition in openapi/openapi.json) to include an "enum" array with the
two allowed strings ["Managed","Unmanaged"] so validation rejects other values,
and leave immutability enforcement to controller logic as noted in the
description.
- Around line 33520-33523: The schema for the property defaultNetworkTransport
lacks an enum constraint; update the OpenAPI schema for the JSON property
"defaultNetworkTransport" to include an "enum" array with the two allowed values
["NoOverlay", "Geneve"] while keeping the existing description and type
unchanged; ensure the enum is added alongside "type": "string" for the property
named defaultNetworkTransport so validation will reject other values (keep
conditional requirements enforced elsewhere via CEL/admission webhook as noted).
- Around line 32984-32987: The outboundSNAT property schema is missing an enum
constraint despite the description limiting values to "Enabled" and "Disabled";
update the outboundSNAT definition in openapi.json (the property named
"outboundSNAT") to include "enum": ["Enabled", "Disabled"] so validation will
reject other strings, and ensure the description remains intact; if there are
shared schemas or other places referencing outboundSNAT, add or align the same
enum constraint there as well.
- Around line 33510-33519: The OpenAPI schema sets "default": {} for the
optional object refs bgpManagedConfig and defaultNetworkNoOverlayOptions which
contradicts their "when omitted" semantics and can mask missing required nested
fields (e.g., bgpTopology in
com.github.openshift.api.operator.v1.BGPManagedConfig); remove the "default": {}
entries for the properties named bgpManagedConfig and
defaultNetworkNoOverlayOptions in the openapi JSON so they remain truly
omittable while leaving the "$ref" and "description" intact.
🧹 Nitpick comments (2)
openapi/openapi.json (1)

28594-28598: Consider adding default value to the schema.

The description mentions asNumber defaults to 64512, but the schema doesn't include a default property. Adding it improves OpenAPI client generation and documentation.

📝 Proposed enhancement
 "asNumber": {
   "description": "asNumber is the 2-byte or 4-byte Autonomous System Number (ASN) to be used in the generated FRR configuration. Valid values are 1 to 4294967295. When omitted, this defaults to 64512.",
   "type": "integer",
-  "format": "int64"
+  "format": "int64",
+  "default": 64512
 }
operator/v1/types_network.go (1)

400-405: FeatureGate-aware validation rules for NoOverlayMode are coherent

  • The maintainer note around DefaultNetworkTransport defaulting and the four FeatureGateAwareXValidation rules on OVNKubernetesConfig correctly model:
    • Requirement of defaultNetworkNoOverlayOptions when defaultNetworkTransport == "NoOverlay".
    • Requirement of bgpManagedConfig when defaultNetworkNoOverlayOptions.routing == "Managed".
    • Preventing removal of defaultNetworkTransport and defaultNetworkNoOverlayOptions once set (while allowing initial set from empty).
  • Given that the same NoOverlayMode feature-gate is also used on the new fields, these validations won’t interfere when the gate is disabled.

One subtle, likely intentional behavior: bgpManagedConfig may be present even if the default network’s routing is Unmanaged (e.g., to support CUDNs with routing="Managed"). If you instead want to forbid bgpManagedConfig when there is no Managed no-overlay use at all, a symmetric CEL guard would be needed; as-is, the API is more permissive but functionally safe.

Also applies to: 408-412

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 6d4e2d4 and dd22f3d.

⛔ Files ignored due to path filters (6)
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.featuregated-crd-manifests/networks.operator.openshift.io/NoOverlayMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
📒 Files selected for processing (17)
  • features.md
  • features/features.go
  • openapi/generated_openapi/zz_generated.openapi.go
  • openapi/openapi.json
  • operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml
  • operator/v1/types_network.go
  • operator/v1/zz_generated.deepcopy.go
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • operator/v1/zz_generated.swagger_doc_generated.go
  • payload-manifests/featuregates/featureGate-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
🚧 Files skipped from review as they are similar to previous changes (10)
  • payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • operator/v1/zz_generated.deepcopy.go
  • payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml
  • operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml
  • features.md
  • openapi/generated_openapi/zz_generated.openapi.go
🧰 Additional context used
🧬 Code graph analysis (3)
operator/v1/types_network.go (1)
operator/v1/zz_generated.swagger_doc_generated.go (2)
  • NoOverlayOptions (1915-1917)
  • BGPManagedConfig (1678-1680)
features/features.go (1)
config/v1/types_feature.go (1)
  • TechPreviewNoUpgrade (45-45)
operator/v1/zz_generated.swagger_doc_generated.go (1)
operator/v1/types_network.go (2)
  • BGPManagedConfig (996-1014)
  • NoOverlayOptions (973-993)
🔇 Additional comments (7)
features/features.go (1)

198-204: LGTM! Feature gate implementation follows established patterns.

The feature gate declaration is correctly structured and includes all required metadata:

  • Appropriate Jira component and contact person
  • Links to the enhancement PR
  • Enabled only in TechPreviewNoUpgrade, which is suitable for a new feature
  • Consistent with other feature gates in the file
payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml (1)

277-279: Enable NoOverlayMode for SelfManagedHA TechPreview looks correct

NoOverlayMode is appropriately added to the enabled list for the TechPreviewNoUpgrade feature set; ordering among peers is fine and has no semantic impact.

payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml (1)

186-188: NoOverlayMode correctly defaulted to disabled in SelfManagedHA-Default

Listing NoOverlayMode in the disabled block for the Default feature set matches expected lifecycle for a TechPreview gate.

payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml (1)

280-282: Hypershift TechPreview enabling of NoOverlayMode is consistent

Adding NoOverlayMode to the enabled list for the Hypershift TechPreviewNoUpgrade profile aligns with the SelfManagedHA TechPreview behavior.

operator/v1/zz_generated.swagger_doc_generated.go (1)

1672-1680: Swagger docs correctly wired to new NoOverlay/BGP types and OVN fields

The new SwaggerDoc maps for BGPManagedConfig and NoOverlayOptions, plus the extended OVNKubernetesConfig map entries for defaultNetworkTransport, defaultNetworkNoOverlayOptions, and bgpManagedConfig, all match the Go type definitions and comments in operator/v1/types_network.go. JSON field names and semantics (requiredness, immutability notes, and Managed/Unmanaged/BGP behavior) are consistent.

Also applies to: 1909-1917, 1919-1935

operator/v1/types_network.go (2)

482-508: New OVNKubernetesConfig fields model no-overlay and BGP state with appropriate immutability

  • DefaultNetworkTransport:
    • Enum-restricted to NoOverlay/Geneve and immutable after first non-empty set (oldSelf == '' || self == oldSelf), plus an object-level guard preventing removal once non-empty. This gives a one-shot choice of overlay vs no-overlay, which matches the intended semantics.
  • DefaultNetworkNoOverlayOptions:
    • Uses NoOverlayOptions (with required outboundSNAT and routing) and omitzero to avoid emitting an all-zero struct.
    • Separate rule ensures it can’t be removed once present, while allowing changes to OutboundSNAT and keeping Routing immutable via the nested XValidation.
  • BGPManagedConfig:
    • Global config used when routing is Managed. The field is optional, but required in the default-network-managed case via the earlier XValidation.
    • The field-level XValidation !oldSelf.hasValue() || self == oldSelf.value() with optionalOldSelf=true makes the config immutable once first set, including preventing later removal, which is consistent with BGP topology stability expectations.

The combination of ,omitzero,omitempty and the CEL has(...) checks is correct here because valid instances of these structs must have non-zero content due to their own required fields.


940-971: Option types and NoOverlay/BGP config structs are well-typed and validate the documented constraints

  • Introducing TransportOption, SNATOption, RoutingOption, and BGPTopology plus the associated constants keeps the public API strongly typed and self-documenting.
  • NoOverlayOptions:
    • Restricts outboundSNAT to Enabled/Disabled and routing to Managed/Unmanaged with enum validations.
    • Makes routing explicitly immutable (self == oldSelf), which aligns with the comment and with the higher-level invariants around BGP vs user-managed routing.
  • BGPManagedConfig:
    • ASN range 1–4294967295 with a default of 64512 is correctly enforced via Minimum, Maximum, and default.
    • bgpTopology is required and enum-limited to FullMesh, matching the constant BGPTopologyFullMesh.

Overall this block is consistent in style with existing network API types and gives controllers enough structure to reason about no-overlay mode and managed BGP configuration.

Also applies to: 972-994, 995-1014

Comment on lines +28599 to +28717
"bgpTopology": {
"description": "bgpTopology defines the BGP topology to be used. Allowed values are \"FullMesh\". When set to \"FullMesh\", every node deploys a BGP router, forming a BGP full mesh. This field is required when BGPManagedConfig is specified.",
"type": "string"
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add enum constraint for bgpTopology.

The description specifies that bgpTopology only allows "FullMesh", but the schema lacks an enum constraint. This allows invalid values to pass OpenAPI validation.

🛡️ Proposed fix to add enum constraint
 "bgpTopology": {
   "description": "bgpTopology defines the BGP topology to be used. Allowed values are \"FullMesh\". When set to \"FullMesh\", every node deploys a BGP router, forming a BGP full mesh. This field is required when BGPManagedConfig is specified.",
-  "type": "string"
+  "type": "string",
+  "enum": ["FullMesh"]
 }
📝 Committable suggestion

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

Suggested change
"bgpTopology": {
"description": "bgpTopology defines the BGP topology to be used. Allowed values are \"FullMesh\". When set to \"FullMesh\", every node deploys a BGP router, forming a BGP full mesh. This field is required when BGPManagedConfig is specified.",
"type": "string"
}
"bgpTopology": {
"description": "bgpTopology defines the BGP topology to be used. Allowed values are \"FullMesh\". When set to \"FullMesh\", every node deploys a BGP router, forming a BGP full mesh. This field is required when BGPManagedConfig is specified.",
"type": "string",
"enum": ["FullMesh"]
}
🤖 Prompt for AI Agents
In @openapi/openapi.json around lines 28599 - 28602, The schema for the property
bgpTopology is missing an enum constraint despite the description limiting
values to "FullMesh"; update the bgpTopology schema (property name: bgpTopology)
to include an enum: ["FullMesh"] while keeping type: "string" and the existing
description so OpenAPI validation only accepts the allowed value.

Comment on lines 32984 to 33102
"outboundSNAT": {
"description": "outboundSNAT defines the SNAT behavior for outbound traffic from pods. Allowed values are \"Enabled\" and \"Disabled\". When set to \"Enabled\", SNAT is performed on outbound traffic from pods. When set to \"Disabled\", SNAT is not performed and pod IPs are preserved in outbound traffic. This field is required when the network operates in no-overlay mode.",
"type": "string"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add enum constraint for outboundSNAT.

The description specifies allowed values "Enabled" and "Disabled", but the schema lacks an enum constraint, allowing invalid values to pass validation.

🛡️ Proposed fix to add enum constraint
 "outboundSNAT": {
   "description": "outboundSNAT defines the SNAT behavior for outbound traffic from pods. Allowed values are \"Enabled\" and \"Disabled\". When set to \"Enabled\", SNAT is performed on outbound traffic from pods. When set to \"Disabled\", SNAT is not performed and pod IPs are preserved in outbound traffic. This field is required when the network operates in no-overlay mode.",
-  "type": "string"
+  "type": "string",
+  "enum": ["Enabled", "Disabled"]
 }
📝 Committable suggestion

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

Suggested change
"outboundSNAT": {
"description": "outboundSNAT defines the SNAT behavior for outbound traffic from pods. Allowed values are \"Enabled\" and \"Disabled\". When set to \"Enabled\", SNAT is performed on outbound traffic from pods. When set to \"Disabled\", SNAT is not performed and pod IPs are preserved in outbound traffic. This field is required when the network operates in no-overlay mode.",
"type": "string"
},
"outboundSNAT": {
"description": "outboundSNAT defines the SNAT behavior for outbound traffic from pods. Allowed values are \"Enabled\" and \"Disabled\". When set to \"Enabled\", SNAT is performed on outbound traffic from pods. When set to \"Disabled\", SNAT is not performed and pod IPs are preserved in outbound traffic. This field is required when the network operates in no-overlay mode.",
"type": "string",
"enum": ["Enabled", "Disabled"]
},
🤖 Prompt for AI Agents
In @openapi/openapi.json around lines 32984 - 32987, The outboundSNAT property
schema is missing an enum constraint despite the description limiting values to
"Enabled" and "Disabled"; update the outboundSNAT definition in openapi.json
(the property named "outboundSNAT") to include "enum": ["Enabled", "Disabled"]
so validation will reject other strings, and ensure the description remains
intact; if there are shared schemas or other places referencing outboundSNAT,
add or align the same enum constraint there as well.

Comment on lines +32988 to +33106
"routing": {
"description": "routing specifies whether the pod network routing is managed by OVN-Kubernetes or users. Allowed values are \"Managed\" and \"Unmanaged\". When set to \"Managed\", OVN-Kubernetes manages the pod network routing configuration through BGP. When set to \"Unmanaged\", users are responsible for configuring the pod network routing. This field is required when the network operates in no-overlay mode. This field is immutable once set.",
"type": "string"
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add enum constraint for routing.

The description specifies allowed values "Managed" and "Unmanaged", but the schema lacks an enum constraint, allowing invalid values to pass validation.

Note: The immutability constraint mentioned in the description must be enforced by controller validation logic, as OpenAPI schemas cannot express immutability.

🛡️ Proposed fix to add enum constraint
 "routing": {
   "description": "routing specifies whether the pod network routing is managed by OVN-Kubernetes or users. Allowed values are \"Managed\" and \"Unmanaged\". When set to \"Managed\", OVN-Kubernetes manages the pod network routing configuration through BGP. When set to \"Unmanaged\", users are responsible for configuring the pod network routing. This field is required when the network operates in no-overlay mode. This field is immutable once set.",
-  "type": "string"
+  "type": "string",
+  "enum": ["Managed", "Unmanaged"]
 }
🤖 Prompt for AI Agents
In @openapi/openapi.json around lines 32988 - 32991, The "routing" property
schema is missing an enum constraint even though the description restricts
values to "Managed" and "Unmanaged"; update the OpenAPI schema for the routing
field (the "routing" property definition in openapi/openapi.json) to include an
"enum" array with the two allowed strings ["Managed","Unmanaged"] so validation
rejects other values, and leave immutability enforcement to controller logic as
noted in the description.

Comment on lines 33510 to 33634
"bgpManagedConfig": {
"description": "bgpManagedConfig configures the BGP properties for networks (default network or CUDNs) in no-overlay mode that specify routing=\"Managed\" in their NoOverlayOptions. It is required when DefaultNetworkNoOverlayOptions.Routing is set to \"Managed\". When omitted, this means the user does not configure BGP for managed routing.",
"default": {},
"$ref": "#/definitions/com.github.openshift.api.operator.v1.BGPManagedConfig"
},
"defaultNetworkNoOverlayOptions": {
"description": "defaultNetworkNoOverlayOptions contains configuration for no-overlay mode for the default network. It is required when DefaultNetworkTransport is \"NoOverlay\". When omitted, this means the user does not configure no-overlay mode options.",
"default": {},
"$ref": "#/definitions/com.github.openshift.api.operator.v1.NoOverlayOptions"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove improper default values for optional object references.

Both bgpManagedConfig and defaultNetworkNoOverlayOptions have "default": {}, which conflicts with their "when omitted" semantics described in the documentation. These fields should be fully optional (omittable), not defaulting to empty objects.

The descriptions state:

  • "When omitted, this means the user does not configure BGP for managed routing."
  • "When omitted, this means the user does not configure no-overlay mode options."

An empty object {} is not the same as an omitted field. If these fields are present with empty values, it may trigger validation errors (e.g., required nested fields in BGPManagedConfig like bgpTopology).

🔧 Proposed fix to remove default values
 "bgpManagedConfig": {
   "description": "bgpManagedConfig configures the BGP properties for networks (default network or CUDNs) in no-overlay mode that specify routing=\"Managed\" in their NoOverlayOptions. It is required when DefaultNetworkNoOverlayOptions.Routing is set to \"Managed\". When omitted, this means the user does not configure BGP for managed routing.",
-  "default": {},
   "$ref": "#/definitions/com.github.openshift.api.operator.v1.BGPManagedConfig"
 },
 "defaultNetworkNoOverlayOptions": {
   "description": "defaultNetworkNoOverlayOptions contains configuration for no-overlay mode for the default network. It is required when DefaultNetworkTransport is \"NoOverlay\". When omitted, this means the user does not configure no-overlay mode options.",
-  "default": {},
   "$ref": "#/definitions/com.github.openshift.api.operator.v1.NoOverlayOptions"
 },
📝 Committable suggestion

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

Suggested change
"bgpManagedConfig": {
"description": "bgpManagedConfig configures the BGP properties for networks (default network or CUDNs) in no-overlay mode that specify routing=\"Managed\" in their NoOverlayOptions. It is required when DefaultNetworkNoOverlayOptions.Routing is set to \"Managed\". When omitted, this means the user does not configure BGP for managed routing.",
"default": {},
"$ref": "#/definitions/com.github.openshift.api.operator.v1.BGPManagedConfig"
},
"defaultNetworkNoOverlayOptions": {
"description": "defaultNetworkNoOverlayOptions contains configuration for no-overlay mode for the default network. It is required when DefaultNetworkTransport is \"NoOverlay\". When omitted, this means the user does not configure no-overlay mode options.",
"default": {},
"$ref": "#/definitions/com.github.openshift.api.operator.v1.NoOverlayOptions"
},
"bgpManagedConfig": {
"description": "bgpManagedConfig configures the BGP properties for networks (default network or CUDNs) in no-overlay mode that specify routing=\"Managed\" in their NoOverlayOptions. It is required when DefaultNetworkNoOverlayOptions.Routing is set to \"Managed\". When omitted, this means the user does not configure BGP for managed routing.",
"$ref": "#/definitions/com.github.openshift.api.operator.v1.BGPManagedConfig"
},
"defaultNetworkNoOverlayOptions": {
"description": "defaultNetworkNoOverlayOptions contains configuration for no-overlay mode for the default network. It is required when DefaultNetworkTransport is \"NoOverlay\". When omitted, this means the user does not configure no-overlay mode options.",
"$ref": "#/definitions/com.github.openshift.api.operator.v1.NoOverlayOptions"
},
🤖 Prompt for AI Agents
In @openapi/openapi.json around lines 33510 - 33519, The OpenAPI schema sets
"default": {} for the optional object refs bgpManagedConfig and
defaultNetworkNoOverlayOptions which contradicts their "when omitted" semantics
and can mask missing required nested fields (e.g., bgpTopology in
com.github.openshift.api.operator.v1.BGPManagedConfig); remove the "default": {}
entries for the properties named bgpManagedConfig and
defaultNetworkNoOverlayOptions in the openapi JSON so they remain truly
omittable while leaving the "$ref" and "description" intact.

Comment on lines 33520 to 33638
"defaultNetworkTransport": {
"description": "defaultNetworkTransport describes the transport protocol for east-west traffic for the default network. Allowed values are \"NoOverlay\" and \"Geneve\". When set to \"NoOverlay\", the default network operates in no-overlay mode. When set to \"Geneve\", the default network uses Geneve overlay. When omitted, this means the user has no opinion and the platform chooses a reasonable default which is subject to change over time. The current default is \"Geneve\".",
"type": "string"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add enum constraint for defaultNetworkTransport.

The description specifies allowed values "NoOverlay" and "Geneve", but the schema lacks an enum constraint, allowing invalid values to pass validation.

Note: The conditional requirements described in the parent object's documentation (e.g., "defaultNetworkNoOverlayOptions is required when defaultNetworkTransport is NoOverlay") cannot be expressed in OpenAPI schemas and must be enforced through CEL validation rules or admission webhooks.

🛡️ Proposed fix to add enum constraint
 "defaultNetworkTransport": {
   "description": "defaultNetworkTransport describes the transport protocol for east-west traffic for the default network. Allowed values are \"NoOverlay\" and \"Geneve\". When set to \"NoOverlay\", the default network operates in no-overlay mode. When set to \"Geneve\", the default network uses Geneve overlay. When omitted, this means the user has no opinion and the platform chooses a reasonable default which is subject to change over time. The current default is \"Geneve\".",
-  "type": "string"
+  "type": "string",
+  "enum": ["NoOverlay", "Geneve"]
 }
🤖 Prompt for AI Agents
In @openapi/openapi.json around lines 33520 - 33523, The schema for the property
defaultNetworkTransport lacks an enum constraint; update the OpenAPI schema for
the JSON property "defaultNetworkTransport" to include an "enum" array with the
two allowed values ["NoOverlay", "Geneve"] while keeping the existing
description and type unchanged; ensure the enum is added alongside "type":
"string" for the property named defaultNetworkTransport so validation will
reject other values (keep conditional requirements enforced elsewhere via
CEL/admission webhook as noted).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@operator/v1/types_network.go`:
- Around line 408-412: Add inverse validation rules to OVNKubernetesConfig to
forbid defaultNetworkNoOverlayOptions and bgpManagedConfig unless
defaultNetworkTransport == 'NoOverlay': add FeatureGateAwareXValidation rules
that require !has(self.defaultNetworkNoOverlayOptions) ||
self.defaultNetworkTransport == 'NoOverlay' with an appropriate message, and
!has(self.bgpManagedConfig) || self.defaultNetworkTransport == 'NoOverlay' (or
tie bgpManagedConfig presence to defaultNetworkNoOverlayOptions.routing ==
'Managed' and transport == 'NoOverlay') so those fields are rejected when
transport is Geneve or unset; reference the OVNKubernetesConfig type and the
fields defaultNetworkTransport, defaultNetworkNoOverlayOptions, and
bgpManagedConfig when adding the rules.
♻️ Duplicate comments (3)
openapi/openapi.json (3)

28644-28661: Generated schema acknowledged.

This BGPManagedConfig schema is auto-generated from operator/v1/types_network.go. The schema structure correctly reflects the required bgpTopology field and optional asNumber with documented ASN range.

Previous review comments about adding enum and min/max constraints were addressed by the author clarifying that any such changes need to be made in the source Go types file, not in this generated output.


33033-33050: Generated schema acknowledged.

This NoOverlayOptions schema is auto-generated. The structure correctly requires both outboundSNAT and routing fields, with allowed values documented in descriptions.

Previous comments about enum constraints were addressed—any validation enhancements belong in the source Go types.


33567-33580: Generated schema acknowledged.

These OVNKubernetesConfig extensions are auto-generated. Previous comments about "default": {} values for object references and missing enum constraints for defaultNetworkTransport were addressed by the author—any changes need to be made in the source Go types file (operator/v1/types_network.go).

🧹 Nitpick comments (3)
operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml (1)

8-117: Add a “forbidden unless transport=NoOverlay” negative test to prevent ambiguous configs

Right now the suite asserts “required when NoOverlay,” but it doesn’t assert the inverse (“must not be set when Geneve”). If the API is intended to reject defaultNetworkNoOverlayOptions (and bgpManagedConfig) unless defaultNetworkTransport: NoOverlay, add a test case for that. This will prevent silently-ignored/contradictory configs.

Proposed test addition
 tests:
   onCreate:
+  - name: Should fail if NoOverlayOptions are set when transport is Geneve
+    initial: |
+      apiVersion: operator.openshift.io/v1
+      kind: Network
+      spec:
+        defaultNetwork:
+          ovnKubernetesConfig:
+            defaultNetworkTransport: Geneve
+            defaultNetworkNoOverlayOptions:
+              outboundSNAT: Enabled
+              routing: Unmanaged
+    expectedError: "defaultNetworkNoOverlayOptions is forbidden when defaultNetworkTransport is not NoOverlay"
operator/v1/zz_generated.swagger_doc_generated.go (1)

1672-1680: Swagger docs: consider reflecting bgpManagedConfig immutability in the source comments

OVNKubernetesConfig.bgpManagedConfig is enforced immutable in operator/v1/types_network.go (Line 506-508), but the docstring here doesn’t hint at that. Since this file is generated, the fix should be updating the field comment in types_network.go and re-running generation.

operator/v1/types_network.go (1)

482-492: Consider making defaultNetworkTransport immutability rule robust to “unset → set later” edge-cases

The current rule (Line 490) relies on oldSelf == '' as the “unset” sentinel. If the field is omitted (not an explicit empty string), CEL optional semantics can be subtle across Kubernetes versions. Adding a focused test for “create with field omitted, then set it” (and/or switching to optionalOldSelf=true + hasValue() style) would make this safer.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between dd22f3d and b3e455e.

⛔ Files ignored due to path filters (6)
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.featuregated-crd-manifests/networks.operator.openshift.io/NoOverlayMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
📒 Files selected for processing (17)
  • features.md
  • features/features.go
  • openapi/generated_openapi/zz_generated.openapi.go
  • openapi/openapi.json
  • operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml
  • operator/v1/types_network.go
  • operator/v1/zz_generated.deepcopy.go
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • operator/v1/zz_generated.swagger_doc_generated.go
  • payload-manifests/featuregates/featureGate-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
🚧 Files skipped from review as they are similar to previous changes (9)
  • features/features.go
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • operator/v1/zz_generated.deepcopy.go
  • payload-manifests/featuregates/featureGate-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
🧰 Additional context used
🧬 Code graph analysis (2)
openapi/generated_openapi/zz_generated.openapi.go (1)
config/v1/types_feature.go (1)
  • Default (41-41)
operator/v1/zz_generated.swagger_doc_generated.go (1)
operator/v1/types_network.go (2)
  • BGPManagedConfig (998-1016)
  • NoOverlayOptions (973-995)
🔇 Additional comments (10)
payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml (1)

38-40: LGTM!

The NoOverlayMode feature gate is correctly added to the disabled list, maintaining alphabetical ordering and consistent with the feature being enabled only in TechPreviewNoUpgrade profiles.

payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml (1)

200-202: LGTM!

The NoOverlayMode feature gate is correctly added to the disabled list for the OKD profile, maintaining proper alphabetical ordering and consistency with the feature gate definition.

features.md (1)

17-17: LGTM!

The NoOverlayMode feature gate documentation is correctly added, showing enablement only in TechPreviewNoUpgrade profiles for both Hypershift and SelfManagedHA. This is consistent with the corresponding YAML manifest changes where the feature is added to disabled lists in Default, DevPreviewNoUpgrade, and OKD profiles.

openapi/generated_openapi/zz_generated.openapi.go (4)

979-979: LGTM!

The new type registrations for BGPManagedConfig and NoOverlayOptions are correctly placed in alphabetical order and properly reference the schema functions defined later in this generated file.

Also applies to: 1118-1118


49545-49571: LGTM!

The BGPManagedConfig schema is correctly generated:

  • asNumber uses int64 format appropriate for 4-byte ASN values
  • bgpTopology is marked as required
  • Descriptions accurately document the allowed values and defaults

Value range validation for asNumber and enum constraints for bgpTopology are expected to be enforced via validation markers in the source Go types.


56931-56957: LGTM!

The NoOverlayOptions schema is correctly generated with both outboundSNAT and routing marked as required. The descriptions clearly document the allowed values and mutability constraints (SNAT is mutable post-install, routing is immutable once set).


57948-57975: LGTM!

The OVNKubernetesConfig schema extensions are correctly generated:

  • Three new fields added with appropriate descriptions documenting conditional requirements
  • Ref types properly reference the new schemas with standard Default: map[string]interface{}{}
  • Dependencies array correctly updated to include BGPManagedConfig and NoOverlayOptions

The conditional validation logic (e.g., defaultNetworkNoOverlayOptions required when transport is "NoOverlay") is expected to be enforced via CEL validation rules in the source Go types.

operator/v1/zz_generated.swagger_doc_generated.go (1)

1909-1936: Docs look consistent for NoOverlayOptions + new OVNKubernetesConfig fields

The descriptions for defaultNetworkTransport, defaultNetworkNoOverlayOptions, and bgpManagedConfig read coherently and match the high-level intent. Any semantic tweaks (e.g., forbidding options when transport!=NoOverlay) should be reflected by updating types_network.go comments and regenerating.

operator/v1/types_network.go (1)

400-405: Maintainer note is clear and useful

Captures why the default isn’t expressed in-schema yet and what to do at graduation.

operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml (1)

138-174: Verify alignment between test assertions and intended bgpManagedConfig day-2 mutability

The onUpdate test (lines 198-224) should match the intended behavior: if day-2 ASN changes are allowed, the test must assert bgpManagedConfig.asNumber is mutable (or only bgpTopology is immutable); if day-2 changes are disallowed, the current immutability assertion is correct. Cross-reference the test with the schema in operator/v1/types_network.go and PR discussion history to confirm alignment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@openapi/generated_openapi/zz_generated.openapi.go`:
- Around line 56931-56954: The generated OpenAPI definition in
schema_openshift_api_operator_v1_NoOverlayOptions is missing Enum constraints
for the outboundSNAT and routing properties; update the OpenAPIDefinition so
each spec.SchemaProps for "outboundSNAT" and "routing" includes Enum:
[]interface{}{"Enabled","Disabled"} and Enum:
[]interface{}{"Managed","Unmanaged"} respectively (i.e., add the Enum entries to
the SchemaProps in the OpenAPIDefinition returned by
schema_openshift_api_operator_v1_NoOverlayOptions) and then regenerate the
OpenAPI artifacts so the OpenAPIDefinition/SchemaProps reflect the kubebuilder
+kubebuilder:validation:Enum annotations.
- Around line 57948-57967: The OpenAPI output is missing the Enum for
defaultNetworkTransport and is incorrectly emitting empty-object defaults for
complex optional fields; update the generation so that the schema for
"defaultNetworkTransport" includes Enum: []string{"NoOverlay","Geneve"} (match
the +kubebuilder:validation:Enum tag) and remove the Default:
map[string]interface{}{} entries for "defaultNetworkNoOverlayOptions" and
"bgpManagedConfig" so they remain optional with no default; ensure the refs
still point to NoOverlayOptions and BGPManagedConfig (Ref:
ref("github.com/openshift/api/operator/v1.NoOverlayOptions") and
ref("github.com/openshift/api/operator/v1.BGPManagedConfig")) and adjust the
OpenAPI generator or struct tags so required subfields inside those types are
validated only when the object is present.
♻️ Duplicate comments (4)
operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml (1)

240-265: bgpManagedConfig immutability expectation conflicts with current validation.

This update only changes asNumber, but current API validation only makes bgpTopology immutable; asNumber remains mutable. Either enforce full immutability in the API or relax this test accordingly.

openapi/openapi.json (3)

28702-28719: BGPManagedConfig type definition appears correctly generated.

This type is auto-generated from the Go source types. The structure with required bgpTopology and optional asNumber fields matches the documented API design. Any validation constraints (enum values, numeric ranges) would need to be added via CEL validation rules or kubebuilder markers in the source Go types.


33091-33108: NoOverlayOptions type definition appears correctly generated.

This type is auto-generated from Go source types. The structure with both outboundSNAT and routing as required fields aligns with the no-overlay mode requirements described in the documentation.


33625-33638: OVNKubernetesConfig extensions for no-overlay mode look correctly generated.

The new fields (bgpManagedConfig, defaultNetworkNoOverlayOptions, defaultNetworkTransport) are properly integrated into the OVNKubernetesConfig schema. The "default": {} pattern is a known behavior from kubebuilder's OpenAPI generation for optional struct pointer fields.

🧹 Nitpick comments (1)
operator/v1/types_network.go (1)

408-411: Consider adding inverse validation to forbid no-overlay fields when transport is not NoOverlay.

The current rules require defaultNetworkNoOverlayOptions when transport is NoOverlay, but don't forbid these fields when transport is Geneve or omitted. This could allow contradictory configurations where defaultNetworkTransport: Geneve is set alongside defaultNetworkNoOverlayOptions or bgpManagedConfig.

Proposed additional validations
 // +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.defaultNetworkTransport) || self.defaultNetworkTransport != 'NoOverlay' || has(self.defaultNetworkNoOverlayOptions)",message="defaultNetworkNoOverlayOptions is required when defaultNetworkTransport is NoOverlay"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.defaultNetworkNoOverlayOptions) || (has(self.defaultNetworkTransport) && self.defaultNetworkTransport == 'NoOverlay')",message="defaultNetworkNoOverlayOptions is forbidden when defaultNetworkTransport is not NoOverlay"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.bgpManagedConfig) || (has(self.defaultNetworkTransport) && self.defaultNetworkTransport == 'NoOverlay')",message="bgpManagedConfig is forbidden when defaultNetworkTransport is not NoOverlay"
 // +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.defaultNetworkNoOverlayOptions) || self.defaultNetworkNoOverlayOptions.routing != 'Managed' || has(self.bgpManagedConfig)",message="bgpManagedConfig is required when defaultNetworkNoOverlayOptions.routing is Managed"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between b3e455e and 162b45b.

⛔ Files ignored due to path filters (6)
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_70_network_01_networks-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.featuregated-crd-manifests/networks.operator.openshift.io/NoOverlayMode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
📒 Files selected for processing (17)
  • features.md
  • features/features.go
  • openapi/generated_openapi/zz_generated.openapi.go
  • openapi/openapi.json
  • operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml
  • operator/v1/types_network.go
  • operator/v1/zz_generated.deepcopy.go
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • operator/v1/zz_generated.swagger_doc_generated.go
  • payload-manifests/featuregates/featureGate-Hypershift-Default.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
🚧 Files skipped from review as they are similar to previous changes (7)
  • operator/v1/zz_generated.featuregated-crd-manifests.yaml
  • payload-manifests/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml
  • features.md
  • payload-manifests/featuregates/featureGate-SelfManagedHA-DevPreviewNoUpgrade.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-OKD.yaml
  • payload-manifests/featuregates/featureGate-SelfManagedHA-Default.yaml
🧰 Additional context used
🧬 Code graph analysis (4)
operator/v1/zz_generated.deepcopy.go (2)
operator/v1/types_network.go (2)
  • BGPManagedConfig (1000-1018)
  • NoOverlayOptions (975-997)
operator/v1/zz_generated.swagger_doc_generated.go (2)
  • BGPManagedConfig (1678-1680)
  • NoOverlayOptions (1915-1917)
features/features.go (1)
config/v1/types_feature.go (1)
  • TechPreviewNoUpgrade (45-45)
operator/v1/zz_generated.swagger_doc_generated.go (1)
operator/v1/types_network.go (2)
  • BGPManagedConfig (1000-1018)
  • NoOverlayOptions (975-997)
operator/v1/types_network.go (1)
operator/v1/zz_generated.swagger_doc_generated.go (2)
  • NoOverlayOptions (1915-1917)
  • BGPManagedConfig (1678-1680)
🔇 Additional comments (33)
payload-manifests/featuregates/featureGate-Hypershift-Default.yaml (1)

198-200: NoOverlayMode disabled entry looks consistent.
Keeps the default Hypershift profile explicit about the gate state.

features/features.go (1)

198-204: Confirm TechPreview enablement scope is intentional.
enableIn(configv1.TechPreviewNoUpgrade) applies across cluster profiles; if NoOverlayMode should be limited to specific profiles, please confirm or switch to enableForClusterProfile.

payload-manifests/featuregates/featureGate-Hypershift-OKD.yaml (1)

200-202: NoOverlayMode disabled entry looks consistent for OKD.

payload-manifests/featuregates/featureGate-Hypershift-DevPreviewNoUpgrade.yaml (1)

50-52: NoOverlayMode disabled entry looks consistent for DevPreviewNoUpgrade.

operator/v1/zz_generated.deepcopy.go (3)

393-407: BGPManagedConfig deepcopy additions look good.


3684-3698: NoOverlayOptions deepcopy additions look good.


4193-4194: Verify copy/optionality semantics for new OVNKubernetesConfig fields.
If these fields are pointers, they should be deep-copied with nil checks; if value types, confirm they’re intended to be always present even when no-overlay is off.

openapi/generated_openapi/zz_generated.openapi.go (3)

976-980: Schema registration looks correct.


1115-1119: Schema registration looks correct.


49545-49569: Add explicit schema constraints for BGPManagedConfig.

The schema description declares an ASN range (1 to 4294967295) and allowed bgpTopology values ("FullMesh"), but the generated OpenAPI schema does not enforce them. Please verify that kubebuilder validation annotations (Minimum/Maximum for asNumber, enum for bgpTopology) exist in the source type definition, and if missing, add them and regenerate the OpenAPI.

operator/v1/tests/networks.operator.openshift.io/NoOverlayMode.yaml (11)

1-6: Feature gate wiring looks good.


8-27: Geneve default-path create test is solid.


28-36: Negative test for missing NoOverlay options is clear.


37-63: Unmanaged no-overlay create test is clear.


64-74: Install-time outboundSNAT constraint test is clear.


75-86: Managed routing requires BGP config test is good.


87-117: Managed routing happy-path test looks good.


119-137: defaultNetworkTransport immutability test is appropriate.


138-174: Day‑2 outboundSNAT update test is clear.


175-197: Routing immutability update test is clear.


198-239: Day‑2 enabling of bgpManagedConfig is covered.

operator/v1/zz_generated.swagger_doc_generated.go (3)

1672-1680: Swagger doc for BGPManagedConfig looks fine.


1909-1917: Swagger doc for NoOverlayOptions looks fine.


1919-1936: OVNKubernetesConfig doc updates look consistent.

openapi/openapi.json (4)

4575-4587: New conditional update risk types look well-structured.

The new AcceptRisk type and associated fields (conditionalUpdateRisks, riskNames, conditions) follow standard Kubernetes API patterns with appropriate list type semantics (map with unique keys, set for unique strings).

Also applies to: 5875-5886, 6094-6102, 6129-6140


6351-6351: TLS profile description enhancements look good.

The updated descriptions provide clearer documentation with YAML examples and cipher suite details for the various TLS security profiles. These are documentation improvements that enhance API usability.

Also applies to: 8537-8537, 8815-8815, 9745-9745, 11323-11323, 11334-11353


11639-11650: Update type enhancements for risk acceptance look correct.

The new acceptRisks field correctly uses a map list type keyed by name to ensure uniqueness, consistent with the AcceptRisk type definition.

Also applies to: 11685-11685


28977-28977: Console capability descriptions correctly updated.

The descriptions now clearly enumerate the available capability values (LightspeedButton, GettingStartedBanner, GuidedTour).

Also applies to: 29626-29626

operator/v1/types_network.go (5)

400-405: LGTM: Helpful maintainer note for GA graduation.

This comment clearly documents the upgrade path and rationale for not including the default in the schema during TechPreview.


482-510: LGTM: Well-structured feature-gated fields with appropriate immutability constraints.

  • DefaultNetworkTransport: Correctly enforces set-once semantics at installation time.
  • DefaultNetworkNoOverlayOptions: Field removal prevention at struct level (line 411) complements the feature gate.
  • BGPManagedConfig: The XValidation at line 508 allows setting on day 2 but makes the entire struct immutable once bgpTopology is populated, which provides a sensible "configure once" pattern.

The omitzero,omitempty JSON tags are appropriate for optional feature-gated structs.


941-972: LGTM: Type definitions follow established patterns.

The typed string enums and their corresponding constants are consistent with existing patterns in this file (e.g., IPsecMode, SDNMode, RouteAdvertisementsEnablement).


974-997: LGTM: NoOverlayOptions validation rules are well-designed.

  • OutboundSNAT: The installation-time constraint requiring "Enabled" (line 983) with subsequent mutability is a practical pattern allowing initial conservatism with day-2 tuning flexibility.
  • Routing: Full immutability via self == oldSelf (line 994) is appropriate given topology changes would be disruptive.

Both fields use the standard kubebuilder pattern of +required for OpenAPI schema generation combined with omitempty for JSON serialization.


999-1018: LGTM: BGPManagedConfig provides sensible defaults and constraints.

  • ASNumber: The range 1-4294967295 covers both 2-byte and 4-byte ASNs, and default 64512 is appropriately in the private ASN range (64512-65534).
  • BGPTopology: Currently constrained to FullMesh with room to extend via the enum.

Note that per the design discussion, immutability is enforced at the field level (line 508) rather than within this struct, making the entire BGPManagedConfig immutable once bgpTopology is populated.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +57948 to +57967
"defaultNetworkTransport": {
SchemaProps: spec.SchemaProps{
Description: "defaultNetworkTransport describes the transport protocol for east-west traffic for the default network. Allowed values are \"NoOverlay\" and \"Geneve\". When set to \"NoOverlay\", the default network operates in no-overlay mode. When set to \"Geneve\", the default network uses Geneve overlay. When omitted, this means the user has no opinion and the platform chooses a reasonable default which is subject to change over time. The current default is \"Geneve\". This field can only be set at installation time and cannot be changed afterwards.",
Type: []string{"string"},
Format: "",
},
},
"defaultNetworkNoOverlayOptions": {
SchemaProps: spec.SchemaProps{
Description: "defaultNetworkNoOverlayOptions contains configuration for no-overlay mode for the default network. It is required when DefaultNetworkTransport is \"NoOverlay\". When omitted, this means the user does not configure no-overlay mode options.",
Default: map[string]interface{}{},
Ref: ref("github.com/openshift/api/operator/v1.NoOverlayOptions"),
},
},
"bgpManagedConfig": {
SchemaProps: spec.SchemaProps{
Description: "bgpManagedConfig configures the BGP properties for networks (default network or CUDNs) in no-overlay mode that specify routing=\"Managed\" in their NoOverlayOptions. It is required when DefaultNetworkNoOverlayOptions.Routing is set to \"Managed\". When omitted, this means the user does not configure BGP for managed routing. This field can be set once, either at installation time or on day 2, and is immutable thereafter.",
Default: map[string]interface{}{},
Ref: ref("github.com/openshift/api/operator/v1.BGPManagedConfig"),
},
Copy link

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:

#!/bin/bash
# Find the source file for OVNKubernetesConfig (likely in operator/v1)
find . -type f -name "*.go" | xargs rg -l "type OVNKubernetesConfig" | grep -v zz_generated | head -5

Repository: openshift/api

Length of output: 170


🏁 Script executed:

#!/bin/bash
# Search for OVNKubernetesConfig definition
rg -A 20 "type OVNKubernetesConfig struct" --type go | grep -v zz_generated | head -40

Repository: openshift/api

Length of output: 170


🏁 Script executed:

#!/bin/bash
# Look for NoOverlayOptions and BGPManagedConfig types
rg "type NoOverlayOptions|type BGPManagedConfig" --type go | grep -v zz_generated

Repository: openshift/api

Length of output: 176


🏁 Script executed:

#!/bin/bash
# Read the types_network.go file to see NoOverlayOptions and BGPManagedConfig definitions
wc -l operator/v1/types_network.go

Repository: openshift/api

Length of output: 90


🏁 Script executed:

#!/bin/bash
# Find OVNKubernetesConfig in types_network.go
rg -B 5 -A 30 "type OVNKubernetesConfig struct" operator/v1/types_network.go

Repository: openshift/api

Length of output: 2647


🏁 Script executed:

#!/bin/bash
# Find NoOverlayOptions definition
rg -A 20 "type NoOverlayOptions struct" operator/v1/types_network.go

Repository: openshift/api

Length of output: 1489


🏁 Script executed:

#!/bin/bash
# Find BGPManagedConfig definition
rg -A 20 "type BGPManagedConfig struct" operator/v1/types_network.go

Repository: openshift/api

Length of output: 812


🏁 Script executed:

#!/bin/bash
# Find the defaultNetworkTransport, defaultNetworkNoOverlayOptions, bgpManagedConfig field definitions in OVNKubernetesConfig
rg -A 5 "defaultNetworkTransport|defaultNetworkNoOverlayOptions|bgpManagedConfig" operator/v1/types_network.go | head -60

Repository: openshift/api

Length of output: 3552


🏁 Script executed:

#!/bin/bash
# Check if there's an enum defined for DefaultNetworkTransport or NetworkTransportType
rg "type.*NetworkTransport|Enum.*NoOverlay|Enum.*Geneve" operator/v1/types_network.go

Repository: openshift/api

Length of output: 106


🏁 Script executed:

#!/bin/bash
# Read the generated OpenAPI file to see the actual defaults
sed -n '57948,57967p' openapi/generated_openapi/zz_generated.openapi.go

Repository: openshift/api

Length of output: 1908


🏁 Script executed:

#!/bin/bash
# Look for the full definitions of these fields in generated file
sed -n '57945,57990p' openapi/generated_openapi/zz_generated.openapi.go

Repository: openshift/api

Length of output: 3503


Add missing enum constraint for defaultNetworkTransport and review auto-generated defaults for complex types.

The generated OpenAPI is missing the Enum constraint for defaultNetworkTransport despite the source defining +kubebuilder:validation:Enum=NoOverlay;Geneve. Additionally, defaultNetworkNoOverlayOptions and bgpManagedConfig are being generated with Default: map[string]interface{}{} even though the source has no +kubebuilder:default annotations and marks both fields as +optional. Since NoOverlayOptions and BGPManagedConfig have required subfields (OutboundSNAT/Routing and BGPTopology respectively), defaulting to empty objects creates invalid default states that contradict the documented behavior that "when omitted, the user does not configure" these options. Ensure the OpenAPI generator includes the enum constraint and re-evaluate whether these complex optional types should have defaults.

🤖 Prompt for AI Agents
In `@openapi/generated_openapi/zz_generated.openapi.go` around lines 57948 -
57967, The OpenAPI output is missing the Enum for defaultNetworkTransport and is
incorrectly emitting empty-object defaults for complex optional fields; update
the generation so that the schema for "defaultNetworkTransport" includes Enum:
[]string{"NoOverlay","Geneve"} (match the +kubebuilder:validation:Enum tag) and
remove the Default: map[string]interface{}{} entries for
"defaultNetworkNoOverlayOptions" and "bgpManagedConfig" so they remain optional
with no default; ensure the refs still point to NoOverlayOptions and
BGPManagedConfig (Ref:
ref("github.com/openshift/api/operator/v1.NoOverlayOptions") and
ref("github.com/openshift/api/operator/v1.BGPManagedConfig")) and adjust the
OpenAPI generator or struct tags so required subfields inside those types are
validated only when the object is present.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 16, 2026

@ricky-rav: all tests passed!

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.

This commit introduces API changes to support OVN-Kubernetes no-overlay mode for the default network,
where the cluster default network operates without overlay encapsulation (Geneve).

API changes (operator.openshift.io/v1):
- Added defaultNetworkTransport field to OVNKubernetesConfig (NoOverlay or Geneve)
- Added defaultNetworkNoOverlayOptions with outboundSNAT and routing configuration
- Added bgpManagedConfig for BGP configuration when routing is managed
- All no-overlay fields are immutable after cluster creation

Added feature gate (TechPreviewNoUpgrade) for NoOverlayMode within the Networking/ovn-kubernetes component.

Ran these commands to update autogenerated source files:
$ hack/update-codegen-crds.sh
$ hack/update-swagger-docs.sh
$ hack/update-payload-featuregates.sh

Openshift enhancement for this feature: openshift/enhancements#1859

Signed-off-by: Riccardo Ravaioli <rravaiol@redhat.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@openapi/openapi.json`:
- Around line 5875-5886: The schema for the conditionalUpdateRisks array lacks
the documented 500-item cap; update the source Go type that defines the
conditionalUpdateRisks field (the slice of ConditionalUpdateRisk referenced by
spec.desiredUpdate) to add the Kubernetes validation tag for max items (e.g. the
kubebuilder/validation tag that sets MaxItems=500) so OpenAPI generation emits
"maxItems": 500 for conditionalUpdateRisks; after adding the tag, regenerate the
OpenAPI/CRD to verify the maxItems appears in openapi.json.
- Around line 6094-6102: The riskNames array schema lacks the size and
entry-length constraints described; update the "riskNames" definition to include
"maxItems": 500 on the array and add "maxLength": 256 to the array "items" (the
string schema) so each entry is capped at 256 characters; keep the existing
"x-kubernetes-list-type": "set" for uniqueness and ensure you modify the
"riskNames" object and its "items" schema (referencing the "riskNames" symbol
and its "items" child) to enforce these limits.
- Around line 6129-6140: The "conditions" array schema lacks a maxItems
constraint even though the docs say it must not contain more than one entry; add
a maxItems: 1 constraint for the conditions field (the array that references
io.k8s.apimachinery.pkg.apis.meta.v1.Condition) by adding the appropriate
validation annotation in the Go source (e.g. add a kubebuilder/api validation
tag like "+kubebuilder:validation:MaxItems:=1" or the equivalent OpenAPI
generation tag immediately above the Conditions field definition) so the
generated openapi.json includes "maxItems": 1 for the "conditions" property.
- Around line 4575-4586: The OpenAPI schema for AcceptRisk currently documents
constraints for AcceptRisk.name but doesn't enforce them; update the Go struct
definition for type AcceptRisk by adding validation tags (e.g.,
`validate:"min=1,max=256"` or the project's preferred kube/openapi tags) on the
Name field so the generated OpenAPI includes minLength: 1 and maxLength: 256,
then run the OpenAPI generation step to regenerate openapi.json so the schema
for AcceptRisk.name is updated accordingly.
- Around line 11639-11649: The openapi schema for the array field "acceptRisks"
is missing the documented 1000-item cap; update the source Go struct for the
field (the AcceptRisks slice referenced by the definition
com.github.openshift.api.config.v1.AcceptRisk / the AcceptRisks field) to add
the Kubernetes validation tag to enforce the limit (e.g. add a
+kubebuilder:validation:MaxItems=1000 comment above the AcceptRisks field) so
the generated OpenAPI JSON includes "maxItems": 1000 for acceptRisks.
♻️ Duplicate comments (6)
openapi/generated_openapi/zz_generated.openapi.go (2)

56931-56957: Enum constraints still missing from NoOverlayOptions schema.

The outboundSNAT and routing fields are still missing their Enum constraints as noted in the previous review.


57948-57968: Missing enum and problematic defaults still present.

The issues flagged in the previous review remain:

  • defaultNetworkTransport missing Enum constraint for "NoOverlay"/"Geneve"
  • defaultNetworkNoOverlayOptions and bgpManagedConfig have Default: map[string]interface{}{} which creates invalid default states since both types have required subfields
operator/v1/types_network.go (1)

408-413: Add inverse validation to forbid no-overlay fields unless transport is NoOverlay.

Right now, defaultNetworkNoOverlayOptions and bgpManagedConfig can be set even when defaultNetworkTransport is omitted or Geneve, which allows contradictory-but-accepted configs (Line 408–413). Please add the inverse constraints.

Proposed validation additions
 // +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.defaultNetworkTransport) || self.defaultNetworkTransport != 'NoOverlay' || has(self.defaultNetworkNoOverlayOptions)",message="defaultNetworkNoOverlayOptions is required when defaultNetworkTransport is NoOverlay"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.defaultNetworkNoOverlayOptions) || (has(self.defaultNetworkTransport) && self.defaultNetworkTransport == 'NoOverlay')",message="defaultNetworkNoOverlayOptions is forbidden when defaultNetworkTransport is not NoOverlay"
 // +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.defaultNetworkNoOverlayOptions) || self.defaultNetworkNoOverlayOptions.routing != 'Managed' || has(self.bgpManagedConfig)",message="bgpManagedConfig is required when defaultNetworkNoOverlayOptions.routing is Managed"
+// +openshift:validation:FeatureGateAwareXValidation:featureGate=NoOverlayMode,rule="!has(self.bgpManagedConfig) || (has(self.defaultNetworkTransport) && self.defaultNetworkTransport == 'NoOverlay')",message="bgpManagedConfig is forbidden when defaultNetworkTransport is not NoOverlay"
openapi/openapi.json (3)

28702-28717: Duplicate: missing enum/min/max validation in BGPManagedConfig.


33091-33106: Duplicate: missing enums for NoOverlayOptions fields.


33625-33638: Duplicate: default {} and missing enum in OVNKubernetesConfig.

🧹 Nitpick comments (1)
openapi/openapi.json (1)

11334-11352: Validate or clarify allowed values for TLSProfile.type.

Line 11350 describes a closed set of values, but the schema allows any string. If this is not intentional for forward compatibility, consider adding an enum (including "" if “unspecified” is valid). If it is intentional, consider clarifying the description.

Comment on lines +4575 to +4586
"com.github.openshift.api.config.v1.AcceptRisk": {
"description": "AcceptRisk represents a risk that is considered acceptable.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"description": "name is the name of the acceptable risk. It must be a non-empty string and must not exceed 256 characters.",
"type": "string"
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add length constraints for AcceptRisk.name.

Line 4583 states the name must be non-empty and ≤256 chars, but the schema does not enforce this. Add min/max length validation in the source Go type and regenerate the OpenAPI.

🔧 Suggested schema shape (apply via Go validation tags)
        "name": {
          "description": "name is the name of the acceptable risk. It must be a non-empty string and must not exceed 256 characters.",
-         "type": "string"
+         "type": "string",
+         "minLength": 1,
+         "maxLength": 256
        }
📝 Committable suggestion

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

Suggested change
"com.github.openshift.api.config.v1.AcceptRisk": {
"description": "AcceptRisk represents a risk that is considered acceptable.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"description": "name is the name of the acceptable risk. It must be a non-empty string and must not exceed 256 characters.",
"type": "string"
}
}
"com.github.openshift.api.config.v1.AcceptRisk": {
"description": "AcceptRisk represents a risk that is considered acceptable.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"description": "name is the name of the acceptable risk. It must be a non-empty string and must not exceed 256 characters.",
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
🤖 Prompt for AI Agents
In `@openapi/openapi.json` around lines 4575 - 4586, The OpenAPI schema for
AcceptRisk currently documents constraints for AcceptRisk.name but doesn't
enforce them; update the Go struct definition for type AcceptRisk by adding
validation tags (e.g., `validate:"min=1,max=256"` or the project's preferred
kube/openapi tags) on the Name field so the generated OpenAPI includes
minLength: 1 and maxLength: 256, then run the OpenAPI generation step to
regenerate openapi.json so the schema for AcceptRisk.name is updated
accordingly.

Comment on lines +5875 to +5886
"conditionalUpdateRisks": {
"description": "conditionalUpdateRisks contains the list of risks associated with conditionalUpdates. When performing a conditional update, all its associated risks will be compared with the set of accepted risks in the spec.desiredUpdate.acceptRisks field. If all risks for a conditional update are included in the spec.desiredUpdate.acceptRisks set, the conditional update can proceed, otherwise it is blocked. The risk names in the list must be unique. conditionalUpdateRisks must not contain more than 500 entries.",
"type": "array",
"items": {
"default": {},
"$ref": "#/definitions/com.github.openshift.api.config.v1.ConditionalUpdateRisk"
},
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Enforce the documented 500-item cap for conditionalUpdateRisks.

Line 5876 says the list must not contain more than 500 entries, but there’s no maxItems. Add the validation in the source type so it appears in OpenAPI.

🔧 Suggested schema shape (apply via Go validation tags)
        "conditionalUpdateRisks": {
          "description": "conditionalUpdateRisks contains the list of risks associated with conditionalUpdates. ... conditionalUpdateRisks must not contain more than 500 entries.",
          "type": "array",
+         "maxItems": 500,
          "items": {
            "default": {},
            "$ref": "#/definitions/com.github.openshift.api.config.v1.ConditionalUpdateRisk"
          },
📝 Committable suggestion

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

Suggested change
"conditionalUpdateRisks": {
"description": "conditionalUpdateRisks contains the list of risks associated with conditionalUpdates. When performing a conditional update, all its associated risks will be compared with the set of accepted risks in the spec.desiredUpdate.acceptRisks field. If all risks for a conditional update are included in the spec.desiredUpdate.acceptRisks set, the conditional update can proceed, otherwise it is blocked. The risk names in the list must be unique. conditionalUpdateRisks must not contain more than 500 entries.",
"type": "array",
"items": {
"default": {},
"$ref": "#/definitions/com.github.openshift.api.config.v1.ConditionalUpdateRisk"
},
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
},
"conditionalUpdateRisks": {
"description": "conditionalUpdateRisks contains the list of risks associated with conditionalUpdates. When performing a conditional update, all its associated risks will be compared with the set of accepted risks in the spec.desiredUpdate.acceptRisks field. If all risks for a conditional update are included in the spec.desiredUpdate.acceptRisks set, the conditional update can proceed, otherwise it is blocked. The risk names in the list must be unique. conditionalUpdateRisks must not contain more than 500 entries.",
"type": "array",
"maxItems": 500,
"items": {
"default": {},
"$ref": "#/definitions/com.github.openshift.api.config.v1.ConditionalUpdateRisk"
},
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
},
🤖 Prompt for AI Agents
In `@openapi/openapi.json` around lines 5875 - 5886, The schema for the
conditionalUpdateRisks array lacks the documented 500-item cap; update the
source Go type that defines the conditionalUpdateRisks field (the slice of
ConditionalUpdateRisk referenced by spec.desiredUpdate) to add the Kubernetes
validation tag for max items (e.g. the kubebuilder/validation tag that sets
MaxItems=500) so OpenAPI generation emits "maxItems": 500 for
conditionalUpdateRisks; after adding the tag, regenerate the OpenAPI/CRD to
verify the maxItems appears in openapi.json.

Comment on lines +6094 to +6102
"riskNames": {
"description": "riskNames represents the set of the names of conditionalUpdateRisks that are relevant to this update for some clusters. The Applies condition of each conditionalUpdateRisks entry declares if that risk applies to this cluster. A conditional update is accepted only if each of its risks either does not apply to the cluster or is considered acceptable by the cluster administrator. The latter means that the risk names are included in value of the spec.desiredUpdate.acceptRisks field. Entries must be unique and must not exceed 256 characters. riskNames must not contain more than 500 entries.",
"type": "array",
"items": {
"type": "string",
"default": ""
},
"x-kubernetes-list-type": "set"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Constrain riskNames entries to match the description.

Line 6095 says entries must be unique, ≤256 chars, and the list must not exceed 500 items. Uniqueness is handled by x-kubernetes-list-type: set, but length and size caps are missing.

🔧 Suggested schema shape (apply via Go validation tags)
        "riskNames": {
          "description": "riskNames represents the set ... Entries must be unique and must not exceed 256 characters. riskNames must not contain more than 500 entries.",
          "type": "array",
+         "maxItems": 500,
          "items": {
            "type": "string",
-           "default": ""
+           "default": "",
+           "minLength": 1,
+           "maxLength": 256
          },
          "x-kubernetes-list-type": "set"
        },
🤖 Prompt for AI Agents
In `@openapi/openapi.json` around lines 6094 - 6102, The riskNames array schema
lacks the size and entry-length constraints described; update the "riskNames"
definition to include "maxItems": 500 on the array and add "maxLength": 256 to
the array "items" (the string schema) so each entry is capped at 256 characters;
keep the existing "x-kubernetes-list-type": "set" for uniqueness and ensure you
modify the "riskNames" object and its "items" schema (referencing the
"riskNames" symbol and its "items" child) to enforce these limits.

Comment on lines +6129 to +6140
"conditions": {
"description": "conditions represents the observations of the conditional update risk's current status. Known types are: * Applies, for whether the risk applies to the current cluster. The condition's types in the list must be unique. conditions must not contain more than one entry.",
"type": "array",
"items": {
"default": {},
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Condition"
},
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Limit conditions to a single entry as documented.

Line 6130 says the list must not contain more than one entry, but no maxItems is present. Add it in the source schema.

🔧 Suggested schema shape (apply via Go validation tags)
        "conditions": {
          "description": "conditions represents the observations ... conditions must not contain more than one entry.",
          "type": "array",
+         "maxItems": 1,
          "items": {
            "default": {},
            "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Condition"
          },
🤖 Prompt for AI Agents
In `@openapi/openapi.json` around lines 6129 - 6140, The "conditions" array schema
lacks a maxItems constraint even though the docs say it must not contain more
than one entry; add a maxItems: 1 constraint for the conditions field (the array
that references io.k8s.apimachinery.pkg.apis.meta.v1.Condition) by adding the
appropriate validation annotation in the Go source (e.g. add a kubebuilder/api
validation tag like "+kubebuilder:validation:MaxItems:=1" or the equivalent
OpenAPI generation tag immediately above the Conditions field definition) so the
generated openapi.json includes "maxItems": 1 for the "conditions" property.

Comment on lines +11639 to +11649
"acceptRisks": {
"description": "acceptRisks is an optional set of names of conditional update risks that are considered acceptable. A conditional update is performed only if all of its risks are acceptable. This list may contain entries that apply to current, previous or future updates. The entries therefore may not map directly to a risk in .status.conditionalUpdateRisks. acceptRisks must not contain more than 1000 entries. Entries in this list must be unique.",
"type": "array",
"items": {
"default": {},
"$ref": "#/definitions/com.github.openshift.api.config.v1.AcceptRisk"
},
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Enforce the documented 1000-item cap for acceptRisks.

Line 11640 says the list must not exceed 1000 entries, but no maxItems is present. Add it via source validation.

🔧 Suggested schema shape (apply via Go validation tags)
        "acceptRisks": {
          "description": "acceptRisks is an optional set ... acceptRisks must not contain more than 1000 entries.",
          "type": "array",
+         "maxItems": 1000,
          "items": {
            "default": {},
            "$ref": "#/definitions/com.github.openshift.api.config.v1.AcceptRisk"
          },
🤖 Prompt for AI Agents
In `@openapi/openapi.json` around lines 11639 - 11649, The openapi schema for the
array field "acceptRisks" is missing the documented 1000-item cap; update the
source Go struct for the field (the AcceptRisks slice referenced by the
definition com.github.openshift.api.config.v1.AcceptRisk / the AcceptRisks
field) to add the Kubernetes validation tag to enforce the limit (e.g. add a
+kubebuilder:validation:MaxItems=1000 comment above the AcceptRisks field) so
the generated OpenAPI JSON includes "maxItems": 1000 for acceptRisks.

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants