-
Notifications
You must be signed in to change notification settings - Fork 57
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
DFBUGS-1026: Provision to disable DRPC reconsile temporarily - WA of CG #1720
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 |
---|---|---|
|
@@ -58,6 +58,9 @@ | |
|
||
DoNotDeletePVCAnnotation = "drplacementcontrol.ramendr.openshift.io/do-not-delete-pvc" | ||
DoNotDeletePVCAnnotationVal = "true" | ||
|
||
// Force DRPC reconcile to be enabled | ||
ReconciliationUnpaused = "drplacementcontrol.ramendr.openshift.io/reconciliationUnpaused" | ||
) | ||
|
||
var ErrInitialWaitTimeForDRPCPlacementRule = errors.New("waiting for DRPC Placement to produces placement decision") | ||
|
@@ -152,6 +155,16 @@ | |
return ctrl.Result{}, err | ||
} | ||
|
||
// Workaround: to add drplacementcontrol.ramendr.openshift.io/is-cg-enabled annotation | ||
// for the application workload that is DR protected from the UI. | ||
if !schedulingEnabled(drpc, ramenConfig) { | ||
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. Since the flags are about reconciliation, this helper should be reconciliationEnabled() |
||
logger.Info("DRPC is reconcile is paused, To continue the reconsile, " + | ||
"either add drplacementcontrol.ramendr.openshift.io/reconciliationUnpaused: 'true' " + | ||
"annotation or update StartDRPCReconciliationPaused on the ramen configMap.") | ||
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. This log will appear many times - each time a watched resource changes, and it is a very verbose log. It would be better to set the status to report that the drpc is disabled. In this case this will happen once since the next reconcile the status will not change. |
||
|
||
return ctrl.Result{}, nil | ||
} | ||
|
||
var placementObj client.Object | ||
|
||
placementObj, err = getPlacementOrPlacementRule(ctx, r.Client, drpc, logger) | ||
|
@@ -2467,3 +2480,8 @@ | |
|
||
return drpolicyClusters.Intersection(otherDrpolicyClusters).Len() > 0, nil | ||
} | ||
|
||
func schedulingEnabled(drpc *rmn.DRPlacementControl, ramenConfig *rmn.RamenConfig) bool { | ||
force := drpc.GetAnnotations()[ReconciliationUnpaused] | ||
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. force is does not match the new name, it was good for the old name. |
||
return !ramenConfig.StartDRPCReconciliationPaused && force == "true" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -729,6 +729,10 @@ func createDRPC(placementName, name, namespace, drPolicyName, preferredCluster s | |
return drpc | ||
} | ||
|
||
func updateDRPC(drpc *rmn.DRPlacementControl) { | ||
Expect(k8sClient.Update(context.TODO(), drpc)).Should(Succeed()) | ||
} | ||
|
||
//nolint:unparam | ||
func deleteUserPlacementRule(name, namespace string) { | ||
userPlacementRule := getLatestUserPlacementRule(name, namespace) | ||
|
@@ -2772,6 +2776,80 @@ var _ = Describe("DRPlacementControl Reconciler", func() { | |
deleteDRClustersAsync() | ||
}) | ||
}) | ||
|
||
Context("Disable DRPlacementControl Reconciler", func() { | ||
var userPlacementRule1 *plrv1.PlacementRule | ||
|
||
Specify("DRClusters", func() { | ||
populateDRClusters() | ||
}) | ||
|
||
When("Application deployed for the first time", func() { | ||
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. DRPC created in the first time? Application is deployment may is not related to the drpc, it can be deployed before the drpc was created. |
||
It("Should not have any drpc status", func() { | ||
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. It will be better to have status reporting that the drpc is disabled. |
||
createNamespacesAsync(getNamespaceObj(DefaultDRPCNamespace)) | ||
createManagedClusters(asyncClusters) | ||
createDRClustersAsync() | ||
createDRPolicyAsync() | ||
ramenConfig.StartDRPCReconciliationPaused = true | ||
configMapUpdate() | ||
DeferCleanup(func() { | ||
ramenConfig.StartDRPCReconciliationPaused = false | ||
configMapUpdate() | ||
}) | ||
|
||
var placementObj client.Object | ||
placementObj, _ = CreatePlacementAndDRPC( | ||
DefaultDRPCNamespace, UserPlacementRuleName, East1ManagedCluster, UsePlacementRule) | ||
userPlacementRule1 = placementObj.(*plrv1.PlacementRule) | ||
Expect(userPlacementRule1).NotTo(BeNil()) | ||
drpc := getLatestDRPC(DefaultDRPCNamespace) | ||
Expect(drpc.Status.Phase == "").Should(BeTrue()) | ||
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. This contradicts the test name - we have Status. Maybe you mean that we should not have phase? Can you share an example drpc status in this case? Adding it to the commit message will be helpful. |
||
}) | ||
|
||
}) | ||
|
||
When("Update ramen config to override DRPC reconcile", func() { | ||
It("Should have some drpc status after reconcile", func() { | ||
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. Do you mean that disabling reconciliation will keep the status before the reconciliation was disabled? It would be more useful if we had disable status in the drpc status, and it would reflect the current status of the drpc. If we disabled the drpc after it was reconciled, the status will be the same as the last status, with Status.disabled: "true". |
||
ramenConfig.StartDRPCReconciliationPaused = true | ||
configMapUpdate() | ||
DeferCleanup(func() { | ||
ramenConfig.StartDRPCReconciliationPaused = false | ||
configMapUpdate() | ||
}) | ||
drpc := getLatestDRPC(DefaultDRPCNamespace) | ||
drpc.Annotations = map[string]string{controllers.ReconciliationUnpaused: "true"} | ||
updateDRPC(drpc) | ||
waitForDRPCPhaseAndProgression(DefaultDRPCNamespace, rmn.Deployed) | ||
}) | ||
}) | ||
|
||
When("Deleting DRPolicy with DRPC references", func() { | ||
It("Should retain the deleted DRPolicy in the API server", func() { | ||
By("\n\n*** DELETE drpolicy ***\n\n") | ||
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. This was copied from another test? not sure why we need all these newlines and *** |
||
deleteDRPolicyAsync() | ||
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. This tests that drpolicy is not deleted? |
||
}) | ||
}) | ||
|
||
When("Deleting user PlacementRule", func() { | ||
It("Should cleanup DRPC", func() { | ||
By("\n\n*** DELETE User PlacementRule ***\n\n") | ||
deleteUserPlacementRule(UserPlacementRuleName, DefaultDRPCNamespace) | ||
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. What does "cleanup DRPC" means? if this delete the drpc, the next test is incorrect since the drpc was already deleted. But I don't think that deleting drpc will work with the current code, since return from the reconcile very early before we reach the check for deleted drpc. |
||
}) | ||
}) | ||
|
||
When("Deleting DRPC", func() { | ||
It("Should delete all VRGs", func() { | ||
deleteDRPC() | ||
waitForCompletion("deleted") | ||
ensureNamespaceMWsDeletedFromAllClusters(DefaultDRPCNamespace) | ||
}) | ||
}) | ||
|
||
Specify("delete drclusters", func() { | ||
deleteDRClustersAsync() | ||
}) | ||
}) | ||
|
||
}) | ||
|
||
func getVRGManifestWorkCount() int { | ||
|
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.
I would remove the Start from the name, this flag disable reconcile even if was already started. It means that drpc is paused by default and requires unpuasing to start reconciling.
I'm not sure about paused and unpause, maybe we can use more common terms like disabled and enabled?
The option can be:
and the annotation:
The logic seems clear, if the option is set, all drpcs are disabled, except the these with the explicit "enabled" annotation. It is common that local flag overrides global flag.
@BenamarMk what do you think?
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.
The
Start...
here, is simply an indication that disabling is intended for new DRPCs only. But, we can drop it. I'll let Gowtham decides. Also, I like the wordPause
instead of disable.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.
I am not really certain we need this, to stop reconciliation just scale down the deployment to 0 replicas. That would scale down all controllers (i.e policy/cluster/etc.) but this seems excessive at present.
Once the annotation is removed for CG enabling, if a future use-case arises where a single controller from the set needs to be disabled, this maybe considered.