-
Notifications
You must be signed in to change notification settings - Fork 531
CNTRLPLANE-3532: migrate CPO status patches to statuspatching helpers #8966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ import ( | |
| "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kms" | ||
| "github.com/openshift/hypershift/support/config" | ||
| "github.com/openshift/hypershift/support/secretencryption" | ||
| "github.com/openshift/hypershift/support/statuspatching" | ||
| "github.com/openshift/hypershift/support/util" | ||
|
|
||
| "github.com/openshift/library-go/pkg/operator/encryption/controllers/migrators" | ||
|
|
@@ -62,24 +63,45 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco | |
| return reconcile.Result{}, fmt.Errorf("failed to get HCP: %w", err) | ||
| } | ||
|
|
||
| originalHCP := hcp.DeepCopy() | ||
| // Snapshot pre-reconcile encryption state for metrics comparison. | ||
| previousEncryption := *hcp.Status.SecretEncryption.DeepCopy() | ||
|
|
||
| result, err := r.reconcile(ctx, log, hcp) | ||
| if err != nil { | ||
| return result, err | ||
| } | ||
|
|
||
| if !equality.Semantic.DeepEqual(hcp.Status, originalHCP.Status) { | ||
| log.Info("Patching HCP status with secret encryption changes") | ||
| patch := crclient.MergeFrom(originalHCP) | ||
| if err := r.cpClient.Status().Patch(ctx, hcp, patch); err != nil { | ||
| return reconcile.Result{}, fmt.Errorf("failed to patch HCP status: %w", err) | ||
| // Capture desired status changes computed by reconcile(). | ||
| // Copy by value — PatchStatus re-fetches hcp, which replaces the backing slice. | ||
| desiredEncryption := *hcp.Status.SecretEncryption.DeepCopy() | ||
| var desiredCondition metav1.Condition | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential semantic narrowing: The original If Is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. Confirmed — |
||
| hasCondition := false | ||
| if c := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate)); c != nil { | ||
| desiredCondition = *c | ||
| hasCondition = true | ||
| } | ||
|
|
||
| if patchErr := statuspatching.PatchStatus(ctx, r.cpClient, hcp, func() error { | ||
| hcp.Status.SecretEncryption = desiredEncryption | ||
| if hasCondition { | ||
| meta.SetStatusCondition(&hcp.Status.Conditions, desiredCondition) | ||
| } else { | ||
| meta.RemoveStatusCondition(&hcp.Status.Conditions, string(hyperv1.EtcdDataEncryptionUpToDate)) | ||
| } | ||
| log.Info("Successfully patched HCP status") | ||
| recordMigrationState(r.hcpNamespace, r.hcpName, hcp.Status.SecretEncryption) | ||
| previousState := encryptionHistoryState(originalHCP.Status.SecretEncryption) | ||
| currentState := encryptionHistoryState(hcp.Status.SecretEncryption) | ||
| return nil | ||
| }); patchErr != nil { | ||
| return reconcile.Result{}, fmt.Errorf("failed to patch HCP status: %w", patchErr) | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| // Always re-emit the current migration state gauge so it survives pod restarts. | ||
| recordMigrationState(r.hcpNamespace, r.hcpName, desiredEncryption) | ||
|
|
||
| // Record duration only on actual state transitions. | ||
| if !equality.Semantic.DeepEqual(previousEncryption, desiredEncryption) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Consider moving
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. Moved AI-assisted response via Claude Code |
||
| previousState := encryptionHistoryState(previousEncryption) | ||
| currentState := encryptionHistoryState(desiredEncryption) | ||
| if currentState == hyperv1.EncryptionMigrationStateCompleted && previousState != currentState { | ||
| recordMigrationDuration(r.hcpNamespace, r.hcpName, hcp.Status.SecretEncryption) | ||
| recordMigrationDuration(r.hcpNamespace, r.hcpName, desiredEncryption) | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a regression (old code also re-fetched before referencing
Generation), butObservedGenerationinside the PatchStatus closure will reflect the re-fetched HCP's generation, which may be newer than the generation used to computemissingImages. If the spec changed between the original read and the re-fetch, the condition content won't match what that generation actually means. A follow-up reconcile self-corrects, so this is minor — just flagging in case you want to snapshot the generation before the PatchStatus call.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Acknowledged. This is pre-existing — the old code also re-fetched before referencing
Generation. A follow-up reconcile self-corrects, so leaving as-is for now.AI-assisted response via Claude Code