Skip to content

CNTRLPLANE-3691: Decouple NodePool condition handling from CAPI reconciliation#9032

Open
hypershift-jira-solve-ci[bot] wants to merge 2 commits into
openshift:mainfrom
hypershift-community:fix-CNTRLPLANE-3691
Open

CNTRLPLANE-3691: Decouple NodePool condition handling from CAPI reconciliation#9032
hypershift-jira-solve-ci[bot] wants to merge 2 commits into
openshift:mainfrom
hypershift-community:fix-CNTRLPLANE-3691

Conversation

@hypershift-jira-solve-ci

@hypershift-jira-solve-ci hypershift-jira-solve-ci Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

Decouples NodePool condition management from CAPI.Reconcile() by introducing a CAPIResult struct that carries condition information back to the caller. Previously, CAPI.Reconcile() was setting NodePool conditions inline, mixing CAPI resource reconciliation with NodePool status management. This made capi.go harder to reason about and violated separation of concerns.

The caller in nodepool_controller.go now sets conditions on the NodePool after the CAPI reconciliation completes, centralizing condition management in the controller layer.

Conditions moved:

  • NodePoolUpdatingPlatformMachineTemplateConditionType
  • NodePoolAutorepairEnabledConditionType
  • NodePoolReadyConditionType (from both MachineDeployment and MachineSet)

No behavioral change — the same conditions are set under the same circumstances.

Tests are updated to capture and validate the CAPIResult returned by capi.Reconcile(), and a pre-existing test bug is fixed where conditions accumulated on capi.conditions were not applied to the NodePool.

Which issue(s) this PR fixes:

Fixes https://redhat.atlassian.net/browse/CNTRLPLANE-3691

Special notes for your reviewer:

This is a pure refactor with no behavioral change. The diff is large because condition-setting logic moves from capi.go to nodepool_controller.go, but the conditions themselves and when they are set remain identical.

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Always review AI generated responses prior to use.
Generated with Claude Code via openshift-developer plugin


Note: This PR was auto-generated by the jira-agent periodic CI job in response to CNTRLPLANE-3691. See the full report for token usage, cost breakdown, and detailed phase output.

Summary by CodeRabbit

  • Bug Fixes

    • Improved NodePool status reporting by reliably propagating readiness, machine update, and autorepair conditions.
    • Prevented MachineHealthChecks from being reconciled before the NodePool reaches the ignition endpoint.
    • Improved error handling during MachineHealthCheck operations.
  • Tests

    • Updated reconciliation coverage to validate returned NodePool conditions and rollout status.

OpenShift CI Bot and others added 2 commits July 16, 2026 09:16
CAPI.Reconcile() was setting NodePool conditions inline, mixing CAPI
resource reconciliation with NodePool status management. This made
capi.go harder to reason about and violated separation of concerns.

Introduce a CAPIResult struct returned by CAPI.Reconcile() that carries
condition information back to the caller. The caller in
nodepool_controller.go now sets conditions on the NodePool after
the CAPI reconciliation completes, centralizing condition management
in the controller layer.

Conditions moved:
- NodePoolUpdatingPlatformMachineTemplateConditionType
- NodePoolAutorepairEnabledConditionType
- NodePoolReadyConditionType (from both MachineDeployment and MachineSet)

No behavioral change — the same conditions are set under the same
circumstances.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capture and validate the CAPIResult returned by capi.Reconcile() in
TestCAPIReconcile, TestCAPIReconcile_machineset, and fix a pre-existing
test bug in TestReconcileMachineDeploymentStatus where conditions
accumulated on capi.conditions were not applied to the NodePool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

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

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 17, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 17, 2026

Copy link
Copy Markdown

@hypershift-jira-solve-ci[bot]: This pull request references CNTRLPLANE-3691 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 task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

Decouples NodePool condition management from CAPI.Reconcile() by introducing a CAPIResult struct that carries condition information back to the caller. Previously, CAPI.Reconcile() was setting NodePool conditions inline, mixing CAPI resource reconciliation with NodePool status management. This made capi.go harder to reason about and violated separation of concerns.

The caller in nodepool_controller.go now sets conditions on the NodePool after the CAPI reconciliation completes, centralizing condition management in the controller layer.

Conditions moved:

  • NodePoolUpdatingPlatformMachineTemplateConditionType
  • NodePoolAutorepairEnabledConditionType
  • NodePoolReadyConditionType (from both MachineDeployment and MachineSet)

