Skip to content

Commit

Permalink
controllers/reconcile: copy resourceVersion metadata field
Browse files Browse the repository at this point in the history
metadata.resourceVersion should be kept for backward backward-compatibility with older Kubernetes cluster version.

 For instance, any Kubernetes version requires `resourceVersion` to be set for `PodDisruptionBudget`.

 Kubernetes versions before v1.23 requires `resourceVersion` for `Service`.

 This commit copies significant metadata fields:
 - generation
 - resourceVersion
 - creationTimestamp

 for `Update` API requests.

 Related issue:
#1200

Signed-off-by: f41gh7 <[email protected]>
  • Loading branch information
f41gh7 committed Dec 23, 2024
1 parent 2c7f65f commit c6b4403
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 25 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ aliases:

## tip

* BUGFIX: [vmoperator](https://docs.victoriametrics.com/operator/): keep `resourceVersion` and other significant `metadata` fields during `update` objects requests. See [this issue](https://github.com/VictoriaMetrics/operator/issues/1200) for details.

## [v0.51.0](https://github.com/VictoriaMetrics/operator/releases/tag/v0.51.0)

Expand Down
3 changes: 2 additions & 1 deletion internal/controller/operator/factory/reconcile/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ func ConfigMap(ctx context.Context, rclient client.Client, newCM *corev1.ConfigM
return nil
}

vmv1beta1.AddFinalizer(newCM, &currentCM)
cloneSignificantMetadata(newCM, &currentCM)
newCM.Annotations = mergeAnnotations(currentCM.Annotations, newCM.Annotations, prevAnnotations)

vmv1beta1.AddFinalizer(newCM, &currentCM)
logger.WithContext(ctx).Info(fmt.Sprintf("updating ConfigMap %s configuration", newCM.Name))

return rclient.Update(ctx, newCM)
Expand Down
8 changes: 5 additions & 3 deletions internal/controller/operator/factory/reconcile/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ func Deployment(ctx context.Context, rclient client.Client, newDeploy, prevDeplo
isAnnotationsEqual(currentDeploy.Annotations, newDeploy.Annotations, prevAnnotations) {
return waitDeploymentReady(ctx, rclient, newDeploy, appWaitReadyDeadline)
}

vmv1beta1.AddFinalizer(newDeploy, &currentDeploy)
newDeploy.Annotations = mergeAnnotations(currentDeploy.Annotations, newDeploy.Annotations, prevAnnotations)
cloneSignificantMetadata(newDeploy, &currentDeploy)

logger.WithContext(ctx).Info(fmt.Sprintf("updating Deployment %s configuration"+
"is_prev_equal=%v,is_current_equal=%v,is_prev_nil=%v",
newDeploy.Name, isPrevEqual, isEqual, prevDeploy == nil))

newDeploy.Annotations = mergeAnnotations(currentDeploy.Annotations, newDeploy.Annotations, prevAnnotations)

vmv1beta1.AddFinalizer(newDeploy, &currentDeploy)
if err := rclient.Update(ctx, newDeploy); err != nil {
return fmt.Errorf("cannot update deployment for app: %s, err: %w", newDeploy.Name, err)
}
Expand Down
7 changes: 4 additions & 3 deletions internal/controller/operator/factory/reconcile/hpa.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ func HPA(ctx context.Context, rclient client.Client, newHPA, prevHPA *v2.Horizon
isAnnotationsEqual(currentHPA.Annotations, newHPA.Annotations, prevAnnotations) {
return nil
}
logger.WithContext(ctx).Info(fmt.Sprintf("updating HPA %s configuration", newHPA.Name))

newHPA.ResourceVersion = currentHPA.ResourceVersion
newHPA.Status = currentHPA.Status
newHPA.Annotations = mergeAnnotations(currentHPA.Annotations, newHPA.Annotations, prevAnnotations)
cloneSignificantMetadata(newHPA, &currentHPA)
newHPA.Status = currentHPA.Status

logger.WithContext(ctx).Info(fmt.Sprintf("updating HPA %s configuration", newHPA.Name))

return rclient.Update(ctx, newHPA)
})
Expand Down
5 changes: 1 addition & 4 deletions internal/controller/operator/factory/reconcile/pdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ func PDB(ctx context.Context, rclient client.Client, newPDB, prevPDB *policyv1.P
}
logger.WithContext(ctx).Info(fmt.Sprintf("updating PDB %s configuration", newPDB.Name))

// empty ResourceVersion for some reason produces the following error
// is invalid: metadata.resourceVersion: Invalid value: 0x0: must be specified for an update
// so keep it from current resource
newPDB.ObjectMeta.ResourceVersion = currentPdb.ResourceVersion
cloneSignificantMetadata(newPDB, currentPdb)
// for some reason Status is not marked as status sub-resource at PDB CRD
newPDB.Status = currentPdb.Status
newPDB.Annotations = mergeAnnotations(currentPdb.Annotations, newPDB.Annotations, prevAnnotations)
Expand Down
8 changes: 5 additions & 3 deletions internal/controller/operator/factory/reconcile/pvc.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,17 @@ func PersistentVolumeClaim(ctx context.Context, rclient client.Client, newPVC, p
return nil
}
}
logger.WithContext(ctx).Info(fmt.Sprintf("updating PVC %s configuration", newPVC.Name))

newPVC.Annotations = mergeAnnotations(currentPVC.Annotations, newPVC.Annotations, prevAnnotations)

