Skip to content

Commit b2aa21d

Browse files
JustinKuliopenshift-ci[bot]
authored andcommitted
Fix code smells and PR comments
The bigger change is that the status is now updated before sending the events to the replicated policy reconciler - this should help prevent some requeues. Otherwise, these are largely just organizational changes. Signed-off-by: Justin Kulikauskas <jkulikau@redhat.com>
1 parent aa643c0 commit b2aa21d

File tree

5 files changed

+104
-84
lines changed

5 files changed

+104
-84
lines changed

controllers/propagator/propagation.go

+42-39
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ type Propagator struct {
5050
client.Client
5151
Scheme *runtime.Scheme
5252
Recorder record.EventRecorder
53-
DynamicWatcher k8sdepwatches.DynamicWatcher
5453
RootPolicyLocks *sync.Map
5554
ReplicatedPolicyUpdates chan event.GenericEvent
5655
}
@@ -182,12 +181,12 @@ func (r *RootPolicyReconciler) getAllClusterDecisions(
182181
decisions = make(map[appsv1.PlacementDecision]policiesv1.BindingOverrides)
183182

184183
// Process all placement bindings without subFilter
185-
for _, pb := range pbList.Items {
184+
for i, pb := range pbList.Items {
186185
if pb.SubFilter == policiesv1.Restricted {
187186
continue
188187
}
189188

190-
plcDecisions, plcPlacements, err := r.getPolicyPlacementDecisions(instance, &pb)
189+
plcDecisions, plcPlacements, err := r.getPolicyPlacementDecisions(instance, &pbList.Items[i])
191190
if err != nil {
192191
return nil, nil, err
193192
}
@@ -226,14 +225,14 @@ func (r *RootPolicyReconciler) getAllClusterDecisions(
226225
}
227226

228227
// Process all placement bindings with subFilter:restricted
229-
for _, pb := range pbList.Items {
228+
for i, pb := range pbList.Items {
230229
if pb.SubFilter != policiesv1.Restricted {
231230
continue
232231
}
233232

234233
foundInDecisions := false
235234

236-
plcDecisions, plcPlacements, err := r.getPolicyPlacementDecisions(instance, &pb)
235+
plcDecisions, plcPlacements, err := r.getPolicyPlacementDecisions(instance, &pbList.Items[i])
237236
if err != nil {
238237
return nil, nil, err
239238
}
@@ -267,9 +266,8 @@ func (r *RootPolicyReconciler) getAllClusterDecisions(
267266
return decisions, placements, nil
268267
}
269268

270-
// handleDecisions identifies all managed clusters which should have a replicated policy, and sends
271-
// events to the replicated policy reconciler for them to be created or updated.
272-
func (r *RootPolicyReconciler) handleDecisions(
269+
// getDecisions identifies all managed clusters which should have a replicated policy
270+
func (r *RootPolicyReconciler) getDecisions(
273271
instance *policiesv1.Policy,
274272
) (
275273
[]*policiesv1.Placement, decisionSet, error,
@@ -299,25 +297,6 @@ func (r *RootPolicyReconciler) handleDecisions(
299297
decisions[dec] = true
300298
}
301299

302-
log.Info("Sending reconcile events to replicated policies", "decisionsCount", len(allClusterDecisions))
303-
304-
for decision := range allClusterDecisions {
305-
simpleObj := &GuttedObject{
306-
TypeMeta: metav1.TypeMeta{
307-
Kind: policiesv1.Kind,
308-
APIVersion: policiesv1.GroupVersion.String(),
309-
},
310-
ObjectMeta: metav1.ObjectMeta{
311-
Name: common.FullNameForPolicy(instance),
312-
Namespace: decision.ClusterNamespace,
313-
},
314-
}
315-
316-
log.V(2).Info("Sending reconcile for replicated policy", "replicatedPolicyName", simpleObj.GetName())
317-
318-
r.ReplicatedPolicyUpdates <- event.GenericEvent{Object: simpleObj}
319-
}
320-
321300
return placements, decisions, nil
322301
}
323302

@@ -326,11 +305,11 @@ func (r *RootPolicyReconciler) handleDecisions(
326305
// decisions, then it's considered stale and an event is sent to the replicated policy reconciler
327306
// so the policy will be removed.
328307
func (r *RootPolicyReconciler) cleanUpOrphanedRplPolicies(
329-
instance *policiesv1.Policy, allDecisions decisionSet,
308+
instance *policiesv1.Policy, originalCPCS []*policiesv1.CompliancePerClusterStatus, allDecisions decisionSet,
330309
) error {
331310
log := log.WithValues("policyName", instance.GetName(), "policyNamespace", instance.GetNamespace())
332311

333-
for _, cluster := range instance.Status.Status {
312+
for _, cluster := range originalCPCS {
334313
key := appsv1.PlacementDecision{
335314
ClusterName: cluster.ClusterNamespace,
336315
ClusterNamespace: cluster.ClusterNamespace,
@@ -388,32 +367,30 @@ func (r *RootPolicyReconciler) handleRootPolicy(instance *policiesv1.Policy) err
388367
}
389368
}
390369

391-
placements, decisions, err := r.handleDecisions(instance)
370+
placements, decisions, err := r.getDecisions(instance)
392371
if err != nil {
393372
log.Info("Failed to get any placement decisions. Giving up on the request.")
394373

395374
return errors.New("could not get the placement decisions")
396375
}
397376

398-
err = r.cleanUpOrphanedRplPolicies(instance, decisions)
399-
if err != nil {
400-
log.Error(err, "Failed to delete orphaned replicated policies")
401-
402-
return err
403-
}
404-
405377
log.V(1).Info("Updating the root policy status")
406378

407379
cpcs, cpcsErr := r.calculatePerClusterStatus(instance, decisions)
408380
if cpcsErr != nil {
409-
log.Error(cpcsErr, "Failed to get at least one replicated policy")
381+
// If there is a new replicated policy, then its lookup is expected to fail - it hasn't been created yet.
382+
log.Error(cpcsErr, "Failed to get at least one replicated policy, but that may be expected. Ignoring.")
410383
}
411384

412385
err = r.Get(context.TODO(), types.NamespacedName{Namespace: instance.Namespace, Name: instance.Name}, instance)
413386
if err != nil {
414387
log.Error(err, "Failed to refresh the cached policy. Will use existing policy.")
415388
}
416389

390+
// make a copy of the original status
391+
originalCPCS := make([]*policiesv1.CompliancePerClusterStatus, len(instance.Status.Status))
392+
copy(originalCPCS, instance.Status.Status)
393+
417394
instance.Status.Status = cpcs
418395
instance.Status.ComplianceState = CalculateRootCompliance(cpcs)
419396
instance.Status.Placement = placements
@@ -423,7 +400,33 @@ func (r *RootPolicyReconciler) handleRootPolicy(instance *policiesv1.Policy) err
423400
return err
424401
}
425402

426-
return cpcsErr
403+
log.Info("Sending reconcile events to replicated policies", "decisionsCount", len(decisions))
404+
405+
for decision := range decisions {
406+
simpleObj := &GuttedObject{
407+
TypeMeta: metav1.TypeMeta{
408+
Kind: policiesv1.Kind,
409+
APIVersion: policiesv1.GroupVersion.String(),
410+
},
411+
ObjectMeta: metav1.ObjectMeta{
412+
Name: common.FullNameForPolicy(instance),
413+
Namespace: decision.ClusterNamespace,
414+
},
415+
}
416+
417+
log.V(2).Info("Sending reconcile for replicated policy", "replicatedPolicyName", simpleObj.GetName())
418+
419+
r.ReplicatedPolicyUpdates <- event.GenericEvent{Object: simpleObj}
420+
}
421+
422+
err = r.cleanUpOrphanedRplPolicies(instance, originalCPCS, decisions)
423+
if err != nil {
424+
log.Error(err, "Failed to delete orphaned replicated policies")
425+
426+
return err
427+
}
428+
429+
return nil
427430
}
428431

429432
// a helper to quickly check if there are any templates in any of the policy templates

controllers/propagator/replicatedpolicy_controller.go

+43-37
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var _ reconcile.Reconciler = &ReplicatedPolicyReconciler{}
2424
type ReplicatedPolicyReconciler struct {
2525
Propagator
2626
ResourceVersions *sync.Map
27+
DynamicWatcher k8sdepwatches.DynamicWatcher
2728
}
2829

2930
func (r *ReplicatedPolicyReconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) {
@@ -52,13 +53,18 @@ func (r *ReplicatedPolicyReconciler) Reconcile(ctx context.Context, request ctrl
5253
}
5354

5455
rootName, rootNS, err := common.ParseRootPolicyLabel(request.Name)
55-
if err != nil && replicatedExists {
56-
if err := r.cleanUpReplicated(ctx, replicatedPolicy); err != nil {
57-
if !k8serrors.IsNotFound(err) {
58-
log.Error(err, "Failed to delete the invalid replicated policy, requeueing")
56+
if err != nil {
57+
if !replicatedExists {
58+
log.Error(err, "Invalid replicated policy sent for reconcile, rejecting")
5959

60-
return reconcile.Result{}, err
61-
}
60+
return reconcile.Result{}, nil
61+
}
62+
63+
cleanUpErr := r.cleanUpReplicated(ctx, replicatedPolicy)
64+
if cleanUpErr != nil && !k8serrors.IsNotFound(cleanUpErr) {
65+
log.Error(err, "Failed to delete the invalid replicated policy, requeueing")
66+
67+
return reconcile.Result{}, err
6268
}
6369

6470
log.Info("Invalid replicated policy deleted")
@@ -73,48 +79,48 @@ func (r *ReplicatedPolicyReconciler) Reconcile(ctx context.Context, request ctrl
7379
rootNN := types.NamespacedName{Namespace: rootNS, Name: rootName}
7480

7581
if err := r.Get(ctx, rootNN, rootPolicy); err != nil {
76-
if k8serrors.IsNotFound(err) {
77-
if replicatedExists {
78-
// do not handle a replicated policy which does not belong to the current cluster
79-
inClusterNS, err := common.IsInClusterNamespace(r.Client, request.Namespace)
80-
if err != nil {
81-
return reconcile.Result{}, err
82-
}
83-
84-
if !inClusterNS {
85-
log.Info("Found a replicated policy in non-cluster namespace, skipping it")
86-
87-
return reconcile.Result{}, nil
88-
}
89-
90-
// otherwise, we need to clean it up
91-
if err := r.cleanUpReplicated(ctx, replicatedPolicy); err != nil {
92-
if !k8serrors.IsNotFound(err) {
93-
log.Error(err, "Failed to delete the orphaned replicated policy, requeueing")
94-
95-
return reconcile.Result{}, err
96-
}
97-
}
98-
99-
log.Info("Orphaned replicated policy deleted")
82+
if !k8serrors.IsNotFound(err) {
83+
log.Error(err, "Failed to get the root policy, requeueing")
10084

101-
return reconcile.Result{}, nil
102-
}
85+
return reconcile.Result{}, err
86+
}
10387

88+
if !replicatedExists {
10489
version := safeWriteLoad(r.ResourceVersions, rsrcVersKey)
10590
defer version.Unlock()
10691

10792
// Store this to ensure the cache matches a known possible state for this situation
10893
version.resourceVersion = "deleted"
10994

110-
log.Info("Root policy and replicated policy already missing")
95+
log.V(1).Info("Root policy and replicated policy already missing")
11196

11297
return reconcile.Result{}, nil
11398
}
11499

115-
log.Error(err, "Failed to get the root policy, requeueing")
100+
// do not handle a replicated policy which does not belong to the current cluster
101+
inClusterNS, err := common.IsInClusterNamespace(r.Client, request.Namespace)
102+
if err != nil {
103+
return reconcile.Result{}, err
104+
}
105+
106+
if !inClusterNS {
107+
log.V(1).Info("Found a replicated policy in non-cluster namespace, skipping it")
116108

117-
return reconcile.Result{}, err
109+
return reconcile.Result{}, nil
110+
}
111+
112+
// otherwise, we need to clean it up
113+
if err := r.cleanUpReplicated(ctx, replicatedPolicy); err != nil {
114+
if !k8serrors.IsNotFound(err) {
115+
log.Error(err, "Failed to delete the orphaned replicated policy, requeueing")
116+
117+
return reconcile.Result{}, err
118+
}
119+
}
120+
121+
log.Info("Orphaned replicated policy deleted")
122+
123+
return reconcile.Result{}, nil
118124
}
119125

120126
if rootPolicy.Spec.Disabled {
@@ -138,7 +144,7 @@ func (r *ReplicatedPolicyReconciler) Reconcile(ctx context.Context, request ctrl
138144
// Store this to ensure the cache matches a known possible state for this situation
139145
version.resourceVersion = "deleted"
140146

141-
log.Info("Root policy is disabled, and replicated policy correctly not found.")
147+
log.V(1).Info("Root policy is disabled, and replicated policy correctly not found.")
142148

143149
return reconcile.Result{}, nil
144150
}
@@ -173,7 +179,7 @@ func (r *ReplicatedPolicyReconciler) Reconcile(ctx context.Context, request ctrl
173179
// Store this to ensure the cache matches a known possible state for this situation
174180
version.resourceVersion = "deleted"
175181

176-
log.Info("Replicated policy should not exist on this managed cluster, and does not.")
182+
log.V(1).Info("Replicated policy should not exist on this managed cluster, and does not.")
177183

178184
return reconcile.Result{}, nil
179185
}

controllers/propagator/rootpolicy_setup.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,13 @@ func mapPlacementRuleToPolicies(c client.Client) handler.MapFunc {
197197

198198
var result []reconcile.Request
199199
// loop through pbs and collect policies from each matching one.
200-
for _, pb := range pbList.Items {
200+
for i, pb := range pbList.Items {
201201
if pb.PlacementRef.APIGroup != appsv1.SchemeGroupVersion.Group ||
202202
pb.PlacementRef.Kind != "PlacementRule" || pb.PlacementRef.Name != object.GetName() {
203203
continue
204204
}
205205

206-
result = append(result, common.GetPoliciesInPlacementBinding(ctx, c, &pb)...)
206+
result = append(result, common.GetPoliciesInPlacementBinding(ctx, c, &pbList.Items[i])...)
207207
}
208208

209209
return result
@@ -238,13 +238,13 @@ func mapPlacementDecisionToPolicies(c client.Client) handler.MapFunc {
238238

239239
var result []reconcile.Request
240240
// loop through pbs and collect policies from each matching one.
241-
for _, pb := range pbList.Items {
241+
for i, pb := range pbList.Items {
242242
if pb.PlacementRef.APIGroup != clusterv1beta1.SchemeGroupVersion.Group ||
243243
pb.PlacementRef.Kind != "Placement" || pb.PlacementRef.Name != placementName {
244244
continue
245245
}
246246

247-
result = append(result, common.GetPoliciesInPlacementBinding(ctx, c, &pb)...)
247+
result = append(result, common.GetPoliciesInPlacementBinding(ctx, c, &pbList.Items[i])...)
248248
}
249249

250250
return result

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ func main() {
281281
Client: mgr.GetClient(),
282282
Scheme: mgr.GetScheme(),
283283
Recorder: mgr.GetEventRecorderFor(propagatorctrl.ControllerName),
284-
DynamicWatcher: dynamicWatcher,
285284
RootPolicyLocks: policiesLock,
286285
ReplicatedPolicyUpdates: replicatedPolicyUpdates,
287286
}
@@ -296,6 +295,7 @@ func main() {
296295
if err = (&propagatorctrl.ReplicatedPolicyReconciler{
297296
Propagator: propagator,
298297
ResourceVersions: replicatedResourceVersions,
298+
DynamicWatcher: dynamicWatcher,
299299
}).SetupWithManager(mgr, replPolicyMaxConcurrency, dynamicWatcherSource, replicatedUpdatesSource); err != nil {
300300
log.Error(err, "Unable to create the controller", "controller", "replicated-policy")
301301
os.Exit(1)

test/e2e/case1_propagation_test.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -747,13 +747,24 @@ var _ = Describe("Test policy propagation", func() {
747747
policyMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(policy)
748748
Expect(err).ToNot(HaveOccurred())
749749

750-
policyRV, err := policyClient().Create(
750+
_, err = policyClient().Create(
751751
context.TODO(), &unstructured.Unstructured{Object: policyMap}, metav1.CreateOptions{},
752752
)
753753
Expect(err).ToNot(HaveOccurred())
754754

755-
_, found, _ := unstructured.NestedBool(policyRV.Object, "spec", "copyPolicyMetadata")
756-
Expect(found).To(BeFalse())
755+
Eventually(func(g Gomega) {
756+
replicatedPlc := utils.GetWithTimeout(
757+
clientHubDynamic,
758+
gvrPolicy,
759+
testNamespace+"."+policyName,
760+
"managed1",
761+
true,
762+
defaultTimeoutSeconds,
763+
)
764+
765+
_, found, _ := unstructured.NestedBool(replicatedPlc.Object, "spec", "copyPolicyMetadata")
766+
g.Expect(found).To(BeFalse())
767+
}, defaultTimeoutSeconds, 1).Should(Succeed())
757768
})
758769

759770
It("verifies that the labels and annotations are copied with spec.copyPolicyMetadata=true", func() {

0 commit comments

Comments
 (0)