From bcdea625926e48ff082b068e4f13f7005e6606e2 Mon Sep 17 00:00:00 2001 From: Arnar Gauti Ingason Date: Sat, 27 Jul 2024 15:33:32 +0200 Subject: [PATCH] Improve syncPolicy options for applications --- modules/applications/default.nix | 104 +++++++++++++++++++++++++++++-- modules/nixidy.nix | 22 +++++-- 2 files changed, 117 insertions(+), 9 deletions(-) diff --git a/modules/applications/default.nix b/modules/applications/default.nix index ad7583d..6fb1d55 100644 --- a/modules/applications/default.nix +++ b/modules/applications/default.nix @@ -65,6 +65,11 @@ lib.mkIf (lib.length filtered > 0) { "argocd.argoproj.io/compare-options" = lib.mkDefault (lib.concatStringsSep "," filtered); }; + + convertSyncOptionsList = opts: let + filtered = lib.filter (val: val != null) (lib.mapAttrsToList (_: val: val) opts); + in + filtered; in { imports = [ ./helm.nix @@ -130,25 +135,112 @@ in { }; }; syncPolicy = { - automated = { + autoSync = { + enabled = mkOption { + type = types.bool; + default = nixidyDefaults.syncPolicy.autoSync.enabled; + defaultText = literalExpression "config.nixidy.defaults.syncPolicy.autoSync.enabled"; + description = '' + Specifies if application should automatically sync. + ''; + }; prune = mkOption { type = types.bool; - default = nixidyDefaults.syncPolicy.automated.prune; - defaultText = literalExpression "config.nixidy.defaults.syncPolicy.automated.prune"; + default = nixidyDefaults.syncPolicy.autoSync.prune; + defaultText = literalExpression "config.nixidy.defaults.syncPolicy.autoSync.prune"; description = '' Specifies if resources should be pruned during auto-syncing. ''; }; selfHeal = mkOption { type = types.bool; - default = nixidyDefaults.syncPolicy.automated.selfHeal; - defaultText = literalExpression "config.nixidy.defaults.syncPolicy.automated.selfHeal"; + default = nixidyDefaults.syncPolicy.autoSync.selfHeal; + defaultText = literalExpression "config.nixidy.defaults.syncPolicy.autoSync.selfHeal"; description = '' Specifies if partial app sync should be executed when resources are changed only in target Kubernetes cluster and no git change detected. ''; }; }; + syncOptions = { + applyOutOfSyncOnly = mkOption { + type = types.bool; + default = false; + apply = val: + if val + then "ApplyOutOfSyncOnly=true" + else null; + description = '' + Currently when syncing using auto sync Argo CD applies every object in the application. + For applications containing thousands of objects this takes quite a long time and puts undue pressure on the api server. + Turning on selective sync option which will sync only out-of-sync resources. + ''; + }; + pruneLast = mkOption { + type = types.bool; + default = false; + apply = val: + if val + then "PruneLast=true" + else null; + description = '' + This feature is to allow the ability for resource pruning to happen as a final, implicit wave of a sync operation, + after the other resources have been deployed and become healthy, and after all other waves completed successfully. + ''; + }; + replace = mkOption { + type = types.bool; + default = false; + apply = val: + if val + then "Replace=true" + else null; + description = '' + By default, Argo CD executes `kubectl apply` operation to apply the configuration stored in Git. + In some cases `kubectl apply` is not suitable. For example, resource spec might be too big and won't fit into + `kubectl.kubernetes.io/last-applied-configuration` annotation that is added by kubectl apply. + + If the `replace = true;`` sync option is set the Argo CD will use `kubectl replace` or `kubectl create` command + to apply changes. + ''; + }; + serverSideApply = mkOption { + type = types.bool; + default = false; + apply = val: + if val + then "ServerSideApply=true" + else null; + description = '' + By default, Argo CD executes `kubectl apply` operation to apply the configuration stored in Git. + This is a client side operation that relies on `kubectl.kubernetes.io/last-applied-configuration` annotation to + store the previous resource state. + + If `serverSideApply = true;` sync option is set, Argo CD will use `kubectl apply --server-side` command to apply changes. + + More info [here](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/#server-side-apply). + ''; + }; + failOnSharedResource = mkOption { + type = types.bool; + default = false; + apply = val: + if val + then "FailOnSharedResource=true" + else null; + description = '' + By default, Argo CD will apply all manifests found in the git path configured in the Application regardless if the + resources defined in the yamls are already applied by another Application. If the `failOnSharedResource` sync option + is set, Argo CD will fail the sync whenever it finds a resource in the current Application that is already applied in + the cluster by another Application. + ''; + }; + }; + finalSyncOpts = mkOption { + type = types.listOf types.str; + default = []; + internal = true; + }; }; output = { path = mkOption { @@ -274,5 +366,7 @@ in { config.types); annotations = convertCmpOptionsAnnotation config.compareOptions; + + syncPolicy.finalSyncOpts = convertSyncOptionsList config.syncPolicy.syncOptions; }; } diff --git a/modules/nixidy.nix b/modules/nixidy.nix index 630224e..27274ef 100644 --- a/modules/nixidy.nix +++ b/modules/nixidy.nix @@ -111,7 +111,15 @@ in { }; syncPolicy = { - automated = { + autoSync = { + enabled = mkOption { + type = types.bool; + default = false; + description = '' + Specifies if the application should automatically sync. + This is the default value for all applications if not explicitly set. + ''; + }; prune = mkOption { type = types.bool; default = false; @@ -187,9 +195,15 @@ in { inherit (app) namespace; server = "https://kubernetes.default.svc"; }; - syncPolicy.automated = { - inherit (app.syncPolicy.automated) prune selfHeal; - }; + syncPolicy = + (lib.optionalAttrs (app.syncPolicy.autoSync.enabled) { + automated = { + inherit (app.syncPolicy.autoSync) prune selfHeal; + }; + }) + // (lib.optionalAttrs (lib.length app.syncPolicy.finalSyncOpts > 0) { + syncOptions = app.syncPolicy.finalSyncOpts; + }); }; } )