newResources := newPVC.Spec.Resources.DeepCopy()
// keep old spec with new resource requests
newPVC.Spec = currentPVC.Spec
newPVC.Spec.Resources = *newResources

vmv1beta1.AddFinalizer(newPVC, currentPVC)
newPVC.Annotations = mergeAnnotations(currentPVC.Annotations, newPVC.Annotations, prevAnnotations)
cloneSignificantMetadata(newPVC, currentPVC)

logger.WithContext(ctx).Info(fmt.Sprintf("updating PVC %s configuration", newPVC.Name))

if err := rclient.Update(ctx, newPVC); err != nil {
return err
Expand Down
15 changes: 15 additions & 0 deletions internal/controller/operator/factory/reconcile/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package reconcile

import (
"time"

"sigs.k8s.io/controller-runtime/pkg/client"
)

var (
Expand Down Expand Up @@ -67,3 +69,16 @@ func isAnnotationsEqual(currentA, newA, prevA map[string]string) bool {
}
return true
}

func cloneSignificantMetadata(newObj, currObj client.Object) {
// empty ResourceVersion for some resources produces the following error
// is invalid: metadata.resourceVersion: Invalid value: 0x0: must be specified for an update
// so keep it from current resource
//
newObj.SetResourceVersion(currObj.GetResourceVersion())
// Keep common metadata for consistency sake
newObj.SetGeneration(currObj.GetGeneration())
newObj.SetCreationTimestamp(currObj.GetCreationTimestamp())
newObj.SetUID(currObj.GetUID())
newObj.SetSelfLink(currObj.GetSelfLink())
}
5 changes: 3 additions & 2 deletions internal/controller/operator/factory/reconcile/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ func Secret(ctx context.Context, rclient client.Client, newS *corev1.Secret, pre
isAnnotationsEqual(currentS.Annotations, newS.Annotations, prevAnnotations) {
return nil
}
logger.WithContext(ctx).Info(fmt.Sprintf("updating configuration Secret %s", newS.Name))

newS.Annotations = mergeAnnotations(currentS.Annotations, newS.Annotations, prevAnnotations)
newS.ResourceVersion = currentS.ResourceVersion
cloneSignificantMetadata(newS, &currentS)

logger.WithContext(ctx).Info(fmt.Sprintf("updating configuration Secret %s", newS.Name))

return rclient.Update(ctx, newS)
}
7 changes: 4 additions & 3 deletions internal/controller/operator/factory/reconcile/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,13 @@ func reconcileService(ctx context.Context, rclient client.Client, newService, pr
return nil
}

vmv1beta1.AddFinalizer(newService, currentService)
newService.Annotations = mergeAnnotations(currentService.Annotations, newService.Annotations, prevAnnotations)
cloneSignificantMetadata(newService, currentService)

logger.WithContext(ctx).Info(fmt.Sprintf("updating service %s configuration, is_current_equal=%v, is_prev_equal=%v, is_prev_nil=%v",
newService.Name, isEqual, isPrevServiceEqual, prevService == nil))

newService.Annotations = mergeAnnotations(currentService.Annotations, newService.Annotations, prevAnnotations)
vmv1beta1.AddFinalizer(newService, currentService)

err = rclient.Update(ctx, newService)
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ func ServiceAccount(ctx context.Context, rclient client.Client, newSA, prevSA *c
isAnnotationsEqual(currentSA.Annotations, newSA.Annotations, prevAnnotations) {
return nil
}
logger.WithContext(ctx).Info(fmt.Sprintf("updating ServiceAccount %s metadata", newSA.Name))

currentSA.Annotations = mergeAnnotations(currentSA.Annotations, newSA.Annotations, prevAnnotations)
currentSA.Labels = newSA.Labels
currentSA.Annotations = mergeAnnotations(currentSA.Annotations, newSA.Annotations, prevAnnotations)
vmv1beta1.AddFinalizer(&currentSA, &currentSA)

logger.WithContext(ctx).Info(fmt.Sprintf("updating ServiceAccount %s metadata", newSA.Name))

return rclient.Update(ctx, &currentSA)
})
}
8 changes: 5 additions & 3 deletions internal/controller/operator/factory/reconcile/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,13 @@ func HandleSTSUpdate(ctx context.Context, rclient client.Client, cr STSOptions,
isAnnotationsEqual(currentSts.Annotations, newSts.Annotations, prevAnnotations)

if !shouldSkipUpdate {
logger.WithContext(ctx).Info(fmt.Sprintf("updating statefulset %s configuration, is_current_equal=%v,is_prev_equal=%v,is_prev_nil=%v",
newSts.Name, isEqual, isPrevEqual, prevSts == nil))

newSts.Annotations = mergeAnnotations(currentSts.Annotations, newSts.Annotations, prevAnnotations)
vmv1beta1.AddFinalizer(newSts, &currentSts)
newSts.Annotations = mergeAnnotations(currentSts.Annotations, newSts.Annotations, prevAnnotations)
cloneSignificantMetadata(newSts, &currentSts)

logger.WithContext(ctx).Info(fmt.Sprintf("updating statefulset %s configuration, is_current_equal=%v,is_prev_equal=%v,is_prev_nil=%v",
newSts.Name, isEqual, isPrevEqual, prevSts == nil))

if err := rclient.Update(ctx, newSts); err != nil {
return fmt.Errorf("cannot perform update on sts: %s, err: %w", newSts.Name, err)
Expand Down

0 comments on commit c6b4403

Please sign in to comment.