Skip to content

Add IPv6 and dual-stack networking support to GCP machine provider#2795

Open
barbacbd wants to merge 1 commit intoopenshift:masterfrom
barbacbd:installer-gcp-updates-mapi
Open

Add IPv6 and dual-stack networking support to GCP machine provider#2795
barbacbd wants to merge 1 commit intoopenshift:masterfrom
barbacbd:installer-gcp-updates-mapi

Conversation

@barbacbd
Copy link
Copy Markdown
Contributor

@barbacbd barbacbd commented Apr 6, 2026

Adds support for IPv6 and dual-stack network configurations in GCP machine provider specifications:

  • New StackType field (IPv4Only, DualStack) with IPv4Only as default
  • New IPv6Address field for static IPv6 address assignment
  • New IPv6AccessType field (External, Internal) to control IPv6 internet access
  • Comprehensive integration test suite for IPv6 network interface configurations

Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com

Note: This is a temporary commit. Migration from MAPI to CAPI is in place for compute nodes. If it turns out that these changes are still required after the migration, then this can be changed.

  Adds support for IPv6 and dual-stack network configurations in GCP machine provider specifications:
  - New StackType field (IPv4Only, DualStack) with IPv4Only as default
  - New IPv6Address field for static IPv6 address assignment
  - New IPv6AccessType field (External, Internal) to control IPv6 internet access
  - Comprehensive integration test suite for IPv6 network interface configurations

  Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Note: This is a temporary commit. Migration from MAPI to CAPI is in place for compute nodes.
If it turns out that these changes are still required after the migration, then this can
be changed.
@openshift-ci-robot
Copy link
Copy Markdown

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@barbacbd
Copy link
Copy Markdown
Contributor Author

barbacbd commented Apr 6, 2026

/hold

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 6, 2026

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

@openshift-ci openshift-ci bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 6, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 6, 2026

📝 Walkthrough

Walkthrough

This pull request adds IPv6 network interface support for GCP machines. It introduces two new public string enum types (StackType and IPv6AccessType) with defined constants in types_gcpprovider.go. The GCPNetworkInterface struct is extended with three new optional fields: StackType (supporting IPv4Only and DualStack values), IPv6Address, and IPv6AccessType (supporting External and Internal values). A comprehensive test suite file is added that covers creation and update scenarios for GCP machines with IPv6 configuration, including validation of field combinations and state transitions. Auto-generated Swagger documentation is updated to reflect the new fields.

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

Warning

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

🔧 golangci-lint (2.11.4)

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-ci openshift-ci bot requested review from everettraven and mandre April 6, 2026 14:00
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 6, 2026