No behavioral change — the same conditions are set under the same circumstances.

Tests are updated to capture and validate the CAPIResult returned by capi.Reconcile(), and a pre-existing test bug is fixed where conditions accumulated on capi.conditions were not applied to the NodePool.

Which issue(s) this PR fixes:

Fixes https://redhat.atlassian.net/browse/CNTRLPLANE-3691

Special notes for your reviewer:

This is a pure refactor with no behavioral change. The diff is large because condition-setting logic moves from capi.go to nodepool_controller.go, but the conditions themselves and when they are set remain identical.

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Always review AI generated responses prior to use.
Generated with Claude Code via openshift-developer plugin

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

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

CAPI.Reconcile now returns a CAPIResult containing accumulated NodePool conditions. CAPI reconciliation branches append conditions locally, including MachineTemplate, autorepair, spot health checks, and readiness aggregation. The NodePool reconciler applies returned conditions to status and retains existing requeue behavior. Tests now validate returned conditions and adapt custom reconciliation callbacks to the new signature.

Sequence Diagram(s)

sequenceDiagram
  participant NodePoolReconciler
  participant CAPI
  participant MachineResources
  NodePoolReconciler->>CAPI: Reconcile(ctx)
  CAPI->>MachineResources: Reconcile machines and health checks
  MachineResources-->>CAPI: Status and errors
  CAPI-->>NodePoolReconciler: CAPIResult with conditions
  NodePoolReconciler->>NodePoolReconciler: Apply conditions to NodePool status
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning Edited tests still use bare HaveOccurred assertions and broad reconcile table cases, so they lack the requested diagnostic clarity. Add meaningful failure messages to error assertions and split the broad reconcile checks into smaller, focused tests/subtests.
✅ Passed checks (10 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed The modified tests use fixed, descriptive names; no Ginkgo titles or t.Run names are built from dynamic or volatile values.
Topology-Aware Scheduling Compatibility ✅ Passed The PR only refactors CAPI status-condition handling; I found no new pod affinity, topology-spread, nodeSelector, or topology-dependent replica logic.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the touched test file is standard unit tests and shows no IPv4-only or external connectivity assumptions.
No-Weak-Crypto ✅ Passed No weak-crypto primitives, custom crypto, or non-constant-time secret/token comparisons were added in the touched files or diff.
Container-Privileges ✅ Passed PASS: The PR diff here only updates nodepool tests; no manifests or pod specs add privileged/hostPID/hostNetwork/hostIPC/SYS_ADMIN/allowPrivilegeEscalation.
No-Sensitive-Data-In-Logs ✅ Passed No new log calls were introduced; the PR only refactors condition handling and does not log secrets, tokens, hostnames, or PII.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: moving NodePool condition handling out of CAPI reconciliation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci openshift-ci Bot added area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release and removed do-not-merge/needs-area labels Jul 17, 2026
@openshift-ci

openshift-ci Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: hypershift-jira-solve-ci[bot]
Once this PR has been reviewed and has the lgtm label, please assign csrwng for approval. For more information see the Code Review Process.

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

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

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

@openshift-ci
openshift-ci Bot requested review from csrwng and ironcladlou July 17, 2026 10:11

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
hypershift-operator/controllers/nodepool/capi_test.go (1)

1884-1890: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the expected condition contract, not merely a non-empty result.

These assertions pass if only an unrelated condition is returned. Add expected condition type/status assertions per fixture, particularly for autorepair and ready-condition paths.

  • hypershift-operator/controllers/nodepool/capi_test.go#L1884-L1890: assert the conditions expected from the initial reconciliation.
  • hypershift-operator/controllers/nodepool/capi_test.go#L2000-L2003: assert the expected condition after rollout completion.
  • hypershift-operator/controllers/nodepool/capi_test.go#L2172-L2182: assert the in-place reconciliation condition set.

As per coding guidelines, “Unit test any code changes and additions.”

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

In `@hypershift-operator/controllers/nodepool/capi_test.go` around lines 1884 -
1890, Strengthen the condition assertions in
hypershift-operator/controllers/nodepool/capi_test.go at lines 1884-1890,
2000-2003, and 2172-2182: use each fixture’s expected condition type and status,
including autorepair, ready-condition, rollout-completion, and in-place
reconciliation paths, rather than only checking that conditions are non-empty.
Update the tests around the capi.Reconcile calls and add or adjust unit-test
expectations for every affected scenario.

Source: Coding guidelines

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

Inline comments:
In `@hypershift-operator/controllers/nodepool/capi.go`:
- Around line 150-151: Preserve accumulated conditions after CAPI reconciliation
begins: in CAPI.Reconcile, return the accumulated CAPIResult alongside errors on
every subsequent error path, including the MachineSet failure near
hypershift-operator/controllers/nodepool/capi.go:150-151. In
hypershift-operator/controllers/nodepool/nodepool_controller.go:429-440, apply
any non-nil CAPIResult before handling and returning the reconciliation error.

---

Nitpick comments:
In `@hypershift-operator/controllers/nodepool/capi_test.go`:
- Around line 1884-1890: Strengthen the condition assertions in
hypershift-operator/controllers/nodepool/capi_test.go at lines 1884-1890,
2000-2003, and 2172-2182: use each fixture’s expected condition type and status,
including autorepair, ready-condition, rollout-completion, and in-place
reconciliation paths, rather than only checking that conditions are non-empty.
Update the tests around the capi.Reconcile calls and add or adjust unit-test
expectations for every affected scenario.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 1b60cd96-8142-43b2-8179-b7be4e59fd53

📥 Commits

Reviewing files that changed from the base of the PR and between 3b49a4a and 159b233.

📒 Files selected for processing (3)
  • hypershift-operator/controllers/nodepool/capi.go
  • hypershift-operator/controllers/nodepool/capi_test.go
  • hypershift-operator/controllers/nodepool/nodepool_controller.go

Comment on lines +150 to 151
return nil, fmt.Errorf("failed to reconcile MachineSet %q: %w",
client.ObjectKeyFromObject(ms).String(), err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve accumulated conditions when CAPI reconciliation fails.

A condition is appended before these later failures, but CAPI.Reconcile returns nil, err; the controller therefore returns before applying it. Previously, the inline status mutation was patched even on reconcile errors, so this loses status updates such as the platform-template condition.

  • hypershift-operator/controllers/nodepool/capi.go#L150-L151: return the accumulated CAPIResult on every error path reached after condition collection begins.
  • hypershift-operator/controllers/nodepool/nodepool_controller.go#L429-L440: apply a non-nil result before handling and returning the error.
📍 Affects 2 files
  • hypershift-operator/controllers/nodepool/capi.go#L150-L151 (this comment)
  • hypershift-operator/controllers/nodepool/nodepool_controller.go#L429-L440
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hypershift-operator/controllers/nodepool/capi.go` around lines 150 - 151,
Preserve accumulated conditions after CAPI reconciliation begins: in
CAPI.Reconcile, return the accumulated CAPIResult alongside errors on every
subsequent error path, including the MachineSet failure near
hypershift-operator/controllers/nodepool/capi.go:150-151. In
hypershift-operator/controllers/nodepool/nodepool_controller.go:429-440, apply
any non-nil CAPIResult before handling and returning the reconciliation error.

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 18.18182% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.11%. Comparing base (4fa09b1) to head (159b233).
⚠️ Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
hypershift-operator/controllers/nodepool/capi.go 21.42% 21 Missing and 1 partial ⚠️
...erator/controllers/nodepool/nodepool_controller.go 0.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             main    #9032     +/-   ##
=========================================
  Coverage   44.11%   44.11%             
=========================================
  Files         772      779      +7     
  Lines       96227    98065   +1838     
=========================================
+ Hits        42449    43262    +813     
- Misses      50832    51769    +937     
- Partials     2946     3034     +88     
Files with missing lines Coverage Δ
...erator/controllers/nodepool/nodepool_controller.go 42.96% <0.00%> (-0.39%) ⬇️
hypershift-operator/controllers/nodepool/capi.go 71.93% <21.42%> (-0.03%) ⬇️

... and 25 files with indirect coverage changes

Flag Coverage Δ
cmd-support 38.24% <ø> (+<0.01%) ⬆️
cpo-hostedcontrolplane 46.27% <ø> (+0.09%) ⬆️
cpo-other 45.22% <ø> (+0.08%) ⬆️
hypershift-operator 54.11% <18.18%> (+0.01%) ⬆️
other 33.59% <ø> (+1.47%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@openshift-ci

openshift-ci Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@hypershift-jira-solve-ci[bot]: 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.

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

Labels

area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant