Skip to content

Commit 31342e5

Browse files
authored
Merge pull request mikkeloscar#58 from michohl/xnh9838-failed-updates
Handle stale managedPDB definitions
2 parents 61c5773 + 9bbdc76 commit 31342e5

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

controller.go

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1414
"k8s.io/apimachinery/pkg/util/intstr"
1515
"k8s.io/client-go/kubernetes"
16+
"k8s.io/client-go/util/retry"
1617
)
1718

1819
const (
@@ -192,6 +193,27 @@ func (n *PDBController) generateDesiredPDBs(resources []kubeResource, managedPDB
192193
return desiredPDBs
193194
}
194195

196+
// mergeActualAndDesiredPDB takes the current definition of a PDB as it is in cluster and a PDB
197+
// with our desired configurations and does a merge between them. We also return a boolean to tell the
198+
// caller if any change actually had to be made to achieve our desired state or not
199+
func mergeActualAndDesiredPDB(managedPDB, desiredPDB pv1.PodDisruptionBudget) (pv1.PodDisruptionBudget, bool) {
200+
201+
needsUpdate := false
202+
203+
// check if PDBs are equal an only update if not
204+
if !equality.Semantic.DeepEqual(managedPDB.Spec, desiredPDB.Spec) ||
205+
!equality.Semantic.DeepEqual(managedPDB.Labels, desiredPDB.Labels) ||
206+
!equality.Semantic.DeepEqual(managedPDB.Annotations, desiredPDB.Annotations) {
207+
managedPDB.Annotations = desiredPDB.Annotations
208+
managedPDB.Labels = desiredPDB.Labels
209+
managedPDB.Spec = desiredPDB.Spec
210+
211+
needsUpdate = true
212+
}
213+
214+
return managedPDB, needsUpdate
215+
}
216+
195217
func (n *PDBController) reconcilePDBs(ctx context.Context, desiredPDBs, managedPDBs map[string]pv1.PodDisruptionBudget) {
196218
for key, managedPDB := range managedPDBs {
197219
desiredPDB, ok := desiredPDBs[key]
@@ -215,14 +237,36 @@ func (n *PDBController) reconcilePDBs(ctx context.Context, desiredPDBs, managedP
215237
}
216238

217239
// check if PDBs are equal an only update if not
218-
if !equality.Semantic.DeepEqual(managedPDB.Spec, desiredPDB.Spec) ||
219-
!equality.Semantic.DeepEqual(managedPDB.Labels, desiredPDB.Labels) ||
220-
!equality.Semantic.DeepEqual(managedPDB.Annotations, desiredPDB.Annotations) {
221-
managedPDB.Annotations = desiredPDB.Annotations
222-
managedPDB.Labels = desiredPDB.Labels
223-
managedPDB.Spec = desiredPDB.Spec
224-
225-
_, err := n.PolicyV1().PodDisruptionBudgets(managedPDB.Namespace).Update(ctx, &managedPDB, metav1.UpdateOptions{})
240+
updatedPDB, needsUpdate := mergeActualAndDesiredPDB(managedPDB, desiredPDB)
241+
if needsUpdate {
242+
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
243+
// Technically the updatedPDB and managedPDB namespace should never be different
244+
// but just to be **certain** we're updating the correct namespace we'll just use
245+
// the one that was given to us and not potentially modified
246+
_, err := n.PolicyV1().PodDisruptionBudgets(managedPDB.Namespace).Update(ctx, &updatedPDB, metav1.UpdateOptions{})
247+
248+
// If the update failed that likely means that our definition of what was on the cluster
249+
// has become out of date. To resolve this we'll need to get a more up to date copy of
250+
// the object we're attempting to modify
251+
if err != nil {
252+
currentPDB, err := n.PolicyV1().PodDisruptionBudgets(managedPDB.Namespace).Get(ctx, managedPDB.Name, metav1.GetOptions{})
253+
254+
// This err is locally scoped to this if block and will not cause our `RetryOnConflict`
255+
// to pass if it is nil. If we're in this block then we will get another Retry
256+
if err != nil {
257+
return err
258+
}
259+
260+
updatedPDB, _ = mergeActualAndDesiredPDB(
261+
*currentPDB,
262+
desiredPDB,
263+
)
264+
}
265+
266+
// If this err != nil then the current block will be re-run by `RetryOnConflict`
267+
// on an exponential backoff schedule to see if we can fix the problem by trying again
268+
return err
269+
})
226270
if err != nil {
227271
log.Errorf("Failed to update PDB: %v", err)
228272
continue

0 commit comments

Comments
 (0)