[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 deads2k for approval. For more information see the Code Review Process.

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

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

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

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add IPv6 and dual-stack networking support to GCP machine provider

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Add IPv6 and dual-stack network stack support to GCP
• Introduce StackType field with IPv4Only and DualStack options
• Add IPv6Address field for static IPv6 address assignment
• Add IPv6AccessType field controlling IPv6 internet access
• Comprehensive integration test suite for IPv6 configurations
Diagram
flowchart LR
  A["GCPNetworkInterface"] -->|adds| B["StackType field<br/>IPv4Only/DualStack"]
  A -->|adds| C["IPv6Address field<br/>static IPv6 assignment"]
  A -->|adds| D["IPv6AccessType field<br/>External/Internal"]
  B -->|validated by| E["Kubebuilder enums"]
  C -->|optional| F["Auto-assign if DualStack"]
  D -->|optional| G["Defaults to External"]
  H["Test Suite"] -->|validates| B
  H -->|validates| C
  H -->|validates| D
Loading

Grey Divider

File Changes

1. machine/v1beta1/types_gcpprovider.go ✨ Enhancement +46/-0

Add IPv6 type definitions and network interface fields

• Define StackType enum with IPv4Only and DualStack constants
• Define IPv6AccessType enum with External and Internal constants
• Add stackType field to GCPNetworkInterface with IPv4Only default
• Add ipv6Address field for static IPv6 address configuration
• Add ipv6AccessType field for IPv6 internet access control

machine/v1beta1/types_gcpprovider.go


2. machine/v1beta1/zz_generated.swagger_doc_generated.go 📝 Documentation +8/-5

Update swagger documentation for IPv6 fields

• Update swagger documentation map for GCPNetworkInterface
• Add documentation entries for stackType field
• Add documentation entries for ipv6Address field
• Add documentation entries for ipv6AccessType field

machine/v1beta1/zz_generated.swagger_doc_generated.go


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

Add OpenAPI schema definitions for IPv6 fields

• Add stackType schema with IPv4Only default value
• Add ipv6Address schema for IPv6 address configuration
• Add ipv6AccessType schema with External default value
• Include field descriptions and type specifications

openapi/generated_openapi/zz_generated.openapi.go


View more (1)
4. machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml 🧪 Tests +555/-0

Add comprehensive IPv6 network interface test suite

• Add 10 onCreate test cases covering IPv4Only, DualStack, static IPv6, and multiple interfaces
• Add validation tests for invalid stackType and ipv6AccessType values
• Add default value tests for stackType and ipv6AccessType
• Add 6 onUpdate test cases for stack type transitions and IPv6 configuration changes

machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Apr 6, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (2) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider


Action required

1. New fields lack FeatureGate 📘 Rule violation ⚙ Maintainability
Description
The new stackType, ipv6Address, and ipv6AccessType fields are added to the stable
machine.openshift.io/v1beta1 API without any +openshift:enable:FeatureGate=... marker to gate
rollout. This can introduce behavior changes without a controlled enablement mechanism across
cluster profiles.
Code

machine/v1beta1/types_gcpprovider.go[R292-312]

+	// stackType determines the IP stack configuration for the network interface.
+	// This field defaults to IPv4Only. Valid values are "IPv4Only" and "DualStack".
+	//
+	// +kubebuilder:default:="IPv4Only"
+	// +optional
+	// +default="IPv4Only"
+	StackType StackType `json:"stackType,omitempty"`
+
+	// ipv6Address is an IPv6 internal network address for this network interface.
+	// To use a static internal IP address, it must be unused and in the same region as the instance's zone.
+	// If not specified and stackType is "DualStack", Google Cloud can automatically assign an internal IPv6 address.
+	// +optional
+	IPv6Address string `json:"ipv6Address,omitempty"`
+
+	// ipv6AccessType indicates whether the IPv6 endpoint can be accessed from the Internet.
+	// Valid values are "External" or "Internal". Only valid when stackType is "DualStack".
+	//
+	// +kubebuilder:default:="External"
+	// +optional
+	// +default="External"
+	IPv6AccessType IPv6AccessType `json:"ipv6AccessType,omitempty"`
Evidence
PR Compliance ID 2 requires new fields on stable APIs to be feature-gated via a FeatureGate marker,
but the added fields show kubebuilder markers/defaults and no +openshift:enable:FeatureGate=...
annotation.

AGENTS.md
machine/v1beta1/types_gcpprovider.go[292-312]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New fields were added to `machine.openshift.io/v1beta1` without feature-gating, which violates the requirement to gate stable-API field additions.

## Issue Context
Fields added: `stackType`, `ipv6Address`, `ipv6AccessType`. They currently have kubebuilder defaults/optionality but no `+openshift:enable:FeatureGate=...` marker.

## Fix Focus Areas
- machine/v1beta1/types_gcpprovider.go[292-312]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. ipv6AccessType constraint unenforced 📘 Rule violation ≡ Correctness
Description
The API comment states ipv6AccessType is "Only valid when stackType is \"DualStack\"", but there
is no XValidation/CEL rule enforcing this relationship. This allows invalid combinations (e.g.,
stackType: IPv4Only with ipv6AccessType set) to pass schema validation.
Code

machine/v1beta1/types_gcpprovider.go[R306-312]

+	// ipv6AccessType indicates whether the IPv6 endpoint can be accessed from the Internet.
+	// Valid values are "External" or "Internal". Only valid when stackType is "DualStack".
+	//
+	// +kubebuilder:default:="External"
+	// +optional
+	// +default="External"
+	IPv6AccessType IPv6AccessType `json:"ipv6AccessType,omitempty"`
Evidence
PR Compliance ID 6 requires that documented cross-field relationships be enforced with validation
rules; the code documents a cross-field constraint for ipv6AccessType but adds no
+kubebuilder:validation:XValidation (or equivalent) to enforce it.

AGENTS.md
machine/v1beta1/types_gcpprovider.go[306-312]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`ipv6AccessType` is documented as only valid when `stackType` is `DualStack`, but this is not enforced by schema validation.

## Issue Context
Without cross-field validation, invalid specs may be accepted and fail later at runtime.

## Fix Focus Areas
- machine/v1beta1/types_gcpprovider.go[306-312]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. ProviderSpec validation tests invalid 🐞 Bug ≡ Correctness
Description
IPv6NetworkInterface.yaml expects the apiserver to reject invalid stackType/ipv6AccessType and to
default stackType inside spec.providerSpec.value, but providerSpec.value is preserved-unknown
RawExtension so nested validation/defaulting is not applied. These new test cases will fail because
the API server will accept invalid nested fields and will not inject stackType defaults.
Code

machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml[R214-312]

+  - name: Should reject invalid stackType value
+    initial: |
+      apiVersion: machine.openshift.io/v1beta1
+      kind: Machine
+      spec:
+        providerSpec:
+          value:
+            apiVersion: machine.openshift.io/v1beta1
+            kind: GCPMachineProviderSpec
+            machineType: n1-standard-4
+            region: us-central1
+            zone: us-central1-a
+            networkInterfaces:
+            - network: test-network
+              subnetwork: test-subnet
+              stackType: InvalidStackType
+    expectedError: "spec.providerSpec.value.networkInterfaces[0].stackType: Unsupported value: \"InvalidStackType\": supported values: \"DualStack\", \"IPv4Only\""
+  - name: Should reject invalid ipv6AccessType value
+    initial: |
+      apiVersion: machine.openshift.io/v1beta1
+      kind: Machine
+      spec:
+        providerSpec:
+          value:
+            apiVersion: machine.openshift.io/v1beta1
+            kind: GCPMachineProviderSpec
+            machineType: n1-standard-4
+            region: us-central1
+            zone: us-central1-a
+            networkInterfaces:
+            - network: test-network
+              subnetwork: test-subnet
+              stackType: DualStack
+              ipv6AccessType: InvalidAccessType
+    expectedError: "spec.providerSpec.value.networkInterfaces[0].ipv6AccessType: Unsupported value: \"InvalidAccessType\": supported values: \"External\", \"Internal\""
+  - name: Should be able to create a GCP machine with IPv4Only and IPv6 fields omitted
+    initial: |
+      apiVersion: machine.openshift.io/v1beta1
+      kind: Machine
+      spec:
+        providerSpec:
+          value:
+            apiVersion: machine.openshift.io/v1beta1
+            kind: GCPMachineProviderSpec
+            machineType: n1-standard-4
+            region: us-central1
+            zone: us-central1-a
+            networkInterfaces:
+            - network: test-network
+              subnetwork: test-subnet
+              stackType: IPv4Only
+    expected: |
+      apiVersion: machine.openshift.io/v1beta1
+      kind: Machine
+      spec:
+        authoritativeAPI: MachineAPI
+        providerSpec:
+          value:
+            apiVersion: machine.openshift.io/v1beta1
+            kind: GCPMachineProviderSpec
+            machineType: n1-standard-4
+            region: us-central1
+            zone: us-central1-a
+            networkInterfaces:
+            - network: test-network
+              subnetwork: test-subnet
+              stackType: IPv4Only
+  - name: Should default stackType to IPv4Only when not specified
+    initial: |
+      apiVersion: machine.openshift.io/v1beta1
+      kind: Machine
+      spec:
+        providerSpec:
+          value:
+            apiVersion: machine.openshift.io/v1beta1
+            kind: GCPMachineProviderSpec
+            machineType: n1-standard-4
+            region: us-central1
+            zone: us-central1-a
+            networkInterfaces:
+            - network: test-network
+              subnetwork: test-subnet
+    expected: |
+      apiVersion: machine.openshift.io/v1beta1
+      kind: Machine
+      spec:
+        authoritativeAPI: MachineAPI
+        providerSpec:
+          value:
+            apiVersion: machine.openshift.io/v1beta1
+            kind: GCPMachineProviderSpec
+            machineType: n1-standard-4
+            region: us-central1
+            zone: us-central1-a
+            networkInterfaces:
+            - network: test-network
+              subnetwork: test-subnet
+              stackType: IPv4Only
+  onUpdate:
Evidence
Machine.Spec.ProviderSpec.Value is explicitly marked to preserve unknown fields, and the generated
Machine CRD sets x-kubernetes-preserve-unknown-fields on spec.providerSpec.value; therefore schema
validation/defaulting cannot be enforced for nested GCPMachineProviderSpec fields. The new test
suite nevertheless asserts enum validation errors and defaulting for stackType/ipv6AccessType under
spec.providerSpec.value.networkInterfaces.

machine/v1beta1/types_provider.go[9-21]
machine/v1beta1/zz_generated.crd-manifests/0000_10_machine-api_01_machines-Default.crd.yaml[294-306]
machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml[214-312]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new CRD integration tests assume server-side defaulting and enum validation for fields inside `spec.providerSpec.value` (e.g., `stackType`, `ipv6AccessType`). But `providerSpec.value` is a preserved-unknown `RawExtension`, so the apiserver will not apply nested schema/defaults/enums.

## Issue Context
These tests run against envtest’s real apiserver and therefore only reflect CRD schema behavior. With `x-kubernetes-preserve-unknown-fields: true`, invalid nested values will be accepted and missing nested fields will not be defaulted.

## Fix Focus Areas
- machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml[214-312]

### What to change
- Remove or rewrite the test cases that expect:
 - rejection of invalid `stackType` / `ipv6AccessType`
 - defaulting of `stackType` when omitted
- Replace them with tests that assert **pass-through preservation** (i.e., what is sent is what is stored), or (if true validation/defaulting is required) move those assertions to where validation actually exists (e.g., a webhook/controller in the owning component) rather than CRD schema tests.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. IPv6Address lacks validation 🐞 Bug ☼ Reliability
Description
IPv6Address is described as an IPv6 address but has no schema validation markers
(length/format/pattern), allowing arbitrary strings and weakening API documentation. If/when this
type is used in a validated schema, missing validation will allow invalid specs through to runtime.
Code

machine/v1beta1/types_gcpprovider.go[R300-305]

+	// ipv6Address is an IPv6 internal network address for this network interface.
+	// To use a static internal IP address, it must be unused and in the same region as the instance's zone.
+	// If not specified and stackType is "DualStack", Google Cloud can automatically assign an internal IPv6 address.
+	// +optional
+	IPv6Address string `json:"ipv6Address,omitempty"`
+
Evidence
The new IPv6Address field has no validation annotations, while this repo demonstrates the common
pattern of adding at least length constraints (and optionally format guidance) for IPv6 strings in
API types.

machine/v1beta1/types_gcpprovider.go[300-305]
example/v1/types_stable.go[233-244]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`IPv6Address` is intended to hold an IPv6 address, but the API type provides no validation annotations. This reduces schema quality and allows invalid values.

## Issue Context
The repo already contains examples of IPv6 string fields with basic validation markers (e.g., MaxLength 45).

## Fix Focus Areas
- machine/v1beta1/types_gcpprovider.go[300-305]

### What to change
- Add basic validation markers to `IPv6Address` (at minimum `MaxLength=45`; optionally `MinLength=1` when provided).
- If stronger validation is desired, add a CEL-based validation rule consistent with the project’s approach (avoid relying solely on `Format=ipv6` if that’s not preferred here).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +292 to +312
// stackType determines the IP stack configuration for the network interface.
// This field defaults to IPv4Only. Valid values are "IPv4Only" and "DualStack".
//
// +kubebuilder:default:="IPv4Only"
// +optional
// +default="IPv4Only"
StackType StackType `json:"stackType,omitempty"`

// ipv6Address is an IPv6 internal network address for this network interface.
// To use a static internal IP address, it must be unused and in the same region as the instance's zone.
// If not specified and stackType is "DualStack", Google Cloud can automatically assign an internal IPv6 address.
// +optional
IPv6Address string `json:"ipv6Address,omitempty"`

// ipv6AccessType indicates whether the IPv6 endpoint can be accessed from the Internet.
// Valid values are "External" or "Internal". Only valid when stackType is "DualStack".
//
// +kubebuilder:default:="External"
// +optional
// +default="External"
IPv6AccessType IPv6AccessType `json:"ipv6AccessType,omitempty"`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. New fields lack featuregate 📘 Rule violation ⚙ Maintainability

The new stackType, ipv6Address, and ipv6AccessType fields are added to the stable
machine.openshift.io/v1beta1 API without any +openshift:enable:FeatureGate=... marker to gate
rollout. This can introduce behavior changes without a controlled enablement mechanism across
cluster profiles.
Agent Prompt
## Issue description
New fields were added to `machine.openshift.io/v1beta1` without feature-gating, which violates the requirement to gate stable-API field additions.

## Issue Context
Fields added: `stackType`, `ipv6Address`, `ipv6AccessType`. They currently have kubebuilder defaults/optionality but no `+openshift:enable:FeatureGate=...` marker.

## Fix Focus Areas
- machine/v1beta1/types_gcpprovider.go[292-312]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +306 to +312
// ipv6AccessType indicates whether the IPv6 endpoint can be accessed from the Internet.
// Valid values are "External" or "Internal". Only valid when stackType is "DualStack".
//
// +kubebuilder:default:="External"
// +optional
// +default="External"
IPv6AccessType IPv6AccessType `json:"ipv6AccessType,omitempty"`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. ipv6accesstype constraint unenforced 📘 Rule violation ≡ Correctness

The API comment states ipv6AccessType is "Only valid when stackType is \"DualStack\"", but there
is no XValidation/CEL rule enforcing this relationship. This allows invalid combinations (e.g.,
stackType: IPv4Only with ipv6AccessType set) to pass schema validation.
Agent Prompt
## Issue description
`ipv6AccessType` is documented as only valid when `stackType` is `DualStack`, but this is not enforced by schema validation.

## Issue Context
Without cross-field validation, invalid specs may be accepted and fail later at runtime.

## Fix Focus Areas
- machine/v1beta1/types_gcpprovider.go[306-312]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +214 to +312
- name: Should reject invalid stackType value
initial: |
apiVersion: machine.openshift.io/v1beta1
kind: Machine
spec:
providerSpec:
value:
apiVersion: machine.openshift.io/v1beta1
kind: GCPMachineProviderSpec
machineType: n1-standard-4
region: us-central1
zone: us-central1-a
networkInterfaces:
- network: test-network
subnetwork: test-subnet
stackType: InvalidStackType
expectedError: "spec.providerSpec.value.networkInterfaces[0].stackType: Unsupported value: \"InvalidStackType\": supported values: \"DualStack\", \"IPv4Only\""
- name: Should reject invalid ipv6AccessType value
initial: |
apiVersion: machine.openshift.io/v1beta1
kind: Machine
spec:
providerSpec:
value:
apiVersion: machine.openshift.io/v1beta1
kind: GCPMachineProviderSpec
machineType: n1-standard-4
region: us-central1
zone: us-central1-a
networkInterfaces:
- network: test-network
subnetwork: test-subnet
stackType: DualStack
ipv6AccessType: InvalidAccessType
expectedError: "spec.providerSpec.value.networkInterfaces[0].ipv6AccessType: Unsupported value: \"InvalidAccessType\": supported values: \"External\", \"Internal\""
- name: Should be able to create a GCP machine with IPv4Only and IPv6 fields omitted
initial: |
apiVersion: machine.openshift.io/v1beta1
kind: Machine
spec:
providerSpec:
value:
apiVersion: machine.openshift.io/v1beta1
kind: GCPMachineProviderSpec
machineType: n1-standard-4
region: us-central1
zone: us-central1-a
networkInterfaces:
- network: test-network
subnetwork: test-subnet
stackType: IPv4Only
expected: |
apiVersion: machine.openshift.io/v1beta1
kind: Machine
spec:
authoritativeAPI: MachineAPI
providerSpec:
value:
apiVersion: machine.openshift.io/v1beta1
kind: GCPMachineProviderSpec
machineType: n1-standard-4
region: us-central1
zone: us-central1-a
networkInterfaces:
- network: test-network
subnetwork: test-subnet
stackType: IPv4Only
- name: Should default stackType to IPv4Only when not specified
initial: |
apiVersion: machine.openshift.io/v1beta1
kind: Machine
spec:
providerSpec:
value:
apiVersion: machine.openshift.io/v1beta1
kind: GCPMachineProviderSpec
machineType: n1-standard-4
region: us-central1
zone: us-central1-a
networkInterfaces:
- network: test-network
subnetwork: test-subnet
expected: |
apiVersion: machine.openshift.io/v1beta1
kind: Machine
spec:
authoritativeAPI: MachineAPI
providerSpec:
value:
apiVersion: machine.openshift.io/v1beta1
kind: GCPMachineProviderSpec
machineType: n1-standard-4
region: us-central1
zone: us-central1-a
networkInterfaces:
- network: test-network
subnetwork: test-subnet
stackType: IPv4Only
onUpdate:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Providerspec validation tests invalid 🐞 Bug ≡ Correctness

IPv6NetworkInterface.yaml expects the apiserver to reject invalid stackType/ipv6AccessType and to
default stackType inside spec.providerSpec.value, but providerSpec.value is preserved-unknown
RawExtension so nested validation/defaulting is not applied. These new test cases will fail because
the API server will accept invalid nested fields and will not inject stackType defaults.
Agent Prompt
## Issue description
The new CRD integration tests assume server-side defaulting and enum validation for fields inside `spec.providerSpec.value` (e.g., `stackType`, `ipv6AccessType`). But `providerSpec.value` is a preserved-unknown `RawExtension`, so the apiserver will not apply nested schema/defaults/enums.

## Issue Context
These tests run against envtest’s real apiserver and therefore only reflect CRD schema behavior. With `x-kubernetes-preserve-unknown-fields: true`, invalid nested values will be accepted and missing nested fields will not be defaulted.

## Fix Focus Areas
- machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml[214-312]

### What to change
- Remove or rewrite the test cases that expect:
  - rejection of invalid `stackType` / `ipv6AccessType`
  - defaulting of `stackType` when omitted
- Replace them with tests that assert **pass-through preservation** (i.e., what is sent is what is stored), or (if true validation/defaulting is required) move those assertions to where validation actually exists (e.g., a webhook/controller in the owning component) rather than CRD schema tests.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml (1)

249-280: Consider adding edge case tests for IPv6 fields with IPv4Only stack type.

The test suite covers the main scenarios well, but could benefit from additional edge case tests:

  1. Setting ipv6Address when stackType: IPv4Only - to verify the field is ignored or rejected
  2. Transitioning from DualStack with ipv6Address to IPv4Only - to verify whether IPv6 fields are cleared

These tests would document the expected behavior when users misconfigure the IPv6 fields.

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

In
`@machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml`
around lines 249 - 280, Add two edge-case tests to the IPv6NetworkInterface
suite: (1) a test creating a Machine with spec.providerSpec.value.kind ==
GCPMachineProviderSpec where networkInterfaces[].stackType == IPv4Only but
networkInterfaces[].ipv6Address is set, asserting the API either rejects the
field or ignores it (validate returned Machine.networkInterfaces has no
ipv6Address); (2) a transition test that starts with a Machine having stackType
== DualStack and a populated ipv6Address, then updates the spec to stackType ==
IPv4Only and assert the controller clears or rejects the ipv6Address after
reconciliation; reference GCPMachineProviderSpec, networkInterfaces, stackType,
and ipv6Address when adding these test cases.
machine/v1beta1/types_gcpprovider.go (1)

306-312: Constraint is documented but not schema-enforced; consider alternative approaches.

The documentation correctly states that ipv6AccessType is "only valid when stackType is DualStack", but there's no schema-level validation to prevent users from setting ipv6AccessType when stackType is IPv4Only.

However, CEL-based validation (x-kubernetes-validations) is not used in this codebase, which relies on kubebuilder annotation-based validation (Enum, Pattern, MaxLength, etc.). Since ipv6AccessType is optional with a default, consider whether:

  1. The current approach of documenting the constraint and letting the field be set (with GCP API rejecting invalid combinations) is intentional and acceptable, or
  2. A stronger constraint is needed, in which case alternative approaches (such as dedicated validation middleware or improving field documentation) might be more aligned with the codebase patterns than CEL validation.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@machine/v1beta1/types_gcpprovider.go` around lines 306 - 312, The struct
allows IPv6AccessType to be set regardless of stackType, but the constraint
"only valid when stackType is DualStack" isn't enforced; either explicitly
accept this and strengthen the field doc comment or implement a schema-level
check by adding validation logic in the provider's webhook/validation methods
(e.g., the ValidateCreate/ValidateUpdate/ValidateDelete methods for the GCP
provider type) to reject requests where IPv6AccessType is non-empty/default and
StackType != "DualStack"; locate the IPv6AccessType and StackType fields in
types_gcpprovider.go and add the conditional check that returns a validation
error (with a clear message) when the combination is invalid.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml`:
- Around line 249-280: Add two edge-case tests to the IPv6NetworkInterface
suite: (1) a test creating a Machine with spec.providerSpec.value.kind ==
GCPMachineProviderSpec where networkInterfaces[].stackType == IPv4Only but
networkInterfaces[].ipv6Address is set, asserting the API either rejects the
field or ignores it (validate returned Machine.networkInterfaces has no
ipv6Address); (2) a transition test that starts with a Machine having stackType
== DualStack and a populated ipv6Address, then updates the spec to stackType ==
IPv4Only and assert the controller clears or rejects the ipv6Address after
reconciliation; reference GCPMachineProviderSpec, networkInterfaces, stackType,
and ipv6Address when adding these test cases.

In `@machine/v1beta1/types_gcpprovider.go`:
- Around line 306-312: The struct allows IPv6AccessType to be set regardless of
stackType, but the constraint "only valid when stackType is DualStack" isn't
enforced; either explicitly accept this and strengthen the field doc comment or
implement a schema-level check by adding validation logic in the provider's
webhook/validation methods (e.g., the
ValidateCreate/ValidateUpdate/ValidateDelete methods for the GCP provider type)
to reject requests where IPv6AccessType is non-empty/default and StackType !=
"DualStack"; locate the IPv6AccessType and StackType fields in
types_gcpprovider.go and add the conditional check that returns a validation
error (with a clear message) when the combination is invalid.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 1b11bd16-868c-4fbe-aafa-922ee055c365

📥 Commits

Reviewing files that changed from the base of the PR and between ad9eb11 and 7f681bb.

⛔ Files ignored due to path filters (1)
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**
📒 Files selected for processing (3)
  • machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml
  • machine/v1beta1/types_gcpprovider.go
  • machine/v1beta1/zz_generated.swagger_doc_generated.go

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 6, 2026

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

Test name Commit Details Required Rerun command
ci/prow/lint 7f681bb link true /test lint
ci/prow/integration 7f681bb link true /test integration

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants