Skip to content

CORS-4166: enable IPv6 IMDS endpoint and private DNS configuration for dualstack#177

Open
tthvo wants to merge 2 commits intoopenshift:mainfrom
tthvo:CORS-4166
Open

CORS-4166: enable IPv6 IMDS endpoint and private DNS configuration for dualstack#177
tthvo wants to merge 2 commits intoopenshift:mainfrom
tthvo:CORS-4166

Conversation

@tthvo
Copy link
Member

@tthvo tthvo commented Mar 3, 2026

Thus, this PR configures IPv6 IMDS and private DNS configuration when infrastructure CR status reports dualstack IP family variants. Since we don't add new features to MAPI, these changes follow the pattern in #171.

Motivation

Every EC2 instance receives a private hostname, which should provide both A and AAAA records for the IPv4 and IPv6 addresses of the instance. This is only supported via "resource-name" hostname type.

Additionally, any pods that needs to assume the node assigned IAM role should be able to contact the IMDS endpoint over IPv6. The endpoint must be enabled explicitly.

Summary by CodeRabbit

  • New Features

    • Instances now auto-configure instance metadata and private DNS options according to cluster infrastructure, with explicit support for dual-stack IPv6/IPv4 setups.
  • Refactor

    • Internal logic now derives metadata and DNS hostname options from infrastructure network settings while preserving previous nil/empty behavior when not applicable.
  • Tests

    • Expanded coverage for infra-driven dual-stack and single-stack scenarios validating metadata and DNS behaviors.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Mar 3, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 3, 2026

@tthvo: This pull request references CORS-4166 which is a valid jira issue.

Details

In response to this:

Thus, this PR configures IPv6 IMDS and private DNS configuration when infrastructure CR status reports dualstack IP family variants. Since we don't add new features to MAPI, these changes follow the pattern in #171.

Motivation

Every EC2 instance receives a private hostname, which should provide both A and AAAA records for the IPv4 and IPv6 addresses of the instance. This is only supported via "resource-name" hostname type.

Additionally, any pods that needs to assume the node assigned IAM role should be able to contact the IMDS endpoint over IPv6. The endpoint must be enabled explicitly.

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.

@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

Walkthrough

Instance metadata and Private DNS name options for EC2 RunInstances are now derived from the cluster Infrastructure IP family. New helper isAWSDualStack and getPrivateDNSNameOptionsRequest(infra) were added; getInstanceMetadataOptionsRequest now takes infra. launchInstance passes infra and conditionally applies these options.

Changes

Cohort / File(s) Summary
Core implementation
pkg/actuators/machine/instances.go
Changed getInstanceMetadataOptionsRequest signature to (..., infra *configv1.Infrastructure) and may set HttpProtocolIpv6 when infra indicates dual-stack. Added isAWSDualStack(infra *configv1.Infrastructure) bool and new getPrivateDNSNameOptionsRequest(infra *configv1.Infrastructure) *ec2.PrivateDnsNameOptionsRequest. launchInstance updated to pass infra and to include MetadataOptions and PrivateDnsNameOptions when helpers return non-nil. Helpers may return nil.
Tests
pkg/actuators/machine/instances_test.go
Expanded tests: new LaunchInstance cases for dual-stack IPv6Primary/IPv4Primary asserting MetadataOptions and PrivateDnsNameOptions in RunInstancesInput. Updated TestGetInstanceMetadataOptionsRequest to accept infra variants and added TestGetPrivateDNSNameOptionsRequest covering dual-stack, IPv4-only, and nil/empty infra cases. Adjusted call sites to pass infra.
sequenceDiagram
    participant Actuator as MachineActuator
    participant Infra as Infrastructure
    participant Helper as OptionsHelpers
    participant EC2 as AWS EC2 API

    Actuator->>Infra: read IP family (infra.Status.PlatformStatus...)
    Actuator->>Helper: getInstanceMetadataOptionsRequest(providerConfig, infra)
    Helper->>Infra: inspect IP family
    Helper-->>Actuator: InstanceMetadataOptionsRequest (or nil)
    Actuator->>Helper: getPrivateDNSNameOptionsRequest(infra)
    Helper->>Infra: inspect IP family
    Helper-->>Actuator: PrivateDnsNameOptionsRequest (or nil)
    Actuator->>EC2: RunInstances(Input with MetadataOptions?, PrivateDnsNameOptions?)
    EC2-->>Actuator: RunInstancesOutput / error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning Gomega assertions lack contextual failure messages and TestSortInstances contains no assertions to verify behavior. Add custom messages to all Gomega assertions and update TestSortInstances to explicitly assert sorted order or expected outcomes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Stable And Deterministic Test Names ✅ Passed All test case names in the modified test file are stable and deterministic, using only static descriptive strings without dynamic content.
Title check ✅ Passed The title accurately describes the main change: enabling IPv6 IMDS endpoint and private DNS configuration for dual-stack infrastructure, which matches the core functionality added across instances.go and its tests.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

❤️ Share

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

@openshift-ci openshift-ci bot requested review from mdbooth and racheljpg March 3, 2026 23:59
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 3, 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 racheljpg 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

@tthvo
Copy link
Member Author

tthvo commented Mar 4, 2026

/cc @nrb @sadasu @damdo

@openshift-ci openshift-ci bot requested review from damdo, nrb and sadasu March 4, 2026 00:00
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 4, 2026

@tthvo: This pull request references CORS-4166 which is a valid jira issue.

Details

In response to this:

Thus, this PR configures IPv6 IMDS and private DNS configuration when infrastructure CR status reports dualstack IP family variants. Since we don't add new features to MAPI, these changes follow the pattern in #171.

Motivation

Every EC2 instance receives a private hostname, which should provide both A and AAAA records for the IPv4 and IPv6 addresses of the instance. This is only supported via "resource-name" hostname type.

Additionally, any pods that needs to assume the node assigned IAM role should be able to contact the IMDS endpoint over IPv6. The endpoint must be enabled explicitly.

Summary by CodeRabbit

Release Notes

  • New Features

  • AWS instances now automatically configure metadata and DNS options based on infrastructure network settings, including support for dual-stack IPv6/IPv4 networking.

  • Refactor

  • Enhanced internal metadata and DNS naming configuration builders to support infrastructure-aware option handling.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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)
pkg/actuators/machine/instances.go (1)

791-795: Extract dual-stack infra detection to a shared helper.

The same nested infra/IPFamily check appears twice. Consolidating it avoids future drift and keeps both option builders in lockstep.

