Skip to content

Commit ea2dbc7

Browse files
pasha-codefreshnerdeveloper
authored andcommitted
feat: retry with client side dry run if server one was failed (argoproj#548)
* feat: retry with client side dry run if server one was failed Signed-off-by: pashakostohrys <[email protected]> * feat: retry with client side dry run if server one was failed Signed-off-by: pashakostohrys <[email protected]> * feat: retry with client side dry run if server one was failed Signed-off-by: pashakostohrys <[email protected]> --------- Signed-off-by: pashakostohrys <[email protected]> Signed-off-by: Obinna Odirionye <[email protected]>
1 parent 4a5648e commit ea2dbc7

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

pkg/sync/sync_context.go

+30-20
Original file line numberDiff line numberDiff line change
@@ -921,29 +921,39 @@ func (sc *syncContext) applyObject(t *syncTask, dryRun, force, validate bool) (c
921921
var err error
922922
var message string
923923
shouldReplace := sc.replace || resourceutil.HasAnnotationOption(t.targetObj, common.AnnotationSyncOptions, common.SyncOptionReplace)
924-
if shouldReplace {
925-
if t.liveObj != nil {
926-
// Avoid using `kubectl replace` for CRDs since 'replace' might recreate resource and so delete all CRD instances.
927-
// The same thing applies for namespaces, which would delete the namespace as well as everything within it,
928-
// so we want to avoid using `kubectl replace` in that case as well.
929-
if kube.IsCRD(t.targetObj) || t.targetObj.GetKind() == kubeutil.NamespaceKind {
930-
update := t.targetObj.DeepCopy()
931-
update.SetResourceVersion(t.liveObj.GetResourceVersion())
932-
_, err = sc.resourceOps.UpdateResource(context.TODO(), update, dryRunStrategy)
933-
if err == nil {
934-
message = fmt.Sprintf("%s/%s updated", t.targetObj.GetKind(), t.targetObj.GetName())
935-
} else {
936-
message = fmt.Sprintf("error when updating: %v", err.Error())
937-
}
938-
} else {
939-
message, err = sc.resourceOps.ReplaceResource(context.TODO(), t.targetObj, dryRunStrategy, force)
924+
applyFn := func(dryRunStrategy cmdutil.DryRunStrategy) (string, error) {
925+
if !shouldReplace {
926+
return sc.resourceOps.ApplyResource(context.TODO(), t.targetObj, dryRunStrategy, force, validate, serverSideApply, sc.serverSideApplyManager)
927+
}
928+
if t.liveObj == nil {
929+
return sc.resourceOps.CreateResource(context.TODO(), t.targetObj, dryRunStrategy, validate)
930+
}
931+
// Avoid using `kubectl replace` for CRDs since 'replace' might recreate resource and so delete all CRD instances.
932+
// The same thing applies for namespaces, which would delete the namespace as well as everything within it,
933+
// so we want to avoid using `kubectl replace` in that case as well.
934+
if kube.IsCRD(t.targetObj) || t.targetObj.GetKind() == kubeutil.NamespaceKind {
935+
update := t.targetObj.DeepCopy()
936+
update.SetResourceVersion(t.liveObj.GetResourceVersion())
937+
_, err = sc.resourceOps.UpdateResource(context.TODO(), update, dryRunStrategy)
938+
if err != nil {
939+
return fmt.Sprintf("error when updating: %v", err.Error()), err
940940
}
941-
} else {
942-
message, err = sc.resourceOps.CreateResource(context.TODO(), t.targetObj, dryRunStrategy, validate)
941+
return fmt.Sprintf("%s/%s updated", t.targetObj.GetKind(), t.targetObj.GetName()), nil
942+
943943
}
944-
} else {
945-
message, err = sc.resourceOps.ApplyResource(context.TODO(), t.targetObj, dryRunStrategy, force, validate, serverSideApply, sc.serverSideApplyManager)
944+
return sc.resourceOps.ReplaceResource(context.TODO(), t.targetObj, dryRunStrategy, force)
945+
}
946+
947+
message, err = applyFn(dryRunStrategy)
948+
949+
// DryRunServer fails with "Kind does not support fieldValidation" error for kubernetes server < 1.25
950+
// it fails inside apply.go , o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind) line
951+
// so we retry with DryRunClient that works for all cases, but cause issues with hooks
952+
// Details: https://github.com/argoproj/argo-cd/issues/16177
953+
if dryRunStrategy == cmdutil.DryRunServer && err != nil {
954+
message, err = applyFn(cmdutil.DryRunClient)
946955
}
956+
947957
if err != nil {
948958
return common.ResultCodeSyncFailed, err.Error()
949959
}

0 commit comments

Comments
 (0)