Repository: argoproj/argo-cd
Pull request #4681 (2020-10-27 16:51:03)

Remove newline from new issue template
While markdown often doesn't care about line breaks in paragraphs, the GitHub renderer in the issue viewer does.

Checklist:

* [x] Either (a) I've created an [enhancement proposal](https://github.com/argoproj/argo-cd/issues/new/choose) and discussed it with the community, (b) this is a bug fix, or (c) this does not need to be in the release notes.
* [x] The title of the PR states what changed and the related issues number (used for the release note).
* [ ] I've updated both the CLI and UI to expose my feature, or I plan to submit a second PR with them.
* [ ] Does this PR require documentation updates?
* [ ] I've updated documentation as required by this PR.
* [ ] Optional. My organization is added to USERS.md.
* [x] I've signed the CLA and my build is green ([troubleshooting builds](https://argoproj.github.io/argo-cd/developer-guide/ci/)). 



Patch:
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 6a08122ca..f5344da2b 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -6,8 +6,7 @@ labels: 'bug'
 assignees: ''
 ---
 
-If you are trying to resolve an environment-specific issue or have a one-off question about the edge case that does not require a feature then please consider asking a
-question in argocd slack [channel](https://argoproj.github.io/community/join-slack).
+If you are trying to resolve an environment-specific issue or have a one-off question about the edge case that does not require a feature then please consider asking a question in argocd slack [channel](https://argoproj.github.io/community/join-slack).
 
 Checklist:
 
diff --git a/.gitignore b/.gitignore
index e8d5124d8..c3885badb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,10 @@ test-results
 .scannerwork
 .scratch
 node_modules/
+
+# ignore built binaries
+cmd/argocd/argocd
+cmd/argocd-application-controller/argocd-application-controller
+cmd/argocd-repo-server/argocd-repo-server
+cmd/argocd-server/argocd-server
+cmd/argocd-util/argocd-util
\ No newline at end of file
diff --git a/cmd/argocd-application-controller/main.go b/cmd/argocd-application-controller/main.go
index d10e772c4..8358e25eb 100644
--- a/cmd/argocd-application-controller/main.go
+++ b/cmd/argocd-application-controller/main.go
@@ -7,8 +7,6 @@ import (
 	"os"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/argoproj/pkg/stats"
 	"github.com/go-redis/redis/v8"
 	log "github.com/sirupsen/logrus"
@@ -33,6 +31,8 @@ import (
 	appstatecache "github.com/argoproj/argo-cd/util/cache/appstate"
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/env"
+	"github.com/argoproj/argo-cd/util/errors"
+	kubeutil "github.com/argoproj/argo-cd/util/kube"
 	"github.com/argoproj/argo-cd/util/settings"
 )
 
@@ -87,7 +87,7 @@ func newCommand() *cobra.Command {
 			errors.CheckError(err)
 
 			settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace)
-			kubectl := &kube.KubectlCmd{}
+			kubectl := kubeutil.NewKubectl()
 			clusterFilter := getClusterFilter()
 			appController, err := controller.NewApplicationController(
 				namespace,
diff --git a/cmd/argocd-repo-server/main.go b/cmd/argocd-repo-server/main.go
index 8c46b86ab..ba17dd9cb 100644
--- a/cmd/argocd-repo-server/main.go
+++ b/cmd/argocd-repo-server/main.go
@@ -8,7 +8,6 @@ import (
 	"os"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/argoproj/pkg/stats"
 	"github.com/go-redis/redis/v8"
 	log "github.com/sirupsen/logrus"
@@ -22,6 +21,7 @@ import (
 	cacheutil "github.com/argoproj/argo-cd/util/cache"
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/env"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/gpg"
 	"github.com/argoproj/argo-cd/util/tls"
 )
diff --git a/cmd/argocd-server/commands/root.go b/cmd/argocd-server/commands/root.go
index f3fd593b9..764b8770e 100644
--- a/cmd/argocd-server/commands/root.go
+++ b/cmd/argocd-server/commands/root.go
@@ -4,15 +4,13 @@ import (
 	"context"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/argoproj/pkg/stats"
 	"github.com/go-redis/redis/v8"
+	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/clientcmd"
 
-	log "github.com/sirupsen/logrus"
-
 	"github.com/argoproj/argo-cd/common"
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
@@ -21,6 +19,7 @@ import (
 	servercache "github.com/argoproj/argo-cd/server/cache"
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/env"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/kube"
 	"github.com/argoproj/argo-cd/util/tls"
 )
diff --git a/cmd/argocd-server/main.go b/cmd/argocd-server/main.go
index e69617659..0f747842c 100644
--- a/cmd/argocd-server/main.go
+++ b/cmd/argocd-server/main.go
@@ -1,9 +1,8 @@
 package main
 
 import (
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-
 	commands "github.com/argoproj/argo-cd/cmd/argocd-server/commands"
+	"github.com/argoproj/argo-cd/util/errors"
 
 	// load the gcp plugin (required to authenticate against GKE clusters).
 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
diff --git a/cmd/argocd-util/commands/apps.go b/cmd/argocd-util/commands/apps.go
index 172784508..c5b8ee311 100644
--- a/cmd/argocd-util/commands/apps.go
+++ b/cmd/argocd-util/commands/apps.go
@@ -9,8 +9,6 @@ import (
 	"sort"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/ghodss/yaml"
 	"github.com/spf13/cobra"
 	apiv1 "k8s.io/api/core/v1"
@@ -32,6 +30,7 @@ import (
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/config"
 	"github.com/argoproj/argo-cd/util/db"
+	"github.com/argoproj/argo-cd/util/errors"
 	kubeutil "github.com/argoproj/argo-cd/util/kube"
 	"github.com/argoproj/argo-cd/util/settings"
 )
@@ -291,7 +290,7 @@ func reconcileApplications(
 	}
 
 	appStateManager := controller.NewAppStateManager(
-		argoDB, appClientset, repoServerClient, namespace, &kube.KubectlCmd{}, settingsMgr, stateCache, projInformer, server)
+		argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server)
 
 	appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(context.Background(), v1.ListOptions{LabelSelector: selector})
 	if err != nil {
@@ -333,5 +332,5 @@ func reconcileApplications(
 }
 
 func newLiveStateCache(argoDB db.ArgoDB, appInformer kubecache.SharedIndexInformer, settingsMgr *settings.SettingsManager, server *metrics.MetricsServer) cache.LiveStateCache {
-	return cache.NewLiveStateCache(argoDB, appInformer, settingsMgr, &kube.KubectlCmd{}, server, func(managedByApp map[string]bool, ref apiv1.ObjectReference) {}, nil)
+	return cache.NewLiveStateCache(argoDB, appInformer, settingsMgr, kubeutil.NewKubectl(), server, func(managedByApp map[string]bool, ref apiv1.ObjectReference) {}, nil)
 }
diff --git a/cmd/argocd-util/commands/projects.go b/cmd/argocd-util/commands/projects.go
index 8d21a98e9..d5276bc3a 100644
--- a/cmd/argocd-util/commands/projects.go
+++ b/cmd/argocd-util/commands/projects.go
@@ -11,8 +11,8 @@ import (
 	appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
 	appclient "github.com/argoproj/argo-cd/pkg/client/clientset/versioned/typed/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/cli"
+	"github.com/argoproj/argo-cd/util/errors"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/spf13/cobra"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/cmd/argocd-util/commands/settings.go b/cmd/argocd-util/commands/settings.go
index d618f1e65..607917c4f 100644
--- a/cmd/argocd-util/commands/settings.go
+++ b/cmd/argocd-util/commands/settings.go
@@ -13,7 +13,6 @@ import (
 	"text/tabwriter"
 
 	healthutil "github.com/argoproj/gitops-engine/pkg/health"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/ghodss/yaml"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
@@ -28,6 +27,7 @@ import (
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/argo/normalizers"
 	"github.com/argoproj/argo-cd/util/cli"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/lua"
 	"github.com/argoproj/argo-cd/util/settings"
 )
diff --git a/cmd/argocd-util/main.go b/cmd/argocd-util/main.go
index 6b86d4c20..8511db9ad 100644
--- a/cmd/argocd-util/main.go
+++ b/cmd/argocd-util/main.go
@@ -11,7 +11,6 @@ import (
 	"reflect"
 	"syscall"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/ghodss/yaml"
 	log "github.com/sirupsen/logrus"
@@ -31,6 +30,7 @@ import (
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/db"
 	"github.com/argoproj/argo-cd/util/dex"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/settings"
 
 	// load the gcp plugin (required to authenticate against GKE clusters).
diff --git a/cmd/argocd/commands/account.go b/cmd/argocd/commands/account.go
index 2cc7b6b22..a3c4c18a2 100644
--- a/cmd/argocd/commands/account.go
+++ b/cmd/argocd/commands/account.go
@@ -10,8 +10,6 @@ import (
 	"text/tabwriter"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	timeutil "github.com/argoproj/pkg/time"
 	"github.com/ghodss/yaml"
 	log "github.com/sirupsen/logrus"
@@ -23,6 +21,8 @@ import (
 	"github.com/argoproj/argo-cd/pkg/apiclient/session"
 	"github.com/argoproj/argo-cd/server/rbacpolicy"
 	"github.com/argoproj/argo-cd/util/cli"
+	"github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/localconfig"
 	sessionutil "github.com/argoproj/argo-cd/util/session"
 )
diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go
index dbc9dec69..fa0fb1ff2 100644
--- a/cmd/argocd/commands/app.go
+++ b/cmd/argocd/commands/app.go
@@ -20,8 +20,6 @@ import (
 	"github.com/argoproj/gitops-engine/pkg/health"
 	"github.com/argoproj/gitops-engine/pkg/sync/hook"
 	"github.com/argoproj/gitops-engine/pkg/sync/ignore"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/ghodss/yaml"
 	log "github.com/sirupsen/logrus"
@@ -49,7 +47,9 @@ import (
 	"github.com/argoproj/argo-cd/util/argo"
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/config"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/git"
+	argoio "github.com/argoproj/argo-cd/util/io"
 	argokube "github.com/argoproj/argo-cd/util/kube"
 	"github.com/argoproj/argo-cd/util/templates"
 	"github.com/argoproj/argo-cd/util/text/label"
@@ -1140,7 +1140,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
 				normalizer, err := argo.NewDiffNormalizer(app.Spec.IgnoreDifferences, overrides)
 				errors.CheckError(err)
 
-				diffRes, err := diff.Diff(item.target, item.live, normalizer, diff.GetDefaultDiffOptions())
+				diffRes, err := diff.Diff(item.target, item.live, diff.WithNormalizer(normalizer))
 				errors.CheckError(err)
 
 				if diffRes.Modified || item.target == nil || item.live == nil {
diff --git a/cmd/argocd/commands/app_actions.go b/cmd/argocd/commands/app_actions.go
index 91794feb2..eb00ed6b3 100644
--- a/cmd/argocd/commands/app_actions.go
+++ b/cmd/argocd/commands/app_actions.go
@@ -8,14 +8,14 @@ import (
 	"strconv"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/ghodss/yaml"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	applicationpkg "github.com/argoproj/argo-cd/pkg/apiclient/application"
+	"github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 type DisplayedAction struct {
diff --git a/cmd/argocd/commands/cert.go b/cmd/argocd/commands/cert.go
index b4e754a53..e62a9f0d0 100644
--- a/cmd/argocd/commands/cert.go
+++ b/cmd/argocd/commands/cert.go
@@ -9,14 +9,14 @@ import (
 	"strings"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/spf13/cobra"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	certificatepkg "github.com/argoproj/argo-cd/pkg/apiclient/certificate"
 	appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	certutil "github.com/argoproj/argo-cd/util/cert"
+	"github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 // NewCertCommand returns a new instance of an `argocd repo` command
diff --git a/cmd/argocd/commands/cluster.go b/cmd/argocd/commands/cluster.go
index 48220280d..645872f57 100644
--- a/cmd/argocd/commands/cluster.go
+++ b/cmd/argocd/commands/cluster.go
@@ -9,8 +9,6 @@ import (
 	"strings"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"k8s.io/client-go/kubernetes"
@@ -22,6 +20,8 @@ import (
 	clusterpkg "github.com/argoproj/argo-cd/pkg/apiclient/cluster"
 	argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/clusterauth"
+	"github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 // NewClusterCommand returns a new instance of an `argocd cluster` command
diff --git a/cmd/argocd/commands/context.go b/cmd/argocd/commands/context.go
index e4f34d045..9cad666ab 100644
--- a/cmd/argocd/commands/context.go
+++ b/cmd/argocd/commands/context.go
@@ -8,11 +8,11 @@ import (
 	"strings"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/localconfig"
 )
 
diff --git a/cmd/argocd/commands/gpg.go b/cmd/argocd/commands/gpg.go
index d96a93418..438a342cb 100644
--- a/cmd/argocd/commands/gpg.go
+++ b/cmd/argocd/commands/gpg.go
@@ -8,13 +8,13 @@ import (
 	"strings"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/spf13/cobra"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	gpgkeypkg "github.com/argoproj/argo-cd/pkg/apiclient/gpgkey"
 	appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
+	"github.com/argoproj/argo-cd/util/errors"
+	argoio "github.com/argoproj/argo-cd/util/io"
 )
 
 // NewGPGCommand returns a new instance of an `argocd repo` command
diff --git a/cmd/argocd/commands/login.go b/cmd/argocd/commands/login.go
index 2f810aae1..67cf246b6 100644
--- a/cmd/argocd/commands/login.go
+++ b/cmd/argocd/commands/login.go
@@ -11,8 +11,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/coreos/go-oidc"
 	"github.com/dgrijalva/jwt-go"
 	log "github.com/sirupsen/logrus"
@@ -24,7 +22,9 @@ import (
 	sessionpkg "github.com/argoproj/argo-cd/pkg/apiclient/session"
 	settingspkg "github.com/argoproj/argo-cd/pkg/apiclient/settings"
 	"github.com/argoproj/argo-cd/util/cli"
+	"github.com/argoproj/argo-cd/util/errors"
 	grpc_util "github.com/argoproj/argo-cd/util/grpc"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/localconfig"
 	oidcutil "github.com/argoproj/argo-cd/util/oidc"
 	"github.com/argoproj/argo-cd/util/rand"
diff --git a/cmd/argocd/commands/logout.go b/cmd/argocd/commands/logout.go
index b433c4aec..832efdcfb 100644
--- a/cmd/argocd/commands/logout.go
+++ b/cmd/argocd/commands/logout.go
@@ -4,11 +4,11 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/localconfig"
 )
 
diff --git a/cmd/argocd/commands/project.go b/cmd/argocd/commands/project.go
index 1c0f73abe..b88f2fe21 100644
--- a/cmd/argocd/commands/project.go
+++ b/cmd/argocd/commands/project.go
@@ -12,8 +12,6 @@ import (
 	"text/tabwriter"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
 	humanize "github.com/dustin/go-humanize"
 	"github.com/ghodss/yaml"
 	log "github.com/sirupsen/logrus"
@@ -28,8 +26,10 @@ import (
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/config"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/git"
 	"github.com/argoproj/argo-cd/util/gpg"
+	argoio "github.com/argoproj/argo-cd/util/io"
 )
 
 type projectOpts struct {
diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go
index 0c4d85585..fb10ac331 100644
--- a/cmd/argocd/commands/project_role.go
+++ b/cmd/argocd/commands/project_role.go
@@ -8,8 +8,6 @@ import (
 	"text/tabwriter"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	timeutil "github.com/argoproj/pkg/time"
 	jwtgo "github.com/dgrijalva/jwt-go"
 	"github.com/spf13/cobra"
@@ -17,6 +15,8 @@ import (
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	projectpkg "github.com/argoproj/argo-cd/pkg/apiclient/project"
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
+	"github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 const (
@@ -38,6 +38,7 @@ func NewProjectRoleCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman
 	roleCommand.AddCommand(NewProjectRoleCreateCommand(clientOpts))
 	roleCommand.AddCommand(NewProjectRoleDeleteCommand(clientOpts))
 	roleCommand.AddCommand(NewProjectRoleCreateTokenCommand(clientOpts))
+	roleCommand.AddCommand(NewProjectRoleListTokensCommand(clientOpts))
 	roleCommand.AddCommand(NewProjectRoleDeleteTokenCommand(clientOpts))
 	roleCommand.AddCommand(NewProjectRoleAddPolicyCommand(clientOpts))
 	roleCommand.AddCommand(NewProjectRoleRemovePolicyCommand(clientOpts))
@@ -213,8 +214,9 @@ func NewProjectRoleCreateTokenCommand(clientOpts *argocdclient.ClientOptions) *c
 		tokenID         string
 	)
 	var command = &cobra.Command{
-		Use:   "create-token PROJECT ROLE-NAME",
-		Short: "Create a project token",
+		Use:     "create-token PROJECT ROLE-NAME",
+		Short:   "Create a project token",
+		Aliases: []string{"token-create"},
 		Run: func(c *cobra.Command, args []string) {
 			if len(args) != 2 {
 				c.HelpFunc()(c, args)
@@ -273,11 +275,63 @@ func NewProjectRoleCreateTokenCommand(clientOpts *argocdclient.ClientOptions) *c
 	return command
 }
 
+func NewProjectRoleListTokensCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
+	var (
+		useUnixTime bool
+	)
+	var command = &cobra.Command{
+		Use:     "list-tokens PROJECT ROLE-NAME",
+		Short:   "List tokens for a given role.",
+		Aliases: []string{"list-token", "token-list"},
+		Run: func(c *cobra.Command, args []string) {
+			if len(args) != 2 {
+				c.HelpFunc()(c, args)
+				os.Exit(1)
+			}
+			projName := args[0]
+			roleName := args[1]
+
+			conn, projIf := argocdclient.NewClientOrDie(clientOpts).NewProjectClientOrDie()
+			defer io.Close(conn)
+
+			proj, err := projIf.Get(context.Background(), &projectpkg.ProjectQuery{Name: projName})
+			errors.CheckError(err)
+			role, _, err := proj.GetRoleByName(roleName)
+			errors.CheckError(err)
+
+			if len(role.JWTTokens) == 0 {
+				fmt.Printf("No tokens for %s.%s\n", projName, roleName)
+				return
+			}
+
+			writer := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
+			_, err = fmt.Fprintf(writer, "ID\tISSUED AT\tEXPIRES AT\n")
+			errors.CheckError(err)
+
+			tokenRowFormat := "%s\t%v\t%v\n"
+			for _, token := range role.JWTTokens {
+				if useUnixTime {
+					_, _ = fmt.Fprintf(writer, tokenRowFormat, token.ID, token.IssuedAt, token.ExpiresAt)
+				} else {
+					_, _ = fmt.Fprintf(writer, tokenRowFormat, token.ID, tokenTimeToString(token.IssuedAt), tokenTimeToString(token.ExpiresAt))
+				}
+			}
+			err = writer.Flush()
+			errors.CheckError(err)
+		},
+	}
+	command.Flags().BoolVarP(&useUnixTime, "unixtime", "u", false,
+		"Print timestamps as Unix time instead of converting. Useful for piping into delete-token.",
+	)
+	return command
+}
+
 // NewProjectRoleDeleteTokenCommand returns a new instance of an `argocd proj role delete-token` command
 func NewProjectRoleDeleteTokenCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
 	var command = &cobra.Command{
-		Use:   "delete-token PROJECT ROLE-NAME ISSUED-AT",
-		Short: "Delete a project token",
+		Use:     "delete-token PROJECT ROLE-NAME ISSUED-AT",
+		Short:   "Delete a project token",
+		Aliases: []string{"token-delete", "remove-token"},
 		Run: func(c *cobra.Command, args []string) {
 			if len(args) != 3 {
 				c.HelpFunc()(c, args)
diff --git a/cmd/argocd/commands/projectwindows.go b/cmd/argocd/commands/projectwindows.go
index 2b808e556..e32952480 100644
--- a/cmd/argocd/commands/projectwindows.go
+++ b/cmd/argocd/commands/projectwindows.go
@@ -8,13 +8,13 @@ import (
 	"strings"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/spf13/cobra"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	projectpkg "github.com/argoproj/argo-cd/pkg/apiclient/project"
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
+	"github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 // NewProjectWindowsCommand returns a new instance of the `argocd proj windows` command
diff --git a/cmd/argocd/commands/relogin.go b/cmd/argocd/commands/relogin.go
index 344baab8f..61cf46310 100644
--- a/cmd/argocd/commands/relogin.go
+++ b/cmd/argocd/commands/relogin.go
@@ -5,14 +5,14 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/coreos/go-oidc"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	settingspkg "github.com/argoproj/argo-cd/pkg/apiclient/settings"
+	"github.com/argoproj/argo-cd/util/errors"
+	argoio "github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/localconfig"
 	"github.com/argoproj/argo-cd/util/session"
 )
diff --git a/cmd/argocd/commands/repo.go b/cmd/argocd/commands/repo.go
index 9bbc35a90..035416e82 100644
--- a/cmd/argocd/commands/repo.go
+++ b/cmd/argocd/commands/repo.go
@@ -7,8 +7,6 @@ import (
 	"os"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
@@ -17,7 +15,9 @@ import (
 	repositorypkg "github.com/argoproj/argo-cd/pkg/apiclient/repository"
 	appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/cli"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/git"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 // NewRepoCommand returns a new instance of an `argocd repo` command
diff --git a/cmd/argocd/commands/repocreds.go b/cmd/argocd/commands/repocreds.go
index 5be819e2d..44fdbbb20 100644
--- a/cmd/argocd/commands/repocreds.go
+++ b/cmd/argocd/commands/repocreds.go
@@ -7,8 +7,6 @@ import (
 	"os"
 	"text/tabwriter"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
@@ -16,7 +14,9 @@ import (
 	repocredspkg "github.com/argoproj/argo-cd/pkg/apiclient/repocreds"
 	appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/cli"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/git"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 // NewRepoCredsCommand returns a new instance of an `argocd repocreds` command
diff --git a/cmd/argocd/commands/root.go b/cmd/argocd/commands/root.go
index 0ffc35636..0b33a5e73 100644
--- a/cmd/argocd/commands/root.go
+++ b/cmd/argocd/commands/root.go
@@ -1,13 +1,13 @@
 package commands
 
 import (
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/spf13/cobra"
 	"k8s.io/client-go/tools/clientcmd"
 
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	"github.com/argoproj/argo-cd/util/cli"
 	"github.com/argoproj/argo-cd/util/config"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/localconfig"
 )
 
diff --git a/cmd/argocd/commands/version.go b/cmd/argocd/commands/version.go
index a4d71c06e..c3a669ed1 100644
--- a/cmd/argocd/commands/version.go
+++ b/cmd/argocd/commands/version.go
@@ -8,12 +8,11 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
-
 	"github.com/argoproj/argo-cd/common"
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	"github.com/argoproj/argo-cd/pkg/apiclient/version"
+	"github.com/argoproj/argo-cd/util/errors"
+	argoio "github.com/argoproj/argo-cd/util/io"
 )
 
 // NewVersionCmd returns a new `version` command to be used as a sub-command to root
diff --git a/cmd/argocd/main.go b/cmd/argocd/main.go
index 394501165..5e1e67133 100644
--- a/cmd/argocd/main.go
+++ b/cmd/argocd/main.go
@@ -1,9 +1,8 @@
 package main
 
 import (
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-
 	commands "github.com/argoproj/argo-cd/cmd/argocd/commands"
+	"github.com/argoproj/argo-cd/util/errors"
 
 	// load the gcp plugin (required to authenticate against GKE clusters).
 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
diff --git a/controller/appcontroller.go b/controller/appcontroller.go
index a5ad93143..52e0e70cf 100644
--- a/controller/appcontroller.go
+++ b/controller/appcontroller.go
@@ -13,11 +13,11 @@ import (
 	"sync"
 	"time"
 
+	logutils "github.com/argoproj/argo-cd/util/log"
+
 	"github.com/argoproj/gitops-engine/pkg/diff"
 	"github.com/argoproj/gitops-engine/pkg/health"
 	synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	log "github.com/sirupsen/logrus"
 	"golang.org/x/sync/semaphore"
@@ -49,6 +49,7 @@ import (
 	"github.com/argoproj/argo-cd/util/argo"
 	appstatecache "github.com/argoproj/argo-cd/util/cache/appstate"
 	"github.com/argoproj/argo-cd/util/db"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/glob"
 	settings_util "github.com/argoproj/argo-cd/util/settings"
 )
@@ -195,7 +196,7 @@ func (ctrl *ApplicationController) GetMetricsServer() *metrics.MetricsServer {
 	return ctrl.metricsServer
 }
 
-func (ctrl *ApplicationController) onKubectlRun(command string) (io.Closer, error) {
+func (ctrl *ApplicationController) onKubectlRun(command string) (kube.CleanupFunc, error) {
 	ctrl.metricsServer.IncKubectlExec(command)
 	if ctrl.kubectlSemaphore != nil {
 		if err := ctrl.kubectlSemaphore.Acquire(context.Background(), 1); err != nil {
@@ -203,13 +204,12 @@ func (ctrl *ApplicationController) onKubectlRun(command string) (io.Closer, erro
 		}
 		ctrl.metricsServer.IncKubectlExecPending(command)
 	}
-	return io.NewCloser(func() error {
+	return func() {
 		if ctrl.kubectlSemaphore != nil {
 			ctrl.kubectlSemaphore.Release(1)
 			ctrl.metricsServer.DecKubectlExecPending(command)
 		}
-		return nil
-	}), nil
+	}, nil
 }
 
 func isSelfReferencedApp(app *appv1.Application, ref v1.ObjectReference) bool {
@@ -409,7 +409,10 @@ func (ctrl *ApplicationController) managedResources(comparisonResult *comparison
 			if err != nil {
 				return nil, err
 			}
-			resDiffPtr, err := diff.Diff(target, live, comparisonResult.diffNormalizer, compareOptions)
+			resDiffPtr, err := diff.Diff(target, live,
+				diff.WithNormalizer(comparisonResult.diffNormalizer),
+				diff.WithLogr(logutils.NewLogrusLogger(log.New())),
+				diff.IgnoreAggregatedRoles(compareOptions.IgnoreAggregatedRoles))
 			if err != nil {
 				return nil, err
 			}
@@ -914,7 +917,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
 }
 
 func (ctrl *ApplicationController) setOperationState(app *appv1.Application, state *appv1.OperationState) {
-	kube.RetryUntilSucceed(context.Background(), updateOperationStateTimeout, "Update application operation state", func() error {
+	kube.RetryUntilSucceed(context.Background(), updateOperationStateTimeout, "Update application operation state", logutils.NewLogrusLogger(log.New()), func() error {
 		if state.Phase == "" {
 			// expose any bugs where we neglect to set phase
 			panic("no phase was set")
diff --git a/controller/cache/cache.go b/controller/cache/cache.go
index f9ea4cb3f..d3521cd00 100644
--- a/controller/cache/cache.go
+++ b/controller/cache/cache.go
@@ -23,6 +23,7 @@ import (
 	appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/argo"
 	"github.com/argoproj/argo-cd/util/db"
+	logutils "github.com/argoproj/argo-cd/util/log"
 	"github.com/argoproj/argo-cd/util/lua"
 	"github.com/argoproj/argo-cd/util/settings"
 )
@@ -264,6 +265,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
 			// want the full resource to be available in our cache (to diff), so we store all CRDs
 			return res, res.AppName != "" || un.GroupVersionKind().Kind == kube.CustomResourceDefinitionKind
 		}),
+		clustercache.SetLogr(logutils.NewLogrusLogger(log.WithField("server", cluster.Server))),
 	)
 
 	_ = clusterCache.OnResourceUpdated(func(newRes *clustercache.Resource, oldRes *clustercache.Resource, namespaceResources map[kube.ResourceKey]*clustercache.Resource) {
@@ -434,7 +436,7 @@ func (c *liveStateCache) Init() error {
 func (c *liveStateCache) Run(ctx context.Context) error {
 	go c.watchSettings(ctx)
 
-	kube.RetryUntilSucceed(ctx, clustercache.ClusterRetryTimeout, "watch clusters", func() error {
+	kube.RetryUntilSucceed(ctx, clustercache.ClusterRetryTimeout, "watch clusters", logutils.NewLogrusLogger(log.New()), func() error {
 		return c.db.WatchClusters(ctx, c.handleAddEvent, c.handleModEvent, c.handleDeleteEvent)
 	})
 
diff --git a/controller/state.go b/controller/state.go
index cff645f0c..2e3d828eb 100644
--- a/controller/state.go
+++ b/controller/state.go
@@ -12,7 +12,6 @@ import (
 	hookutil "github.com/argoproj/gitops-engine/pkg/sync/hook"
 	"github.com/argoproj/gitops-engine/pkg/sync/ignore"
 	resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube"
 	log "github.com/sirupsen/logrus"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -32,6 +31,7 @@ import (
 	"github.com/argoproj/argo-cd/util/db"
 	"github.com/argoproj/argo-cd/util/gpg"
 	argohealth "github.com/argoproj/argo-cd/util/health"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/settings"
 	"github.com/argoproj/argo-cd/util/stats"
 )
@@ -426,12 +426,15 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
 	compareOptions, err := m.settingsMgr.GetResourceCompareOptions()
 	if err != nil {
 		log.Warnf("Could not get compare options from ConfigMap (assuming defaults): %v", err)
-		compareOptions = diff.GetDefaultDiffOptions()
+		compareOptions = settings.GetDefaultDiffOptions()
 	}
 
 	logCtx.Debugf("built managed objects list")
 	// Do the actual comparison
-	diffResults, err := diff.DiffArray(reconciliation.Target, reconciliation.Live, diffNormalizer, compareOptions)
+	diffResults, err := diff.DiffArray(
+		reconciliation.Target, reconciliation.Live,
+		diff.WithNormalizer(diffNormalizer),
+		diff.IgnoreAggregatedRoles(compareOptions.IgnoreAggregatedRoles))
 	if err != nil {
 		diffResults = &diff.DiffResultList{}
 		failedToLoadObjs = true
diff --git a/controller/sync.go b/controller/sync.go
index 706f1b1ff..dedfc71c3 100644
--- a/controller/sync.go
+++ b/controller/sync.go
@@ -19,6 +19,7 @@ import (
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	listersv1alpha1 "github.com/argoproj/argo-cd/pkg/client/listers/application/v1alpha1"
 	"github.com/argoproj/argo-cd/util/argo"
+	logutils "github.com/argoproj/argo-cd/util/log"
 	"github.com/argoproj/argo-cd/util/lua"
 	"github.com/argoproj/argo-cd/util/rand"
 )
@@ -126,7 +127,14 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
 			Order:       i + 1,
 		})
 	}
-	syncCtx, err := sync.NewSyncContext(compareResult.syncStatus.Revision, compareResult.reconciliationResult, restConfig, rawConfig, m.kubectl, app.Spec.Destination.Namespace, logEntry,
+	syncCtx, err := sync.NewSyncContext(
+		compareResult.syncStatus.Revision,
+		compareResult.reconciliationResult,
+		restConfig,
+		rawConfig,
+		m.kubectl,
+		app.Spec.Destination.Namespace,
+		sync.WithLogr(logutils.NewLogrusLogger(logEntry)),
 		sync.WithHealthOverride(lua.ResourceHealthOverrides(resourceOverrides)),
 		sync.WithPermissionValidator(func(un *unstructured.Unstructured, res *v1.APIResource) error {
 			if !proj.IsGroupKindPermitted(un.GroupVersionKind().GroupKind(), res.Namespaced) {
diff --git a/docs/user-guide/commands/argocd_proj_role.md b/docs/user-guide/commands/argocd_proj_role.md
index e81085a5e..934be9beb 100644
--- a/docs/user-guide/commands/argocd_proj_role.md
+++ b/docs/user-guide/commands/argocd_proj_role.md
@@ -47,6 +47,7 @@ argocd proj role [flags]
 * [argocd proj role delete-token](argocd_proj_role_delete-token.md)	 - Delete a project token
 * [argocd proj role get](argocd_proj_role_get.md)	 - Get the details of a specific role
 * [argocd proj role list](argocd_proj_role_list.md)	 - List all the roles in a project
+* [argocd proj role list-tokens](argocd_proj_role_list-tokens.md)	 - List tokens for a given role.
 * [argocd proj role remove-group](argocd_proj_role_remove-group.md)	 - Remove a group claim from a role within a project
 * [argocd proj role remove-policy](argocd_proj_role_remove-policy.md)	 - Remove a policy from a role within a project
 
diff --git a/docs/user-guide/commands/argocd_proj_role_list-tokens.md b/docs/user-guide/commands/argocd_proj_role_list-tokens.md
new file mode 100644
index 000000000..6597fae73
--- /dev/null
+++ b/docs/user-guide/commands/argocd_proj_role_list-tokens.md
@@ -0,0 +1,43 @@
+## argocd proj role list-tokens
+
+List tokens for a given role.
+
+### Synopsis
+
+List tokens for a given role.
+
+```
+argocd proj role list-tokens PROJECT ROLE-NAME [flags]
+```
+
+### Options
+
+```
+  -h, --help       help for list-tokens
+  -u, --unixtime   Print timestamps as Unix time instead of converting. Useful for piping into delete-token.
+```
+
+### Options inherited from parent commands
+
+```
+      --auth-token string               Authentication token
+      --client-crt string               Client certificate file
+      --client-crt-key string           Client certificate key file
+      --config string                   Path to Argo CD config (default "/home/user/.argocd/config")
+      --grpc-web                        Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2.
+      --grpc-web-root-path string       Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root.
+  -H, --header strings                  Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers)
+      --insecure                        Skip server certificate and domain verification
+      --logformat string                Set the logging format. One of: text|json (default "text")
+      --loglevel string                 Set the logging level. One of: debug|info|warn|error (default "info")
+      --plaintext                       Disable TLS
+      --port-forward                    Connect to a random argocd-server port using port forwarding
+      --port-forward-namespace string   Namespace name which should be used for port forwarding
+      --server string                   Argo CD server address
+      --server-crt string               Server certificate file
+```
+
+### SEE ALSO
+
+* [argocd proj role](argocd_proj_role.md)	 - Manage a project's roles
+
diff --git a/go.mod b/go.mod
index f6b299ceb..61e098b29 100644
--- a/go.mod
+++ b/go.mod
@@ -7,8 +7,9 @@ require (
 	github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
 	github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 // indirect
 	github.com/alicebob/miniredis v2.5.0+incompatible
-	github.com/argoproj/gitops-engine v0.1.3-0.20201014183719-4eb3ca3feefb
+	github.com/argoproj/gitops-engine v0.1.3-0.20201027001456-31311943a57a
 	github.com/argoproj/pkg v0.2.0
+	github.com/bombsimon/logrusr v0.0.0-20200131103305-03a291ce59b4
 	github.com/casbin/casbin v1.9.1
 	github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
 	github.com/coreos/go-oidc v2.1.0+incompatible
@@ -18,6 +19,7 @@ require (
 	github.com/evanphx/json-patch v4.9.0+incompatible
 	github.com/fsnotify/fsnotify v1.4.9
 	github.com/ghodss/yaml v1.0.0
+	github.com/go-logr/logr v0.2.1
 	github.com/go-openapi/loads v0.19.4
 	github.com/go-openapi/runtime v0.19.4
 	github.com/go-openapi/spec v0.19.3
diff --git a/go.sum b/go.sum
index 5d9ed22bc..ad7a36508 100644
--- a/go.sum
+++ b/go.sum
@@ -84,8 +84,8 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
-github.com/argoproj/gitops-engine v0.1.3-0.20201014183719-4eb3ca3feefb h1:lf5CH6YyPqBJhg7DEI7h75A/Bu4Sfv9OjPePr0mlDl0=
-github.com/argoproj/gitops-engine v0.1.3-0.20201014183719-4eb3ca3feefb/go.mod h1:q1l0iuCyihknkeO3ne6cvOuagsp2NR+7ijRovlDz254=
+github.com/argoproj/gitops-engine v0.1.3-0.20201027001456-31311943a57a h1:ShQaYWNaNKJ8iy65vkftl6jYbDU2kLiAdQ0XJ8LSlOo=
+github.com/argoproj/gitops-engine v0.1.3-0.20201027001456-31311943a57a/go.mod h1:7Hzxz1c5YFXpAsM+i9L4LzKPnt8oY0t9QaGgEEUbQuc=
 github.com/argoproj/pkg v0.2.0 h1:ETgC600kr8WcAi3MEVY5sA1H7H/u1/IysYOobwsZ8No=
 github.com/argoproj/pkg v0.2.0/go.mod h1:F4TZgInLUEjzsWFB/BTJBsewoEy0ucnKSq6vmQiD/yc=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -111,6 +111,8 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
 github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
+github.com/bombsimon/logrusr v0.0.0-20200131103305-03a291ce59b4 h1:Myj4mlaLi25AoncNPb8uf+Riru0Mp4xw7S9RUxBCYxk=
+github.com/bombsimon/logrusr v0.0.0-20200131103305-03a291ce59b4/go.mod h1:Jq0nHtvxabKE5EMwAAdgTaz7dfWE8C4i11NOltxGQpc=
 github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E=
 github.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=
 github.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog=
@@ -236,6 +238,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
 github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY=
 github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
+github.com/go-logr/logr v0.2.1 h1:fV3MLmabKIZ383XifUjFSwcoGee0v9qgPp8wy5svibE=
+github.com/go-logr/logr v0.2.1/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
 github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
 github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@@ -324,6 +328,8 @@ github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200j
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
 github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
diff --git a/pkg/apiclient/apiclient.go b/pkg/apiclient/apiclient.go
index 136145434..f862e8351 100644
--- a/pkg/apiclient/apiclient.go
+++ b/pkg/apiclient/apiclient.go
@@ -15,9 +15,6 @@ import (
 	"sync"
 	"time"
 
-	"github.com/argoproj/argo-cd/util/kube"
-
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/coreos/go-oidc"
 	"github.com/dgrijalva/jwt-go"
 	log "github.com/sirupsen/logrus"
@@ -43,6 +40,8 @@ import (
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	grpc_util "github.com/argoproj/argo-cd/util/grpc"
+	argoio "github.com/argoproj/argo-cd/util/io"
+	"github.com/argoproj/argo-cd/util/kube"
 	"github.com/argoproj/argo-cd/util/localconfig"
 	oidcutil "github.com/argoproj/argo-cd/util/oidc"
 	tls_util "github.com/argoproj/argo-cd/util/tls"
diff --git a/pkg/apiclient/grpcproxy.go b/pkg/apiclient/grpcproxy.go
index a7fb83902..0c8e3ed65 100644
--- a/pkg/apiclient/grpcproxy.go
+++ b/pkg/apiclient/grpcproxy.go
@@ -11,13 +11,13 @@ import (
 	"strconv"
 	"strings"
 
-	argocderrors "github.com/argoproj/gitops-engine/pkg/utils/errors"
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/status"
 
+	argocderrors "github.com/argoproj/argo-cd/util/errors"
+	argoio "github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/rand"
 )
 
diff --git a/reposerver/apiclient/clientset.go b/reposerver/apiclient/clientset.go
index 788363f8b..945fdbbeb 100644
--- a/reposerver/apiclient/clientset.go
+++ b/reposerver/apiclient/clientset.go
@@ -4,7 +4,6 @@ import (
 	"crypto/tls"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
 	grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
 	log "github.com/sirupsen/logrus"
@@ -12,6 +11,7 @@ import (
 	"google.golang.org/grpc/credentials"
 
 	argogrpc "github.com/argoproj/argo-cd/util/grpc"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 const (
diff --git a/reposerver/apiclient/mocks/Clientset.go b/reposerver/apiclient/mocks/Clientset.go
index 9f33e845f..a41b33455 100644
--- a/reposerver/apiclient/mocks/Clientset.go
+++ b/reposerver/apiclient/mocks/Clientset.go
@@ -3,7 +3,7 @@ package mocks
 import (
 	apiclient "github.com/argoproj/argo-cd/reposerver/apiclient"
 
-	io "github.com/argoproj/gitops-engine/pkg/utils/io"
+	io "github.com/argoproj/argo-cd/util/io"
 )
 
 type Clientset struct {
diff --git a/reposerver/repository/lock.go b/reposerver/repository/lock.go
index 385ac4a1d..86cb37186 100644
--- a/reposerver/repository/lock.go
+++ b/reposerver/repository/lock.go
@@ -4,7 +4,7 @@ import (
 	"io"
 	"sync"
 
-	ioutil "github.com/argoproj/gitops-engine/pkg/utils/io"
+	ioutil "github.com/argoproj/argo-cd/util/io"
 )
 
 func NewRepositoryLock() *repositoryLock {
diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go
index 68c040803..c222c0a39 100644
--- a/reposerver/repository/repository.go
+++ b/reposerver/repository/repository.go
@@ -17,7 +17,6 @@ import (
 
 	"github.com/Masterminds/semver"
 	"github.com/TomOnTime/utfutil"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	textutils "github.com/argoproj/gitops-engine/pkg/utils/text"
 	"github.com/argoproj/pkg/sync"
@@ -44,6 +43,7 @@ import (
 	"github.com/argoproj/argo-cd/util/git"
 	"github.com/argoproj/argo-cd/util/gpg"
 	"github.com/argoproj/argo-cd/util/helm"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/ksonnet"
 	argokube "github.com/argoproj/argo-cd/util/kube"
 	"github.com/argoproj/argo-cd/util/kustomize"
diff --git a/server/application/application.go b/server/application/application.go
index ac2fdc4dd..f3fd7ca02 100644
--- a/server/application/application.go
+++ b/server/application/application.go
@@ -16,7 +16,6 @@ import (
 	"github.com/Masterminds/semver"
 	"github.com/argoproj/gitops-engine/pkg/diff"
 	"github.com/argoproj/gitops-engine/pkg/sync/common"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/argoproj/gitops-engine/pkg/utils/text"
 	"github.com/argoproj/pkg/sync"
@@ -53,6 +52,7 @@ import (
 	"github.com/argoproj/argo-cd/util/env"
 	"github.com/argoproj/argo-cd/util/git"
 	"github.com/argoproj/argo-cd/util/helm"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/lua"
 	"github.com/argoproj/argo-cd/util/rbac"
 	"github.com/argoproj/argo-cd/util/session"
diff --git a/server/repository/repository.go b/server/repository/repository.go
index fee4dd86f..7672bb8b8 100644
--- a/server/repository/repository.go
+++ b/server/repository/repository.go
@@ -4,7 +4,6 @@ import (
 	"fmt"
 	"reflect"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/argoproj/gitops-engine/pkg/utils/text"
 	log "github.com/sirupsen/logrus"
@@ -21,6 +20,7 @@ import (
 	"github.com/argoproj/argo-cd/server/rbacpolicy"
 	"github.com/argoproj/argo-cd/util/argo"
 	"github.com/argoproj/argo-cd/util/db"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/rbac"
 	"github.com/argoproj/argo-cd/util/settings"
 )
diff --git a/server/server.go b/server/server.go
index e2531e847..ff42dca80 100644
--- a/server/server.go
+++ b/server/server.go
@@ -19,9 +19,6 @@ import (
 	// nolint:staticcheck
 	golang_proto "github.com/golang/protobuf/proto"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
-	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/argoproj/pkg/jwt/zjwt"
 	"github.com/argoproj/pkg/sync"
 	"github.com/dgrijalva/jwt-go"
@@ -89,9 +86,12 @@ import (
 	"github.com/argoproj/argo-cd/util/dex"
 	dexutil "github.com/argoproj/argo-cd/util/dex"
 	"github.com/argoproj/argo-cd/util/env"
+	"github.com/argoproj/argo-cd/util/errors"
 	grpc_util "github.com/argoproj/argo-cd/util/grpc"
 	"github.com/argoproj/argo-cd/util/healthz"
 	httputil "github.com/argoproj/argo-cd/util/http"
+	"github.com/argoproj/argo-cd/util/io"
+	kubeutil "github.com/argoproj/argo-cd/util/kube"
 	"github.com/argoproj/argo-cd/util/oidc"
 	"github.com/argoproj/argo-cd/util/rbac"
 	util_session "github.com/argoproj/argo-cd/util/session"
@@ -516,7 +516,7 @@ func (a *ArgoCDServer) newGRPCServer() *grpc.Server {
 	)))
 	grpcS := grpc.NewServer(sOpts...)
 	db := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset)
-	kubectl := &kube.KubectlCmd{}
+	kubectl := kubeutil.NewKubectl()
 	clusterService := cluster.NewServer(db, a.enf, a.Cache, kubectl)
 	repoService := repository.NewServer(a.RepoClientset, db, a.enf, a.Cache, a.settingsMgr)
 	repoCredsService := repocreds.NewServer(a.RepoClientset, db, a.enf, a.settingsMgr)
diff --git a/server/session/ratelimiter.go b/server/session/ratelimiter.go
index 5bc432604..cd1b2ed98 100644
--- a/server/session/ratelimiter.go
+++ b/server/session/ratelimiter.go
@@ -1,12 +1,11 @@
 package session
 
 import (
+	util "github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/session"
 
-	"golang.org/x/sync/semaphore"
-
-	util "github.com/argoproj/gitops-engine/pkg/utils/io"
 	log "github.com/sirupsen/logrus"
+	"golang.org/x/sync/semaphore"
 )
 
 func NewLoginRateLimiter(maxNumber int) func() (util.Closer, error) {
diff --git a/server/session/session.go b/server/session/session.go
index ab8fa6a93..480dec68c 100644
--- a/server/session/session.go
+++ b/server/session/session.go
@@ -3,12 +3,12 @@ package session
 import (
 	"context"
 
-	util "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 
 	"github.com/argoproj/argo-cd/pkg/apiclient/session"
 	"github.com/argoproj/argo-cd/server/rbacpolicy"
+	util "github.com/argoproj/argo-cd/util/io"
 	sessionmgr "github.com/argoproj/argo-cd/util/session"
 )
 
diff --git a/server/version/version.go b/server/version/version.go
index 806cfcbd4..d1ab03254 100644
--- a/server/version/version.go
+++ b/server/version/version.go
@@ -1,17 +1,24 @@
 package version
 
 import (
-	"github.com/argoproj/gitops-engine/pkg/utils/kube"
-	"github.com/golang/protobuf/ptypes/empty"
-	"golang.org/x/net/context"
+	"errors"
+	"fmt"
+	"os/exec"
+	"regexp"
+	"strings"
 
+	"github.com/argoproj/gitops-engine/pkg/utils/tracing"
+	"github.com/golang/protobuf/ptypes/empty"
 	"github.com/google/go-jsonnet"
+	"github.com/sirupsen/logrus"
+	"golang.org/x/net/context"
 
 	"github.com/argoproj/argo-cd/common"
 	"github.com/argoproj/argo-cd/pkg/apiclient/version"
 	"github.com/argoproj/argo-cd/util/helm"
 	ksutil "github.com/argoproj/argo-cd/util/ksonnet"
 	"github.com/argoproj/argo-cd/util/kustomize"
+	"github.com/argoproj/argo-cd/util/log"
 )
 
 type Server struct {
@@ -22,6 +29,27 @@ type Server struct {
 	jsonnetVersion   string
 }
 
+func getVersion() (string, error) {
+	span := tracing.NewLoggingTracer(log.NewLogrusLogger(logrus.New())).StartSpan("Version")
+	defer span.Finish()
+	cmd := exec.Command("kubectl", "version", "--client")
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return "", fmt.Errorf("could not get kubectl version: %s", err)
+	}
+
+	re := regexp.MustCompile(`GitVersion:"([a-zA-Z0-9\.\-]+)"`)
+	matches := re.FindStringSubmatch(string(out))
+	if len(matches) != 2 {
+		return "", errors.New("could not get kubectl version")
+	}
+	version := matches[1]
+	if version[0] != 'v' {
+		version = "v" + version
+	}
+	return strings.TrimSpace(version), nil
+}
+
 // Version returns the version of the API server
 func (s *Server) Version(context.Context, *empty.Empty) (*version.VersionMessage, error) {
 	vers := common.GetVersion()
@@ -50,7 +78,7 @@ func (s *Server) Version(context.Context, *empty.Empty) (*version.VersionMessage
 		}
 	}
 	if s.kubectlVersion == "" {
-		kubectlVersion, err := kube.Version()
+		kubectlVersion, err := getVersion()
 		if err == nil {
 			s.kubectlVersion = kubectlVersion
 		} else {
diff --git a/util/argo/argo.go b/util/argo/argo.go
index f7dd86799..972762209 100644
--- a/util/argo/argo.go
+++ b/util/argo/argo.go
@@ -7,7 +7,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	log "github.com/sirupsen/logrus"
 	"google.golang.org/grpc/codes"
@@ -25,6 +24,7 @@ import (
 	"github.com/argoproj/argo-cd/util/db"
 	"github.com/argoproj/argo-cd/util/git"
 	"github.com/argoproj/argo-cd/util/helm"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/settings"
 )
 
diff --git a/util/cache/redis.go b/util/cache/redis.go
index ab280567b..3510646b7 100644
--- a/util/cache/redis.go
+++ b/util/cache/redis.go
@@ -4,7 +4,8 @@ import (
 	"context"
 	"time"
 
-	ioutil "github.com/argoproj/gitops-engine/pkg/utils/io"
+	ioutil "github.com/argoproj/argo-cd/util/io"
+
 	rediscache "github.com/go-redis/cache/v8"
 	"github.com/go-redis/redis/v8"
 )
diff --git a/util/cli/cli.go b/util/cli/cli.go
index 77c346301..2c8ca3f87 100644
--- a/util/cli/cli.go
+++ b/util/cli/cli.go
@@ -14,8 +14,6 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/google/shlex"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
@@ -27,6 +25,8 @@ import (
 	"sigs.k8s.io/yaml"
 
 	"github.com/argoproj/argo-cd/common"
+	"github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 // NewVersionCmd returns a new `version` command to be used as a sub-command to root
diff --git a/util/dex/dex.go b/util/dex/dex.go
index 4dbeba2bd..9676d1efa 100644
--- a/util/dex/dex.go
+++ b/util/dex/dex.go
@@ -12,7 +12,7 @@ import (
 	"regexp"
 	"strconv"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 var messageRe = regexp.MustCompile(`<p>(.*)([\s\S]*?)<\/p>`)
diff --git a/util/errors/errors.go b/util/errors/errors.go
new file mode 100644
index 000000000..f7f718682
--- /dev/null
+++ b/util/errors/errors.go
@@ -0,0 +1,59 @@
+package errors
+
+import (
+	"os"
+
+	log "github.com/sirupsen/logrus"
+)
+
+const (
+	// ErrorCommandSpecific is reserved for command specific indications
+	ErrorCommandSpecific = 1
+	// ErrorConnectionFailure is returned on connection failure to API endpoint
+	ErrorConnectionFailure = 11
+	// ErrorAPIResponse is returned on unexpected API response, i.e. authorization failure
+	ErrorAPIResponse = 12
+	// ErrorResourceDoesNotExist is returned when the requested resource does not exist
+	ErrorResourceDoesNotExist = 13
+	// ErrorGeneric is returned for generic error
+	ErrorGeneric = 20
+)
+
+// CheckError logs a fatal message and exits with ErrorGeneric if err is not nil
+func CheckError(err error) {
+	if err != nil {
+		Fatal(ErrorGeneric, err)
+	}
+}
+
+// CheckErrorWithCode is a convenience function to exit if an error is non-nil and exit if it was
+func CheckErrorWithCode(err error, exitcode int) {
+	if err != nil {
+		Fatal(exitcode, err)
+	}
+}
+
+// FailOnErr panics if there is an error. It returns the first value so you can use it if you cast it:
+// text := FailOrErr(Foo)).(string)
+func FailOnErr(v interface{}, err error) interface{} {
+	CheckError(err)
+	return v
+}
+
+// Fatal is a wrapper for logrus.Fatal() to exit with custom code
+func Fatal(exitcode int, args ...interface{}) {
+	exitfunc := func() {
+		os.Exit(exitcode)
+	}
+	log.RegisterExitHandler(exitfunc)
+	log.Fatal(args...)
+}
+
+// Fatalf is a wrapper for logrus.Fatalf() to exit with custom code
+func Fatalf(exitcode int, format string, args ...interface{}) {
+	exitfunc := func() {
+		os.Exit(exitcode)
+	}
+	log.RegisterExitHandler(exitfunc)
+	log.Fatalf(format, args...)
+}
diff --git a/util/exec/exec.go b/util/exec/exec.go
index cfd57575c..e35df987c 100644
--- a/util/exec/exec.go
+++ b/util/exec/exec.go
@@ -6,6 +6,10 @@ import (
 	"os/exec"
 	"time"
 
+	"github.com/sirupsen/logrus"
+
+	"github.com/argoproj/argo-cd/util/log"
+
 	argoexec "github.com/argoproj/pkg/exec"
 
 	tracing "github.com/argoproj/gitops-engine/pkg/utils/tracing"
@@ -30,7 +34,7 @@ func Run(cmd *exec.Cmd) (string, error) {
 }
 
 func RunWithRedactor(cmd *exec.Cmd, redactor func(text string) string) (string, error) {
-	span := tracing.StartSpan(fmt.Sprintf("exec %v", cmd.Args[0]))
+	span := tracing.NewLoggingTracer(log.NewLogrusLogger(logrus.New())).StartSpan(fmt.Sprintf("exec %v", cmd.Args[0]))
 	span.SetBaggageItem("dir", fmt.Sprintf("%v", cmd.Dir))
 	span.SetBaggageItem("args", fmt.Sprintf("%v", cmd.Args))
 	defer span.Finish()
diff --git a/util/helm/client.go b/util/helm/client.go
index a5ca3de87..9f85c4fe9 100644
--- a/util/helm/client.go
+++ b/util/helm/client.go
@@ -17,12 +17,12 @@ import (
 	"time"
 
 	"github.com/Masterminds/semver"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/pkg/sync"
 	log "github.com/sirupsen/logrus"
 	"gopkg.in/yaml.v2"
 
 	executil "github.com/argoproj/argo-cd/util/exec"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 var (
diff --git a/util/helm/cmd.go b/util/helm/cmd.go
index 3c3a84222..838ff9d46 100644
--- a/util/helm/cmd.go
+++ b/util/helm/cmd.go
@@ -9,9 +9,8 @@ import (
 	"path/filepath"
 	"regexp"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
-
 	executil "github.com/argoproj/argo-cd/util/exec"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 // A thin wrapper around the "helm" command, adding logging and error translation.
diff --git a/util/helm/mocks/Client.go b/util/helm/mocks/Client.go
index 9253a3742..c0f2d7e6a 100644
--- a/util/helm/mocks/Client.go
+++ b/util/helm/mocks/Client.go
@@ -5,7 +5,7 @@ package mocks
 import (
 	helm "github.com/argoproj/argo-cd/util/helm"
 
-	io "github.com/argoproj/gitops-engine/pkg/utils/io"
+	io "github.com/argoproj/argo-cd/util/io"
 
 	mock "github.com/stretchr/testify/mock"
 
diff --git a/util/io/closer.go b/util/io/closer.go
new file mode 100644
index 000000000..7ca4981e9
--- /dev/null
+++ b/util/io/closer.go
@@ -0,0 +1,33 @@
+package io
+
+import log "github.com/sirupsen/logrus"
+
+var (
+	NopCloser = NewCloser(func() error {
+		return nil
+	})
+)
+
+type Closer interface {
+	Close() error
+}
+
+type inlineCloser struct {
+	close func() error
+}
+
+func (c *inlineCloser) Close() error {
+	return c.close()
+}
+
+func NewCloser(close func() error) Closer {
+	return &inlineCloser{close: close}
+}
+
+// Close is a convenience function to close a object that has a Close() method, ignoring any errors
+// Used to satisfy errcheck lint
+func Close(c Closer) {
+	if err := c.Close(); err != nil {
+		log.Warnf("failed to close %v: %v", c, err)
+	}
+}
diff --git a/util/kube/kubectl.go b/util/kube/kubectl.go
new file mode 100644
index 000000000..bca8aa3ed
--- /dev/null
+++ b/util/kube/kubectl.go
@@ -0,0 +1,23 @@
+package kube
+
+import (
+	"os"
+
+	"github.com/argoproj/argo-cd/util/log"
+
+	"github.com/argoproj/gitops-engine/pkg/utils/kube"
+	"github.com/argoproj/gitops-engine/pkg/utils/tracing"
+	"github.com/sirupsen/logrus"
+)
+
+var tracer tracing.Tracer = &tracing.NopTracer{}
+
+func init() {
+	if os.Getenv("ARGOCD_TRACING_ENABLED") == "1" {
+		tracer = tracing.NewLoggingTracer(log.NewLogrusLogger(logrus.New()))
+	}
+}
+
+func NewKubectl() kube.Kubectl {
+	return &kube.KubectlCmd{Tracer: tracer, Log: log.NewLogrusLogger(logrus.New())}
+}
diff --git a/util/kube/portforwarder.go b/util/kube/portforwarder.go
index c915709f8..addcb3ad9 100644
--- a/util/kube/portforwarder.go
+++ b/util/kube/portforwarder.go
@@ -9,13 +9,14 @@ import (
 	"net/http"
 	"os"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/pkg/errors"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/clientcmd"
 	"k8s.io/client-go/tools/portforward"
 	"k8s.io/client-go/transport/spdy"
+
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 func PortForward(podSelector string, targetPort int, namespace string) (int, error) {
diff --git a/util/log/logrus.go b/util/log/logrus.go
new file mode 100644
index 000000000..ecb725a61
--- /dev/null
+++ b/util/log/logrus.go
@@ -0,0 +1,11 @@
+package log
+
+import (
+	adapter "github.com/bombsimon/logrusr"
+	"github.com/go-logr/logr"
+	"github.com/sirupsen/logrus"
+)
+
+func NewLogrusLogger(fieldLogger logrus.FieldLogger) logr.Logger {
+	return adapter.NewLogger(fieldLogger)
+}
diff --git a/util/settings/settings.go b/util/settings/settings.go
index 45772728a..7c9b487d2 100644
--- a/util/settings/settings.go
+++ b/util/settings/settings.go
@@ -15,7 +15,6 @@ import (
 	"sync"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/diff"
 	"github.com/ghodss/yaml"
 	log "github.com/sirupsen/logrus"
 	apiv1 "k8s.io/api/core/v1"
@@ -280,7 +279,7 @@ const (
 )
 
 type ArgoCDDiffOptions struct {
-	diff.DiffOptions
+	IgnoreAggregatedRoles bool `json:"ignoreAggregatedRoles,omitempty"`
 
 	// If set to true then differences caused by status are ignored.
 	IgnoreResourceStatusField IgnoreStatus `json:"ignoreResourceStatusField,omitempty"`
@@ -518,10 +517,14 @@ func addStatusOverrideToGK(resourceOverrides map[string]v1alpha1.ResourceOverrid
 	}
 }
 
+func GetDefaultDiffOptions() ArgoCDDiffOptions {
+	return ArgoCDDiffOptions{IgnoreAggregatedRoles: false}
+}
+
 // GetResourceCompareOptions loads the resource compare options settings from the ConfigMap
-func (mgr *SettingsManager) GetResourceCompareOptions() (diff.DiffOptions, error) {
+func (mgr *SettingsManager) GetResourceCompareOptions() (ArgoCDDiffOptions, error) {
 	// We have a sane set of default diff options
-	diffOptions := diff.GetDefaultDiffOptions()
+	diffOptions := GetDefaultDiffOptions()
 
 	argoCDCM, err := mgr.getConfigMap()
 	if err != nil {


Test patch:
diff --git a/cmd/argocd-util/commands/settings_test.go b/cmd/argocd-util/commands/settings_test.go
index b8c43fc1b..9fce15fef 100644
--- a/cmd/argocd-util/commands/settings_test.go
+++ b/cmd/argocd-util/commands/settings_test.go
@@ -10,9 +10,9 @@ import (
 	"testing"
 
 	"github.com/argoproj/argo-cd/common"
+	utils "github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/settings"
 
-	utils "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/reposerver/repository/lock_test.go b/reposerver/repository/lock_test.go
index a3ec5d274..b3b5f449b 100644
--- a/reposerver/repository/lock_test.go
+++ b/reposerver/repository/lock_test.go
@@ -8,7 +8,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 
-	util "github.com/argoproj/gitops-engine/pkg/utils/io"
+	util "github.com/argoproj/argo-cd/util/io"
 )
 
 // execute given action and return false if action have not completed within 1 second
diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go
index 86827ac52..4792c8993 100644
--- a/reposerver/repository/repository_test.go
+++ b/reposerver/repository/repository_test.go
@@ -15,7 +15,6 @@ import (
 	"time"
 
 	"github.com/Masterminds/semver"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/ghodss/yaml"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
@@ -33,6 +32,7 @@ import (
 	gitmocks "github.com/argoproj/argo-cd/util/git/mocks"
 	"github.com/argoproj/argo-cd/util/helm"
 	helmmocks "github.com/argoproj/argo-cd/util/helm/mocks"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 const testSignature = `gpg: Signature made Wed Feb 26 23:22:34 2020 CET
diff --git a/resource_customizations/custom_actions_test.go b/resource_customizations/custom_actions_test.go
index 853a85146..9c74d0146 100644
--- a/resource_customizations/custom_actions_test.go
+++ b/resource_customizations/custom_actions_test.go
@@ -98,7 +98,7 @@ func TestLuaResourceActionsScript(t *testing.T) {
 
 				expectedObj := getObj(filepath.Join(dir, test.ExpectedOutputPath))
 				// Ideally, we would use a assert.Equal to detect the difference, but the Lua VM returns a object with float64 instead of the original int32.  As a result, the assert.Equal is never true despite that the change has been applied.
-				diffResult, err := diff.Diff(expectedObj, result, testNormalizer{}, diff.GetDefaultDiffOptions())
+				diffResult, err := diff.Diff(expectedObj, result, diff.WithNormalizer(testNormalizer{}))
 				assert.NoError(t, err)
 				if diffResult.Modified {
 					t.Error("Output does not match input:")
diff --git a/resource_customizations/health_test.go b/resource_customizations/health_test.go
index 09eb2f90d..2f669c82b 100644
--- a/resource_customizations/health_test.go
+++ b/resource_customizations/health_test.go
@@ -8,11 +8,11 @@ import (
 	"testing"
 
 	"github.com/argoproj/gitops-engine/pkg/health"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/ghodss/yaml"
 	"github.com/stretchr/testify/assert"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/lua"
 )
 
diff --git a/server/account/account_test.go b/server/account/account_test.go
index 86e3f23e6..91982166c 100644
--- a/server/account/account_test.go
+++ b/server/account/account_test.go
@@ -5,7 +5,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/dgrijalva/jwt-go"
 	"github.com/stretchr/testify/assert"
 	"google.golang.org/grpc/codes"
@@ -18,6 +17,7 @@ import (
 	"github.com/argoproj/argo-cd/pkg/apiclient/account"
 	sessionpkg "github.com/argoproj/argo-cd/pkg/apiclient/session"
 	"github.com/argoproj/argo-cd/server/session"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/password"
 	"github.com/argoproj/argo-cd/util/rbac"
 	sessionutil "github.com/argoproj/argo-cd/util/session"
diff --git a/server/application/application_test.go b/server/application/application_test.go
index b18bb7a3a..b49473256 100644
--- a/server/application/application_test.go
+++ b/server/application/application_test.go
@@ -7,7 +7,6 @@ import (
 	"time"
 
 	synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest"
 	"github.com/argoproj/pkg/sync"
 	"github.com/dgrijalva/jwt-go"
@@ -38,6 +37,7 @@ import (
 	"github.com/argoproj/argo-cd/util/assets"
 	"github.com/argoproj/argo-cd/util/cache"
 	"github.com/argoproj/argo-cd/util/db"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/rbac"
 	"github.com/argoproj/argo-cd/util/settings"
 )
diff --git a/server/session/ratelimiter_test.go b/server/session/ratelimiter_test.go
index 8a3968cb7..1b9524e79 100644
--- a/server/session/ratelimiter_test.go
+++ b/server/session/ratelimiter_test.go
@@ -3,9 +3,9 @@ package session
 import (
 	"testing"
 
-	util "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/stretchr/testify/assert"
 
+	util "github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/session"
 )
 
diff --git a/test/e2e/accounts_test.go b/test/e2e/accounts_test.go
index 8b04de5f7..10fff428c 100644
--- a/test/e2e/accounts_test.go
+++ b/test/e2e/accounts_test.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"testing"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/pkg/errors"
 	"github.com/stretchr/testify/assert"
 	"google.golang.org/grpc/codes"
@@ -13,6 +12,7 @@ import (
 	argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
 	"github.com/argoproj/argo-cd/pkg/apiclient/session"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 func TestCreateAndUseAccount(t *testing.T) {
diff --git a/test/e2e/app_autosync_test.go b/test/e2e/app_autosync_test.go
index 4e8588ec6..a6385ea5d 100644
--- a/test/e2e/app_autosync_test.go
+++ b/test/e2e/app_autosync_test.go
@@ -7,13 +7,13 @@ import (
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/stretchr/testify/assert"
 	"k8s.io/apimachinery/pkg/types"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 func TestAutoSyncSelfHealDisabled(t *testing.T) {
diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go
index 278e66b25..a6143b0e6 100644
--- a/test/e2e/app_management_test.go
+++ b/test/e2e/app_management_test.go
@@ -15,8 +15,6 @@ import (
 	"github.com/argoproj/gitops-engine/pkg/diff"
 	"github.com/argoproj/gitops-engine/pkg/health"
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/argoproj/pkg/errors"
 	log "github.com/sirupsen/logrus"
@@ -37,6 +35,8 @@ import (
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
 	. "github.com/argoproj/argo-cd/util/argo"
+	. "github.com/argoproj/argo-cd/util/errors"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/settings"
 )
 
diff --git a/test/e2e/cluster_test.go b/test/e2e/cluster_test.go
index a3475d56a..9c94d987e 100644
--- a/test/e2e/cluster_test.go
+++ b/test/e2e/cluster_test.go
@@ -6,9 +6,8 @@ import (
 
 	"github.com/stretchr/testify/assert"
 
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
-
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
+	. "github.com/argoproj/argo-cd/util/errors"
 )
 
 func TestClusterList(t *testing.T) {
diff --git a/test/e2e/custom_tool_test.go b/test/e2e/custom_tool_test.go
index 73005aecd..ba66eebd4 100644
--- a/test/e2e/custom_tool_test.go
+++ b/test/e2e/custom_tool_test.go
@@ -8,12 +8,12 @@ import (
 
 	"github.com/argoproj/gitops-engine/pkg/health"
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/stretchr/testify/assert"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	. "github.com/argoproj/argo-cd/util/errors"
 )
 
 // make sure we can echo back the Git creds
diff --git a/test/e2e/fixture/app/actions.go b/test/e2e/fixture/app/actions.go
index b52f06964..cd4f2d4b0 100644
--- a/test/e2e/fixture/app/actions.go
+++ b/test/e2e/fixture/app/actions.go
@@ -4,12 +4,12 @@ import (
 	"fmt"
 	"io/ioutil"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	log "github.com/sirupsen/logrus"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/grpc"
 )
 
diff --git a/test/e2e/fixture/app/consequences.go b/test/e2e/fixture/app/consequences.go
index 1c73e0659..1fecf4e4a 100644
--- a/test/e2e/fixture/app/consequences.go
+++ b/test/e2e/fixture/app/consequences.go
@@ -5,12 +5,12 @@ import (
 	"time"
 
 	"github.com/argoproj/gitops-engine/pkg/health"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	log "github.com/sirupsen/logrus"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 // this implements the "then" part of given/when/then
diff --git a/test/e2e/fixture/certs/certs.go b/test/e2e/fixture/certs/certs.go
index 20b5fff07..eff09a96b 100644
--- a/test/e2e/fixture/certs/certs.go
+++ b/test/e2e/fixture/certs/certs.go
@@ -5,9 +5,8 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 // Add a custom CA certificate to the test and also create the certificate file
diff --git a/test/e2e/fixture/fixture.go b/test/e2e/fixture/fixture.go
index 2e03f0566..ba11fd458 100644
--- a/test/e2e/fixture/fixture.go
+++ b/test/e2e/fixture/fixture.go
@@ -11,8 +11,6 @@ import (
 	"testing"
 	"time"
 
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/argoproj/pkg/errors"
 	jsonpatch "github.com/evanphx/json-patch"
 	"github.com/ghodss/yaml"
@@ -29,7 +27,9 @@ import (
 	sessionpkg "github.com/argoproj/argo-cd/pkg/apiclient/session"
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
+	. "github.com/argoproj/argo-cd/util/errors"
 	grpcutil "github.com/argoproj/argo-cd/util/grpc"
+	"github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/rand"
 	"github.com/argoproj/argo-cd/util/settings"
 )
diff --git a/test/e2e/fixture/gpgkeys/gpgkeys.go b/test/e2e/fixture/gpgkeys/gpgkeys.go
index 0d30e8131..968493d7b 100644
--- a/test/e2e/fixture/gpgkeys/gpgkeys.go
+++ b/test/e2e/fixture/gpgkeys/gpgkeys.go
@@ -6,9 +6,8 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 // Add GPG public key via API and create appropriate file where the ConfigMap mount would de it as well
diff --git a/test/e2e/fixture/repos/repos.go b/test/e2e/fixture/repos/repos.go
index eee84ae27..64d6d2220 100644
--- a/test/e2e/fixture/repos/repos.go
+++ b/test/e2e/fixture/repos/repos.go
@@ -3,9 +3,8 @@ package repos
 import (
 	"path/filepath"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
-
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 var (
diff --git a/test/e2e/fixture/tmpl.go b/test/e2e/fixture/tmpl.go
index bd418d8fa..c489ebb2e 100644
--- a/test/e2e/fixture/tmpl.go
+++ b/test/e2e/fixture/tmpl.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"text/template"
 
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
+	. "github.com/argoproj/argo-cd/util/errors"
 )
 
 // utility method to template a string using a map
diff --git a/test/e2e/fixture/versions.go b/test/e2e/fixture/versions.go
index be431d3eb..c76aef5fc 100644
--- a/test/e2e/fixture/versions.go
+++ b/test/e2e/fixture/versions.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 type Versions struct {
diff --git a/test/e2e/helm_test.go b/test/e2e/helm_test.go
index e0bf6410d..b3160894a 100644
--- a/test/e2e/helm_test.go
+++ b/test/e2e/helm_test.go
@@ -11,7 +11,6 @@ import (
 
 	"github.com/argoproj/gitops-engine/pkg/health"
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -22,6 +21,7 @@ import (
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
 	"github.com/argoproj/argo-cd/test/e2e/fixture/repos"
+	. "github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/settings"
 )
 
diff --git a/test/e2e/hook_test.go b/test/e2e/hook_test.go
index ec7f95bcb..177725534 100644
--- a/test/e2e/hook_test.go
+++ b/test/e2e/hook_test.go
@@ -10,11 +10,11 @@ import (
 
 	"github.com/argoproj/gitops-engine/pkg/health"
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	. "github.com/argoproj/argo-cd/util/errors"
 )
 
 func TestPreSyncHookSuccessful(t *testing.T) {
diff --git a/test/e2e/jsonnet_test.go b/test/e2e/jsonnet_test.go
index a01305a5c..6adf0df9f 100644
--- a/test/e2e/jsonnet_test.go
+++ b/test/e2e/jsonnet_test.go
@@ -4,13 +4,13 @@ import (
 	"testing"
 
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/argoproj/gitops-engine/pkg/utils/kube"
 	"github.com/stretchr/testify/assert"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	. "github.com/argoproj/argo-cd/util/errors"
 )
 
 func TestJsonnetAppliedCorrectly(t *testing.T) {
diff --git a/test/e2e/kustomize_test.go b/test/e2e/kustomize_test.go
index 480b932a1..7901fc337 100644
--- a/test/e2e/kustomize_test.go
+++ b/test/e2e/kustomize_test.go
@@ -5,12 +5,12 @@ import (
 
 	"github.com/argoproj/gitops-engine/pkg/health"
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/stretchr/testify/assert"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 func TestKustomize2AppSource(t *testing.T) {
diff --git a/test/e2e/repo_creds_test.go b/test/e2e/repo_creds_test.go
index eb24f18d5..35e458807 100644
--- a/test/e2e/repo_creds_test.go
+++ b/test/e2e/repo_creds_test.go
@@ -4,10 +4,9 @@ import (
 	"fmt"
 	"testing"
 
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
-
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	. "github.com/argoproj/argo-cd/util/errors"
 )
 
 // make sure you cannot create an app from a private repo without set-up
diff --git a/test/e2e/repo_management_test.go b/test/e2e/repo_management_test.go
index ad5a0fd95..1944ca94f 100644
--- a/test/e2e/repo_management_test.go
+++ b/test/e2e/repo_management_test.go
@@ -4,13 +4,13 @@ import (
 	"context"
 	"testing"
 
-	argoio "github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/stretchr/testify/assert"
 
 	repositorypkg "github.com/argoproj/argo-cd/pkg/apiclient/repository"
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
 	"github.com/argoproj/argo-cd/test/e2e/fixture/app"
 	"github.com/argoproj/argo-cd/test/e2e/fixture/repos"
+	argoio "github.com/argoproj/argo-cd/util/io"
 	"github.com/argoproj/argo-cd/util/settings"
 )
 
diff --git a/test/e2e/selective_sync_test.go b/test/e2e/selective_sync_test.go
index a8232b96c..b66171f76 100644
--- a/test/e2e/selective_sync_test.go
+++ b/test/e2e/selective_sync_test.go
@@ -7,12 +7,12 @@ import (
 
 	"github.com/argoproj/gitops-engine/pkg/health"
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	. "github.com/argoproj/gitops-engine/pkg/utils/errors"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	. "github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/rand"
 )
 
diff --git a/test/e2e/sync_options_test.go b/test/e2e/sync_options_test.go
index 231980211..2913db902 100644
--- a/test/e2e/sync_options_test.go
+++ b/test/e2e/sync_options_test.go
@@ -6,13 +6,13 @@ import (
 	"testing"
 
 	. "github.com/argoproj/gitops-engine/pkg/sync/common"
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 
 	. "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 	"github.com/argoproj/argo-cd/test/e2e/fixture"
 	. "github.com/argoproj/argo-cd/test/e2e/fixture/app"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 // TestSyncOptionsValidateFalse verifies we can disable validation during kubectl apply, using the
diff --git a/test/fixture/path/hack_path.go b/test/fixture/path/hack_path.go
index 22ac35c1f..9e83ce512 100644
--- a/test/fixture/path/hack_path.go
+++ b/test/fixture/path/hack_path.go
@@ -5,7 +5,7 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 type AddBinDirToPath struct {
diff --git a/test/fixture/revision_metadata/author.go b/test/fixture/revision_metadata/author.go
index 1f65b4de3..d1887a30b 100644
--- a/test/fixture/revision_metadata/author.go
+++ b/test/fixture/revision_metadata/author.go
@@ -6,7 +6,7 @@ import (
 
 	argoexec "github.com/argoproj/pkg/exec"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 var Author string
diff --git a/util/clusterauth/clusterauth_test.go b/util/clusterauth/clusterauth_test.go
index b7384d429..dce221fc7 100644
--- a/util/clusterauth/clusterauth_test.go
+++ b/util/clusterauth/clusterauth_test.go
@@ -5,7 +5,6 @@ import (
 	"io/ioutil"
 	"testing"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/ghodss/yaml"
 	"github.com/stretchr/testify/assert"
 	corev1 "k8s.io/api/core/v1"
@@ -14,6 +13,8 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/kubernetes/fake"
 	kubetesting "k8s.io/client-go/testing"
+
+	"github.com/argoproj/argo-cd/util/errors"
 )
 
 const (
diff --git a/util/env/env_test.go b/util/env/env_test.go
index 89acf98e4..bbd51b59c 100644
--- a/util/env/env_test.go
+++ b/util/env/env_test.go
@@ -5,7 +5,7 @@ import (
 	"os"
 	"testing"
 
-	util "github.com/argoproj/gitops-engine/pkg/utils/io"
+	util "github.com/argoproj/argo-cd/util/io"
 
 	"github.com/stretchr/testify/assert"
 )
diff --git a/util/helm/client_test.go b/util/helm/client_test.go
index aacb3f1aa..248df2487 100644
--- a/util/helm/client_test.go
+++ b/util/helm/client_test.go
@@ -5,8 +5,9 @@ import (
 	"testing"
 
 	"github.com/Masterminds/semver"
-	"github.com/argoproj/gitops-engine/pkg/utils/io"
 	"github.com/stretchr/testify/assert"
+
+	"github.com/argoproj/argo-cd/util/io"
 )
 
 func TestIndex(t *testing.T) {
diff --git a/util/session/sessionmanager_test.go b/util/session/sessionmanager_test.go
index 785a045c5..e4afa2a22 100644
--- a/util/session/sessionmanager_test.go
+++ b/util/session/sessionmanager_test.go
@@ -9,7 +9,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/argoproj/gitops-engine/pkg/utils/errors"
 	"github.com/dgrijalva/jwt-go"
 	"github.com/stretchr/testify/assert"
 	"google.golang.org/grpc/codes"
@@ -19,6 +18,7 @@ import (
 	"k8s.io/client-go/kubernetes/fake"
 
 	"github.com/argoproj/argo-cd/common"
+	"github.com/argoproj/argo-cd/util/errors"
 	"github.com/argoproj/argo-cd/util/password"
 	"github.com/argoproj/argo-cd/util/settings"
 )
diff --git a/util/settings/settings_test.go b/util/settings/settings_test.go
index 73aaa71b2..b8f6fe6df 100644
--- a/util/settings/settings_test.go
+++ b/util/settings/settings_test.go
@@ -7,7 +7,6 @@ import (
 	"github.com/argoproj/argo-cd/common"
 	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
 
-	"github.com/argoproj/gitops-engine/pkg/diff"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -260,7 +259,7 @@ func TestGetResourceCompareOptions(t *testing.T) {
 			"resource.compareoptions": "",
 		})
 		compareOptions, err := settingsManager.GetResourceCompareOptions()
-		defaultOptions := diff.GetDefaultDiffOptions()
+		defaultOptions := GetDefaultDiffOptions()
 		assert.NoError(t, err)
 		assert.Equal(t, defaultOptions.IgnoreAggregatedRoles, compareOptions.IgnoreAggregatedRoles)
 	}
@@ -269,7 +268,7 @@ func TestGetResourceCompareOptions(t *testing.T) {
 	{
 		_, settingsManager := fixtures(map[string]string{})
 		compareOptions, err := settingsManager.GetResourceCompareOptions()
-		defaultOptions := diff.GetDefaultDiffOptions()
+		defaultOptions := GetDefaultDiffOptions()
 		assert.NoError(t, err)
 		assert.Equal(t, defaultOptions.IgnoreAggregatedRoles, compareOptions.IgnoreAggregatedRoles)
 	}