♻️ Suggested refactor
+func isDualStackAWSIPFamily(infra *configv1.Infrastructure) bool {
+	return infra != nil &&
+		infra.Status.PlatformStatus != nil &&
+		infra.Status.PlatformStatus.AWS != nil &&
+		(infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv6Primary ||
+			infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv4Primary)
+}
+
 func getInstanceMetadataOptionsRequest(providerConfig *machinev1beta1.AWSMachineProviderConfig, infra *configv1.Infrastructure) *ec2.InstanceMetadataOptionsRequest {
 	imdsOptions := &ec2.InstanceMetadataOptionsRequest{}
@@
-	if infra != nil && infra.Status.PlatformStatus != nil && infra.Status.PlatformStatus.AWS != nil {
-		if infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv6Primary || infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv4Primary {
-			imdsOptions.HttpProtocolIpv6 = ptr.To("enabled")
-		}
-	}
+	if isDualStackAWSIPFamily(infra) {
+		imdsOptions.HttpProtocolIpv6 = ptr.To("enabled")
+	}
@@
 func getPrivateDnsNameOptionsRequest(providerConfig *machinev1beta1.AWSMachineProviderConfig, infra *configv1.Infrastructure) *ec2.PrivateDnsNameOptionsRequest {
 	privateDnsNameOptions := &ec2.PrivateDnsNameOptionsRequest{}
 
-	if infra != nil && infra.Status.PlatformStatus != nil && infra.Status.PlatformStatus.AWS != nil {
-		if infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv6Primary || infra.Status.PlatformStatus.AWS.IPFamily == configv1.DualStackIPv4Primary {
-			privateDnsNameOptions.EnableResourceNameDnsARecord = ptr.To(true)
-			privateDnsNameOptions.EnableResourceNameDnsAAAARecord = ptr.To(true)
-			privateDnsNameOptions.HostnameType = ptr.To("resource-name")
-		}
-	}
+	if isDualStackAWSIPFamily(infra) {
+		privateDnsNameOptions.EnableResourceNameDnsARecord = ptr.To(true)
+		privateDnsNameOptions.EnableResourceNameDnsAAAARecord = ptr.To(true)
+		privateDnsNameOptions.HostnameType = ptr.To("resource-name")
+	}

Also applies to: 807-815

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

In `@pkg/actuators/machine/instances.go` around lines 791 - 795, Extract the
nested infra/IPFamily check into a shared helper (e.g., infraIsAWSDualStack or
supportsAWSDualStack) that accepts the infra object and returns a bool if infra
!= nil && infra.Status.PlatformStatus != nil && infra.Status.PlatformStatus.AWS
!= nil and AWS.IPFamily equals configv1.DualStackIPv6Primary or
configv1.DualStackIPv4Primary; then replace the duplicate blocks that set
imdsOptions.HttpProtocolIpv6 and the other option builder (the second block
around lines 807-815) to call this helper instead so both code paths use the
same centralized check.
pkg/actuators/machine/instances_test.go (1)

1480-1567: Consider one launch-path test that asserts both options are propagated together.

These helper tests are good; adding a single launchInstance dualstack case would catch regressions where one of the two helper outputs stops being wired into RunInstancesInput.

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

In `@pkg/actuators/machine/instances_test.go` around lines 1480 - 1567, Add a test
that ensures the dual-stack DNS options from getPrivateDnsNameOptionsRequest are
actually passed into the EC2 RunInstancesInput during launch; specifically add a
LaunchInstance/launchInstance test case that uses an infra with AWS.IPFamily set
to DualStackIPv6Primary or DualStackIPv4Primary, calls the function that builds
RunInstancesInput (the code path around launchInstance or whatever constructs
ec2.RunInstancesInput), and asserts that RunInstancesInput.PrivateDnsNameOptions
contains EnableResourceNameDnsARecord=true and
EnableResourceNameDnsAAAARecord=true and HostnameType="resource-name", so both
helper outputs are propagated together.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/actuators/machine/instances_test.go`:
- Around line 1480-1567: Add a test that ensures the dual-stack DNS options from
getPrivateDnsNameOptionsRequest are actually passed into the EC2
RunInstancesInput during launch; specifically add a
LaunchInstance/launchInstance test case that uses an infra with AWS.IPFamily set
to DualStackIPv6Primary or DualStackIPv4Primary, calls the function that builds
RunInstancesInput (the code path around launchInstance or whatever constructs
ec2.RunInstancesInput), and asserts that RunInstancesInput.PrivateDnsNameOptions
contains EnableResourceNameDnsARecord=true and
EnableResourceNameDnsAAAARecord=true and HostnameType="resource-name", so both
helper outputs are propagated together.

In `@pkg/actuators/machine/instances.go`:
- Around line 791-795: Extract the nested infra/IPFamily check into a shared
helper (e.g., infraIsAWSDualStack or supportsAWSDualStack) that accepts the
infra object and returns a bool if infra != nil && infra.Status.PlatformStatus
!= nil && infra.Status.PlatformStatus.AWS != nil and AWS.IPFamily equals
configv1.DualStackIPv6Primary or configv1.DualStackIPv4Primary; then replace the
duplicate blocks that set imdsOptions.HttpProtocolIpv6 and the other option
builder (the second block around lines 807-815) to call this helper instead so
both code paths use the same centralized check.

ℹ️ Review info

Configuration used: Repository: openshift/coderabbit/.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 bcf58df and 78a173d.

📒 Files selected for processing (2)
  • pkg/actuators/machine/instances.go
  • pkg/actuators/machine/instances_test.go

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 4, 2026

@tthvo: This pull request references CORS-4166 which is a valid jira issue.

Details

In response to this:

Thus, this PR configures IPv6 IMDS and private DNS configuration when infrastructure CR status reports dualstack IP family variants. Since we don't add new features to MAPI, these changes follow the pattern in #171.

Motivation

Every EC2 instance receives a private hostname, which should provide both A and AAAA records for the IPv4 and IPv6 addresses of the instance. This is only supported via "resource-name" hostname type.

Additionally, any pods that needs to assume the node assigned IAM role should be able to contact the IMDS endpoint over IPv6. The endpoint must be enabled explicitly.

Summary by CodeRabbit

  • New Features

  • Instances now auto-configure metadata and private DNS options based on cluster infrastructure, with explicit support for dual-stack IPv6/IPv4 setups.

  • Refactor

  • Internal configuration logic updated to derive metadata and DNS hostname options from infrastructure network settings, preserving previous nil/empty behavior when not applicable.

  • Tests

  • Expanded tests to cover infra-driven dual-stack and single-stack scenarios for metadata and DNS behaviors.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@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 (1)
pkg/actuators/machine/instances.go (1)

812-828: Unused providerConfig parameter.

The providerConfig parameter is accepted but never used in this function. If it's intended for future extensibility, consider documenting that intent. Otherwise, it could be removed to simplify the signature.

♻️ Optional: Remove unused parameter if not needed for future use
-func getPrivateDNSNameOptionsRequest(providerConfig *machinev1beta1.AWSMachineProviderConfig, infra *configv1.Infrastructure) *ec2.PrivateDnsNameOptionsRequest {
+func getPrivateDNSNameOptionsRequest(infra *configv1.Infrastructure) *ec2.PrivateDnsNameOptionsRequest {

This would also require updating the call site at line 522.

Note: If the parameter is kept for API consistency with getInstanceMetadataOptionsRequest or future extensibility, that's a valid reason to keep it.

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

In `@pkg/actuators/machine/instances.go` around lines 812 - 828, The function
getPrivateDNSNameOptionsRequest has an unused parameter providerConfig; either
remove providerConfig from the signature and update all callers to call
getPrivateDNSNameOptionsRequest() (adjust any call sites that currently pass a
providerConfig), or retain providerConfig but add a clear comment above
getPrivateDNSNameOptionsRequest explaining it is intentionally unused for API
consistency/future extensibility (and mark it with a linter-suppress or
underscore name if your linters require). Ensure any caller changes compile and
run tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/actuators/machine/instances.go`:
- Around line 812-828: The function getPrivateDNSNameOptionsRequest has an
unused parameter providerConfig; either remove providerConfig from the signature
and update all callers to call getPrivateDNSNameOptionsRequest() (adjust any
call sites that currently pass a providerConfig), or retain providerConfig but
add a clear comment above getPrivateDNSNameOptionsRequest explaining it is
intentionally unused for API consistency/future extensibility (and mark it with
a linter-suppress or underscore name if your linters require). Ensure any caller
changes compile and run tests.

ℹ️ Review info

Configuration used: Repository: openshift/coderabbit/.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 78a173d and 0041a18.

📒 Files selected for processing (2)
  • pkg/actuators/machine/instances.go
  • pkg/actuators/machine/instances_test.go

tthvo added 2 commits March 3, 2026 21:32
…r dualstack networking

Configure IPv6 IMDS and private DNS configuration when infrastructure CR
status reports dualstack IP family variants.
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 4, 2026

@tthvo: This pull request references CORS-4166 which is a valid jira issue.

Details

In response to this:

Thus, this PR configures IPv6 IMDS and private DNS configuration when infrastructure CR status reports dualstack IP family variants. Since we don't add new features to MAPI, these changes follow the pattern in #171.

Motivation

Every EC2 instance receives a private hostname, which should provide both A and AAAA records for the IPv4 and IPv6 addresses of the instance. This is only supported via "resource-name" hostname type.

Additionally, any pods that needs to assume the node assigned IAM role should be able to contact the IMDS endpoint over IPv6. The endpoint must be enabled explicitly.

Summary by CodeRabbit

  • New Features

  • Instances now auto-configure instance metadata and private DNS options according to cluster infrastructure, with explicit support for dual-stack IPv6/IPv4 setups.

  • Refactor

  • Internal logic now derives metadata and DNS hostname options from infrastructure network settings while preserving previous nil/empty behavior when not applicable.

  • Tests

  • Expanded coverage for infra-driven dual-stack and single-stack scenarios validating metadata and DNS behaviors.

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.

@damdo
Copy link
Member

damdo commented Mar 4, 2026

/retest

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 4, 2026

@tthvo: 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.

@tthvo tthvo changed the title CORS-4166: Enable IPv6 IMDS protocol and private DNS configuration for dualstack CORS-4166: enable IPv6 IMDS endpoint and private DNS configuration for dualstack Mar 4, 2026
@patrickdillon
Copy link

@tthvo
Copy link
Member Author

tthvo commented Mar 5, 2026

/verified by @tthvo

See #177 (comment)

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Mar 5, 2026
@openshift-ci-robot
Copy link
Contributor

@tthvo: This PR has been marked as verified by @tthvo.

Details

In response to this:

/verified by @tthvo

See #177 (comment)

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@sadasu sadasu left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 10, 2026
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. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants