Repository: argoproj/argo-cd
Pull request #11247 (2022-11-09 21:00:36)

fix: hide app namespace on the ui
Fixes https://github.com/argoproj/argo-cd/issues/11111
Note on DCO:

If the DCO action in the integration test fails, one or more of your commits are not signed off. Please click on the *Details* link next to the DCO action for instructions on how to resolve this.

Checklist:

* [ ] 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.
* [ ] The title of the PR states what changed and the related issues number (used for the release note).
* [ ] I've included "Closes [ISSUE #]" or "Fixes [ISSUE #]" in the description to automatically close the associated issue.
* [ ] 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.
* [ ] I have signed off all my commits as required by [DCO](https://github.com/argoproj/argoproj/tree/master/community#contributing-to-argo)
* [ ] I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged.
* [ ] My build is green ([troubleshooting builds](https://argo-cd.readthedocs.io/en/latest/developer-guide/ci/)). 



codecov[bot]: # [Codecov](https://codecov.io/gh/argoproj/argo-cd/pull/11247?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj) Report
Base: **45.64**% // Head: **45.64**% // Increases project coverage by **`+0.00%`** :tada:
> Coverage data is based on head [(`5b251d7`)](https://codecov.io/gh/argoproj/argo-cd/pull/11247?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj) compared to base [(`4cf807e`)](https://codecov.io/gh/argoproj/argo-cd/commit/4cf807e67a6d40928501360fe69b5e0dc60683bb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj).
> Patch coverage: 100.00% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master   #11247   +/-   ##
=======================================
  Coverage   45.64%   45.64%           
=======================================
  Files         239      239           
  Lines       28991    28992    +1     
=======================================
+ Hits        13233    13234    +1     
  Misses      13939    13939           
  Partials     1819     1819           
```


| [Impacted Files](https://codecov.io/gh/argoproj/argo-cd/pull/11247?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj) | Coverage Δ | |
|---|---|---|
| [util/settings/settings.go](https://codecov.io/gh/argoproj/argo-cd/pull/11247/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj#diff-dXRpbC9zZXR0aW5ncy9zZXR0aW5ncy5nbw==) | `51.25% <ø> (ø)` | |
| [server/server.go](https://codecov.io/gh/argoproj/argo-cd/pull/11247/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj#diff-c2VydmVyL3NlcnZlci5nbw==) | `52.99% <100.00%> (+0.07%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/argoproj/argo-cd/pull/11247?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj).

alexef: superseeds: https://github.com/argoproj/argo-cd/pull/11165
ashutosh16: @crenshaw-dev  @alexef  Can you review the PR?
alexef: @ashutosh16 please fix lint https://github.com/argoproj/argo-cd/actions/runs/3447734925/jobs/5754058103
ashutosh16: @crenshaw-dev  Can we merge the PR?

Patch:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..a159b9930
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,13 @@
+version: 2
+updates:
+  - package-ecosystem: "gomod"
+    directory: "/"
+    schedule:
+      interval: "daily"
+    ignore:
+    - dependency-name: k8s.io/*
+
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "daily"
diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml
index 397c98d72..9e9827750 100644
--- a/.github/workflows/ci-build.yaml
+++ b/.github/workflows/ci-build.yaml
@@ -51,7 +51,7 @@ jobs:
         with:
           go-version: ${{ env.GOLANG_VERSION }}
       - name: Restore go build cache
-        uses: actions/cache@v1
+        uses: actions/cache@v3
         with:
           path: ~/.cache/go-build
           key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -116,7 +116,7 @@ jobs:
         run: |
           echo "/usr/local/bin" >> $GITHUB_PATH
       - name: Restore go build cache
-        uses: actions/cache@v1
+        uses: actions/cache@v3
         with:
           path: ~/.cache/go-build
           key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -133,12 +133,12 @@ jobs:
       - name: Run all unit tests
         run: make test-local
       - name: Generate code coverage artifacts
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: code-coverage
           path: coverage.out
       - name: Generate test results artifacts
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: test-results
           path: test-results/
@@ -179,7 +179,7 @@ jobs:
         run: |
           echo "/usr/local/bin" >> $GITHUB_PATH
       - name: Restore go build cache
-        uses: actions/cache@v1
+        uses: actions/cache@v3
         with:
           path: ~/.cache/go-build
           key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -196,7 +196,7 @@ jobs:
       - name: Run all unit tests
         run: make test-race-local
       - name: Generate test results artifacts
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: race-results
           path: test-results/
@@ -252,12 +252,12 @@ jobs:
       - name: Checkout code
         uses: actions/checkout@v3
       - name: Setup NodeJS
-        uses: actions/setup-node@v1
+        uses: actions/setup-node@v3
         with:
           node-version: '12.18.4'
       - name: Restore node dependency cache
         id: cache-dependencies
-        uses: actions/cache@v1
+        uses: actions/cache@v3
         with:
           path: ui/node_modules
           key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
@@ -292,7 +292,7 @@ jobs:
           fetch-depth: 0
       - name: Restore node dependency cache
         id: cache-dependencies
-        uses: actions/cache@v1
+        uses: actions/cache@v3
         with:
           path: ui/node_modules
           key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
@@ -303,16 +303,16 @@ jobs:
         run: |
           mkdir -p test-results
       - name: Get code coverage artifiact
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
           name: code-coverage
       - name: Get test result artifact
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
           name: test-results
           path: test-results
       - name: Upload code coverage information to codecov.io
-        uses: codecov/codecov-action@v1
+        uses: codecov/codecov-action@v3
         with:
           file: coverage.out
       - name: Perform static code analysis using SonarCloud
@@ -386,7 +386,7 @@ jobs:
           sudo chown runner $HOME/.kube/config
           kubectl version
       - name: Restore go build cache
-        uses: actions/cache@v1
+        uses: actions/cache@v3
         with:
           path: ~/.cache/go-build
           key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -442,7 +442,7 @@ jobs:
           set -x
           make test-e2e-local
       - name: Upload e2e-server logs
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: e2e-server-k8s${{ matrix.k3s-version }}.log
           path: /tmp/e2e-server.log
diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml
index d1eab22e8..d254d1eb4 100644
--- a/.github/workflows/image.yaml
+++ b/.github/workflows/image.yaml
@@ -23,6 +23,7 @@ jobs:
   publish:
     permissions:
       contents: write  # for git to push upgrade commit if not already deployed
+      packages: write  # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags
     if: github.repository == 'argoproj/argo-cd'
     runs-on: ubuntu-22.04
     env:
@@ -42,12 +43,12 @@ jobs:
 
       # login
       - run: |
-          docker login ghcr.io --username $USERNAME --password $PASSWORD
-          docker login quay.io --username "${DOCKER_USERNAME}" --password "${DOCKER_TOKEN}"
+          docker login ghcr.io --username $USERNAME --password-stdin <<< "$PASSWORD"
+          docker login quay.io --username "$DOCKER_USERNAME" --password-stdin <<< "$DOCKER_TOKEN"
         if: github.event_name == 'push'
         env:
-          USERNAME: ${{ secrets.USERNAME }}
-          PASSWORD: ${{ secrets.TOKEN }}
+          USERNAME: ${{ github.actor }}
+          PASSWORD: ${{ secrets.GITHUB_TOKEN }}
           DOCKER_USERNAME: ${{ secrets.RELEASE_QUAY_USERNAME }}
           DOCKER_TOKEN: ${{ secrets.RELEASE_QUAY_TOKEN }}
 
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 18bf2c347..e61ce7fec 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -195,9 +195,9 @@ jobs:
           QUAY_TOKEN: ${{ secrets.RELEASE_QUAY_TOKEN }}
         run: |
           set -ue
-          docker login quay.io --username "${QUAY_USERNAME}" --password "${QUAY_TOKEN}"
+          docker login quay.io --username "${QUAY_USERNAME}" --password-stdin <<< "${QUAY_TOKEN}"
           # Remove the following when Docker Hub is gone
-          docker login --username "${DOCKER_USERNAME}" --password "${DOCKER_TOKEN}"
+          docker login --username "${DOCKER_USERNAME}" --password-stdin <<< "${DOCKER_TOKEN}"
         if: ${{ env.DRY_RUN != 'true' }}
 
       - uses: docker/setup-qemu-action@v2
diff --git a/USERS.md b/USERS.md
index a5a1700de..f11049161 100644
--- a/USERS.md
+++ b/USERS.md
@@ -37,6 +37,7 @@ Currently, the following organizations are **officially** using Argo CD:
 1. [Camptocamp](https://camptocamp.com)
 1. [Capital One](https://www.capitalone.com)
 1. [CARFAX](https://www.carfax.com)
+1. [CARFAX Europe](https://www.carfax.eu)
 1. [Casavo](https://casavo.com)
 1. [Celonis](https://www.celonis.com/)
 1. [CERN](https://home.cern/)
@@ -58,6 +59,7 @@ Currently, the following organizations are **officially** using Argo CD:
 1. [Deutsche Telekom AG](https://telekom.com)
 1. [Devopsi - Poland Software/DevOps Consulting](https://devopsi.pl/)
 1. [Devtron Labs](https://github.com/devtron-labs/devtron)
+1. [Divistant](https://divistant.com)
 1. [EDF Renewables](https://www.edf-re.com/)
 1. [edX](https://edx.org)
 1. [Elastic](https://elastic.co/)
@@ -78,7 +80,7 @@ Currently, the following organizations are **officially** using Argo CD:
 1. [G DATA CyberDefense AG](https://www.gdata-software.com/)
 1. [Garner](https://www.garnercorp.com)
 1. [Generali Deutschland AG](https://www.generali.de/)
-2. [Gepardec](https://gepardec.com/)
+1. [Gepardec](https://gepardec.com/)
 1. [Gitpod](https://www.gitpod.io)
 1. [Gllue](https://gllue.com)
 1. [gloat](https://gloat.com/)
@@ -119,6 +121,7 @@ Currently, the following organizations are **officially** using Argo CD:
 1. [Kurly](https://www.kurly.com/)
 1. [LexisNexis](https://www.lexisnexis.com/)
 1. [Lian Chu Securities](https://lczq.com)
+1. [Liatrio](https://www.liatrio.com)
 1. [Lightricks](https://www.lightricks.com/)
 1. [LINE](https://linecorp.com/en/)
 1. [Lytt](https://www.lytt.co/)
@@ -167,6 +170,7 @@ Currently, the following organizations are **officially** using Argo CD:
 1. [Pipefy](https://www.pipefy.com/)
 1. [Pismo](https://pismo.io/)
 1. [Polarpoint.io](https://polarpoint.io)
+1. [PostFinance](https://github.com/postfinance)
 1. [Preferred Networks](https://preferred.jp/en/)
 1. [Productboard](https://www.productboard.com/)
 1. [Prudential](https://prudential.com.sg)
@@ -238,6 +242,7 @@ Currently, the following organizations are **officially** using Argo CD:
 1. [WeMo Scooter](https://www.wemoscooter.com/)
 1. [Whitehat Berlin](https://whitehat.berlin) by Guido Maria Serra +Fenaroli
 1. [Witick](https://witick.io/)
+1. [Wolffun Game](https://www.wolffungame.com/)
 1. [WooliesX](https://wooliesx.com.au/)
 1. [Woolworths Group](https://www.woolworthsgroup.com.au/)
 1. [WSpot](https://www.wspot.com.br/)
diff --git a/assets/swagger.json b/assets/swagger.json
index 4046f8360..517b2a6f9 100644
--- a/assets/swagger.json
+++ b/assets/swagger.json
@@ -4097,6 +4097,9 @@
         "appLabelKey": {
           "type": "string"
         },
+        "appsInAnyNamespaceEnabled": {
+          "type": "boolean"
+        },
         "configManagementPlugins": {
           "type": "array",
           "items": {
diff --git a/cmd/argocd/commands/admin/notifications.go b/cmd/argocd/commands/admin/notifications.go
index 714e13e0e..990df8739 100644
--- a/cmd/argocd/commands/admin/notifications.go
+++ b/cmd/argocd/commands/admin/notifications.go
@@ -33,7 +33,7 @@ func NewNotificationsCommand() *cobra.Command {
 	var argocdService service.Service
 	toolsCommand := cmd.NewToolsCommand(
 		"notifications",
-		"notifications",
+		"argocd admin notifications",
 		applications,
 		settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), func(clientConfig clientcmd.ClientConfig) {
 			k8sCfg, err := clientConfig.ClientConfig()
diff --git a/controller/appcontroller.go b/controller/appcontroller.go
index 400e314ec..89353d755 100644
--- a/controller/appcontroller.go
+++ b/controller/appcontroller.go
@@ -1497,17 +1497,7 @@ func (ctrl *ApplicationController) refreshAppConditions(app *appv1.Application)
 	errorConditions := make([]appv1.ApplicationCondition, 0)
 	proj, err := ctrl.getAppProj(app)
 	if err != nil {
-		if apierr.IsNotFound(err) {
-			errorConditions = append(errorConditions, appv1.ApplicationCondition{
-				Type:    appv1.ApplicationConditionInvalidSpecError,
-				Message: fmt.Sprintf("Application referencing project %s which does not exist", app.Spec.Project),
-			})
-		} else {
-			errorConditions = append(errorConditions, appv1.ApplicationCondition{
-				Type:    appv1.ApplicationConditionUnknownError,
-				Message: err.Error(),
-			})
-		}
+		errorConditions = append(errorConditions, ctrl.projectErrorToCondition(err, app))
 	} else {
 		specConditions, err := argo.ValidatePermissions(context.Background(), &app.Spec, proj, ctrl.db)
 		if err != nil {
@@ -1798,7 +1788,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar
 					// If the application is not allowed to use the project,
 					// log an error.
 					if _, err := ctrl.getAppProj(app); err != nil {
-						ctrl.setAppCondition(app, appv1.ApplicationCondition{Type: appv1.ApplicationConditionUnknownError, Message: err.Error()})
+						ctrl.setAppCondition(app, ctrl.projectErrorToCondition(err, app))
 					}
 				}
 
@@ -1869,6 +1859,19 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar
 	return informer, lister
 }
 
+func (ctrl *ApplicationController) projectErrorToCondition(err error, app *appv1.Application) appv1.ApplicationCondition {
+	var condition appv1.ApplicationCondition
+	if apierr.IsNotFound(err) {
+		condition = appv1.ApplicationCondition{
+			Type:    appv1.ApplicationConditionInvalidSpecError,
+			Message: fmt.Sprintf("Application referencing project %s which does not exist", app.Spec.Project),
+		}
+	} else {
+		condition = appv1.ApplicationCondition{Type: appv1.ApplicationConditionUnknownError, Message: err.Error()}
+	}
+	return condition
+}
+
 func (ctrl *ApplicationController) RegisterClusterSecretUpdater(ctx context.Context) {
 	updater := NewClusterInfoUpdater(ctrl.stateCache, ctrl.db, ctrl.appLister.Applications(""), ctrl.cache, ctrl.clusterFilter, ctrl.getAppProj, ctrl.namespace)
 	go updater.Run(ctx)
diff --git a/controller/cache/cache.go b/controller/cache/cache.go
index f3c618ead..c0a798b43 100644
--- a/controller/cache/cache.go
+++ b/controller/cache/cache.go
@@ -389,6 +389,11 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
 		return nil, fmt.Errorf("controller is configured to ignore cluster %s", cluster.Server)
 	}
 
+	resourceCustomLabels, err := c.settingsMgr.GetResourceCustomLabels()
+	if err != nil {
+		return nil, fmt.Errorf("error getting custom label: %w", err)
+	}
+
 	clusterCacheOpts := []clustercache.UpdateSettingsFunc{
 		clustercache.SetListSemaphore(semaphore.NewWeighted(clusterCacheListSemaphoreSize)),
 		clustercache.SetListPageSize(clusterCacheListPageSize),
@@ -400,7 +405,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
 		clustercache.SetClusterResources(cluster.ClusterResources),
 		clustercache.SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (interface{}, bool) {
 			res := &ResourceInfo{}
-			populateNodeInfo(un, res)
+			populateNodeInfo(un, res, resourceCustomLabels)
 			c.lock.RLock()
 			cacheSettings := c.cacheSettings
 			c.lock.RUnlock()
diff --git a/controller/cache/info.go b/controller/cache/info.go
index a6e5e419a..3cc7980ad 100644
--- a/controller/cache/info.go
+++ b/controller/cache/info.go
@@ -19,12 +19,21 @@ import (
 	"github.com/argoproj/argo-cd/v2/util/resource"
 )
 
-func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo) {
+func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLabels []string) {
 	gvk := un.GroupVersionKind()
 	revision := resource.GetRevision(un)
 	if revision > 0 {
 		res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Revision", Value: fmt.Sprintf("Rev:%v", revision)})
 	}
+	if len(customLabels) > 0 {
+		if labels := un.GetLabels(); labels != nil {
+			for _, customLabel := range customLabels {
+				if value, ok := labels[customLabel]; ok {
+					res.Info = append(res.Info, v1alpha1.InfoItem{Name: customLabel, Value: value})
+				}
+			}
+		}
+	}
 	switch gvk.Group {
 	case "":
 		switch gvk.Kind {
diff --git a/docs/developer-guide/code-contributions.md b/docs/developer-guide/code-contributions.md
index 39110c44b..b57d9df6d 100644
--- a/docs/developer-guide/code-contributions.md
+++ b/docs/developer-guide/code-contributions.md
@@ -103,7 +103,7 @@ Design documents are usually submitted as PR and use [this template](https://git
 
 Our community regularly meets virtually to discuss issues, ideas and enhancements around Argo CD. We do invite you to join this virtual meetings if you want to bring up certain things (including your enhancement proposals), participate in our triaging or just want to get to know other contributors.
 
-The current cadence of our meetings is weekly, every Thursday at 4pm UTC (9am Pacific, 12pm Eastern, 6pm Central European, 9:30pm Indian). We use Zoom to conduct these meetings.
+The current cadence of our meetings is weekly, every Thursday at 4:15pm UTC (8:15am Pacific, 11:15am Eastern, 5:15pm Central European, 9:45pm Indian). We use Zoom to conduct these meetings.
 
 * [Agenda document (Google Docs, includes Zoom link)](https://docs.google.com/document/d/1xkoFkVviB70YBzSEa4bDnu-rUZ1sIFtwKKG1Uw8XsY8)
 
diff --git a/docs/operator-manual/argocd-cm.yaml b/docs/operator-manual/argocd-cm.yaml
index 7728cc9bd..5715f3a5d 100644
--- a/docs/operator-manual/argocd-cm.yaml
+++ b/docs/operator-manual/argocd-cm.yaml
@@ -190,6 +190,9 @@ data:
       clusters:
       - "*.local"
 
+  # An optional comma-separated list of metadata.labels to observe in the UI.
+  resource.customLabels: tier
+
   resource.compareoptions: |
     # if ignoreAggregatedRoles set to true then differences caused by aggregated roles in RBAC resources are ignored.
     ignoreAggregatedRoles: true
diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md
index e2ac17f6d..baa96fa60 100644
--- a/docs/operator-manual/declarative-setup.md
+++ b/docs/operator-manual/declarative-setup.md
@@ -682,6 +682,10 @@ Notes:
 * Invalid globs result in the whole rule being ignored.
 * If you add a rule that matches existing resources, these will appear in the interface as `OutOfSync`.
 
+## Resource Custom Labels
+
+Custom Labels configured with `resource.customLabels` (comma separated string) will be displayed in the UI (for any resource that defines them).
+
 ## SSO & RBAC
 
 * SSO configuration details: [SSO](./user-management/index.md)
diff --git a/docs/operator-manual/notifications/troubleshooting-commands.md b/docs/operator-manual/notifications/troubleshooting-commands.md
index a57af022b..633eb47d7 100644
--- a/docs/operator-manual/notifications/troubleshooting-commands.md
+++ b/docs/operator-manual/notifications/troubleshooting-commands.md
@@ -1,9 +1,9 @@
-## notifications template get
+## argocd admin notifications template get
 
 Prints information about configured templates
 
 ```
-notifications template get [flags]
+argocd admin notifications template get [flags]
 ```
 
 ### Examples
@@ -11,9 +11,9 @@ notifications template get [flags]
 ```
 
 # prints all templates
-notifications template get
+argocd admin notifications template get
 # print YAML formatted app-sync-succeeded template definition
-notifications template get app-sync-succeeded -o=yaml
+argocd admin notifications template get app-sync-succeeded -o=yaml
 
 ```
 
@@ -53,12 +53,12 @@ notifications template get app-sync-succeeded -o=yaml
       --username string                 Username for basic authentication to the API server
 ```
 
-## notifications template notify
+## argocd admin notifications template notify
 
 Generates notification using the specified template and send it to specified recipients
 
 ```
-notifications template notify NAME RESOURCE_NAME [flags]
+argocd admin notifications template notify NAME RESOURCE_NAME [flags]
 ```
 
 ### Examples
@@ -66,10 +66,10 @@ notifications template notify NAME RESOURCE_NAME [flags]
 ```
 
 # Trigger notification using in-cluster config map and secret
-notifications template notify app-sync-succeeded guestbook --recipient slack:my-slack-channel
+argocd admin notifications template notify app-sync-succeeded guestbook --recipient slack:my-slack-channel
 
 # Render notification render generated notification in console
-notifications template notify app-sync-succeeded guestbook
+argocd admin notifications template notify app-sync-succeeded guestbook
 
 ```
 
@@ -109,12 +109,12 @@ notifications template notify app-sync-succeeded guestbook
       --username string                 Username for basic authentication to the API server
 ```
 
-## notifications trigger get
+## argocd admin notifications trigger get
 
 Prints information about configured triggers
 
 ```
-notifications trigger get [flags]
+argocd admin notifications trigger get [flags]
 ```
 
 ### Examples
@@ -122,9 +122,9 @@ notifications trigger get [flags]
 ```
 
 # prints all triggers
-notifications trigger get
+argocd admin notifications trigger get
 # print YAML formatted on-sync-failed trigger definition
-notifications trigger get on-sync-failed -o=yaml
+argocd admin notifications trigger get on-sync-failed -o=yaml
 
 ```
 
@@ -164,12 +164,12 @@ notifications trigger get on-sync-failed -o=yaml
       --username string                 Username for basic authentication to the API server
 ```
 
-## notifications trigger run
+## argocd admin notifications trigger run
 
 Evaluates specified trigger condition and prints the result
 
 ```
-notifications trigger run NAME RESOURCE_NAME [flags]
+argocd admin notifications trigger run NAME RESOURCE_NAME [flags]
 ```
 
 ### Examples
@@ -177,10 +177,10 @@ notifications trigger run NAME RESOURCE_NAME [flags]
 ```
 
 # Execute trigger configured in 'argocd-notification-cm' ConfigMap
-notifications trigger run on-sync-status-unknown ./sample-app.yaml
+argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml
 
 # Execute trigger using my-config-map.yaml instead of 'argocd-notifications-cm' ConfigMap
-notifications trigger run on-sync-status-unknown ./sample-app.yaml \
+argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml \
     --config-map ./my-config-map.yaml
 ```
 
diff --git a/docs/operator-manual/notifications/troubleshooting.md b/docs/operator-manual/notifications/troubleshooting.md
index 660fa53d6..68ea134e0 100644
--- a/docs/operator-manual/notifications/troubleshooting.md
+++ b/docs/operator-manual/notifications/troubleshooting.md
@@ -1,6 +1,6 @@
 ## Troubleshooting
 
-The `argocd-notifications` binary includes a set of CLI commands that helps to configure the controller
+The `argocd admin notifications` is a CLI command group that helps to configure the controller
 settings and troubleshoot issues.
 
 ## Global flags
@@ -17,15 +17,15 @@ Additionally, you can specify `:empty` value to use empty secret with no notific
 * Get list of triggers configured in the local config map:
 
 ```bash
-argocd-notifications trigger get \
-  --config-map ./argocd-notifications-cm.yaml --secret :empty
+argocd admin notifications trigger get \
+  --config-map ./argocd admin notifications-cm.yaml --secret :empty
 ```
 
 * Trigger notification using in-cluster config map and secret:
 
 ```bash
-argocd-notifications template notify \
-  app-sync-succeeded guestbook --recipient slack:argocd-notifications
+argocd admin notifications template notify \
+  app-sync-succeeded guestbook --recipient slack:argocd admin notifications
 ```
 
 ## Kustomize
@@ -44,18 +44,18 @@ kustomize build ./argocd-notifications | \
 
 ### On your laptop
 
-You can download `argocd-notifications` from the github [release](https://github.com/argoproj-labs/argocd-notifications/releases)
+You can download the `argocd` CLI from the github [release](https://github.com/argoproj/argo-cd/releases)
 attachments.
 
-The binary is available in `argoprojlabs/argocd-notifications` image. Use the `docker run` and volume mount
+The binary is available in `argoproj/argo-cd` image. Use the `docker run` and volume mount
 to execute binary on any platform. 
 
 **Example:**
 
 ```bash
 docker run --rm -it -w /src -v $(pwd):/src \
-  argoprojlabs/argocd-notifications:<version> \
-  /app/argocd-notifications trigger get \
+  argoproj/argo-cd:<version> \
+  /app/argocd admin notifications trigger get \
   --config-map ./argocd-notifications-cm.yaml --secret :empty
 ```
 
@@ -67,7 +67,7 @@ configuration.
 **Example**
 ```bash
 kubectl exec -it argocd-notifications-controller-<pod-hash> \
-  /app/argocd-notifications trigger get
+  /app/argocd admin notifications trigger get
 ```
 
 ## Commands
diff --git a/docs/proposals/deep-links.md b/docs/proposals/deep-links.md
new file mode 100644
index 000000000..6f1f13f04
--- /dev/null
+++ b/docs/proposals/deep-links.md
@@ -0,0 +1,133 @@
+---
+title: Deep Links
+
+authors:
+- "@gdsoumya"
+- "@alexmt"
+
+sponsors:
+- TBD
+
+reviewers:
+- TBD
+
+approvers:
+- TBD
+
+creation-date: 2022-08-01
+
+---
+
+# Deep Links
+
+Deep links allow end users to quickly redirect to third-party systems such as Splunk, DataDog etc. from the Argo CD
+user interface.
+
+
+## Summary
+
+Argo CD administrator will be able to configure links that redirect users to third-party systems such as Splunk,
+DataDog etc. The template should be able to reference different types of resources relating to where the links show up,
+this includes projects, applications, or individual resources(pods, services etc.) that are part of the application.
+
+Deep Link is a generic integration solution for third-party systems which enables users to integrate any system -  not
+only popular solutions but also custom/private systems that can leverage the data available in Argo CD.
+
+## Motivation
+
+Argo CD UI with deep links to third-party integrations will provide a unified solution for users making it easier for
+them to switch between relevant systems without having to separately navigate and correlate the information.
+
+
+## Proposal
+
+The configuration for Deep Links will be present in the `argocd-cm`, we will add new `<location>.links` fields in the
+cm to list all the deep links that will be displayed in the provided location. The possible values for `<location>`
+currently are :
+- `project` : all links under this field will show up in the project tab in the Argo CD UI.
+- `application` : all links under this field will show up in the application summary tab.
+- `resource` : all links under this field will show up in the individual resource(deployments, pods, services etc.)
+  summary tab.
+
+Each link in the list has five subfields :
+1. `title` : title/tag that will be displayed in the UI corresponding to that link
+2. `url` : the actual URL where the deep link will redirect to, this field can be templated to use data from the
+   application, project or resource objects (depending on where it is located)
+3. `description` (optional) : a description for what the deep link is about
+4. `icon.class` (optional) : a font-awesome icon class to be used when displaying the links in dropdown menus.
+5. `if` (optional) : a conditional statement that results in either `true` or `false`, it also has access to the same
+   data as the `url` field. If the condition resolves to `true` the deep link will be displayed else it will be hidden. If
+   the field is omitted by default the deep links will be displayed.
+
+
+An example `argocd-cm.yaml` file with deep links and its variations :
+
+```yaml
+data:
+  # project level links
+  project.links: |
+    - url: https://myaudit-system.com?project={{proj.metadata.name}}
+      title: Audit
+  # application level links
+  application.links: |
+    - url: https://mycompany.splunk.com?search={{app.spec.destination.namespace}}
+      title: Splunk
+    # conditionally show link e.g. for specific project
+    - url: https://mycompany.splunk.com?search={{app.spec.destination.namespace}}
+      title: Splunk
+      if: app.spec.proj == "abc"
+    - url: https://{{project.metadata.annotations.splunkhost}}?search={{app.spec.destination.namespace}}
+      title: Splunk
+      if: project.metadata.annotations.splunkhost
+    
+  # resource level links
+  resource.links: |
+    - url: https://mycompany.splunk.com?search={{res.metadata.namespace}}
+      title: Splunk
+      if: res.kind == "Pod" || res.kind == "Deployment"
+
+```
+
+The argocd server will expose new APIs for rendering deep links in the UI, the server will handle the templating and
+conditional rendering logic and will provide the UI with the final list of links that need to be displayed for a
+particular location/resource.
+
+The following API methods are proposed:
+
+```protobuf
+message LinkInfo {
+  required string name = 1;
+  required string url = 2;
+  optional string description = 3;
+  optional string iconClass = 4;
+}
+
+message LinksResponse {
+  repeated LinkInfo items = 1;
+}
+
+service ApplicationService {
+  rpc ListLinks(google.protobuf.Empty) returns (LinksResponse) {
+    option (google.api.http).get = "/api/v1/applications/{name}/links";
+  }
+
+  rpc ListResourceLinks(ApplicationResourceRequest) returns (LinksResponse) {
+    option (google.api.http).get = "/api/v1/applications/{name}/resource/links";
+  }
+}
+
+service ProjectService {
+  
+  rpc ListLinks(google.protobuf.Empty) returns (LinksResponse) {
+    option (google.api.http).get = "/api/v1/projects/{name}/links";
+  }
+}
+```
+
+### Use cases
+
+Some example use cases this enhancement intends to take care of -
+
+#### Use case 1:
+As a user, I would like to quickly open a splunk/datadog UI with a query that retrieves all logs of application
+namespace or metrics for specific applications etc.
diff --git a/docs/user-guide/commands/argocd_admin.md b/docs/user-guide/commands/argocd_admin.md
index a6d28e084..aff92561b 100644
--- a/docs/user-guide/commands/argocd_admin.md
+++ b/docs/user-guide/commands/argocd_admin.md
@@ -9,7 +9,9 @@ argocd admin [flags]
 ### Options
 
 ```
-  -h, --help   help for admin
+  -h, --help               help for admin
+      --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")
 ```
 
 ### Options inherited from parent commands
@@ -26,8 +28,6 @@ argocd admin [flags]
       --http-retry-max int              Maximum number of retries to establish http connection to Argo CD server
       --insecure                        Skip server certificate and domain verification
       --kube-context string             Directs the command to the given kube-context
-      --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
diff --git a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md
index 5d70f8bab..37aacbdfc 100644
--- a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md
+++ b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md
@@ -28,6 +28,7 @@ argocd admin app get-reconcile-results PATH [flags]
       --refresh                        If set to true then recalculates apps reconciliation
       --repo-server string             Repo server address.
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -53,7 +54,6 @@ argocd admin app get-reconcile-results PATH [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md
index 7b3798ac1..f1a8455af 100644
--- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md
+++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md
@@ -24,6 +24,7 @@ argocd admin cluster kubeconfig CLUSTER_URL OUTPUT_PATH [flags]
       --password string                Password for basic authentication to the API server
       --proxy-url string               If provided, this URL will be used to connect via proxy
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -49,7 +50,6 @@ argocd admin cluster kubeconfig CLUSTER_URL OUTPUT_PATH [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md
index 9fe9e4f9b..f302f14ff 100644
--- a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md
+++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md
@@ -24,6 +24,7 @@ argocd admin cluster namespaces [flags]
       --password string                Password for basic authentication to the API server
       --proxy-url string               If provided, this URL will be used to connect via proxy
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -49,7 +50,6 @@ argocd admin cluster namespaces [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md
index 8af26d31c..17b66a06d 100644
--- a/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md
+++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md
@@ -9,49 +9,49 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags]
 ### Options
 
 ```
-      --dry-run   Print what will be performed (default true)
-  -h, --help      help for disable-namespaced-mode
+      --as string                      Username to impersonate for the operation
+      --as-group stringArray           Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
+      --as-uid string                  UID to impersonate for the operation
+      --certificate-authority string   Path to a cert file for the certificate authority
+      --client-certificate string      Path to a client certificate file for TLS
+      --client-key string              Path to a client key file for TLS
+      --cluster string                 The name of the kubeconfig cluster to use
+      --context string                 The name of the kubeconfig context to use
+      --dry-run                        Print what will be performed (default true)
+  -h, --help                           help for disable-namespaced-mode
+      --insecure-skip-tls-verify       If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
+      --kubeconfig string              Path to a kube config. Only required if out-of-cluster
+  -n, --namespace string               If present, the namespace scope for this CLI request
+      --password string                Password for basic authentication to the API server
+      --proxy-url string               If provided, this URL will be used to connect via proxy
+      --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
+      --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
+      --token string                   Bearer token for authentication to the API server
+      --user string                    The name of the kubeconfig user to use
+      --username string                Username for basic authentication to the API server
 ```
 
 ### Options inherited from parent commands
 
 ```
-      --as string                       Username to impersonate for the operation
-      --as-group stringArray            Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
-      --as-uid string                   UID to impersonate for the operation
       --auth-token string               Authentication token
-      --certificate-authority string    Path to a cert file for the certificate authority
-      --client-certificate string       Path to a client certificate file for TLS
       --client-crt string               Client certificate file
       --client-crt-key string           Client certificate key file
-      --client-key string               Path to a client key file for TLS
-      --cluster string                  The name of the kubeconfig cluster to use
       --config string                   Path to Argo CD config (default "/home/user/.config/argocd/config")
-      --context string                  The name of the kubeconfig context to use
       --core                            If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server
       --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)
       --http-retry-max int              Maximum number of retries to establish http connection to Argo CD server
       --insecure                        Skip server certificate and domain verification
-      --insecure-skip-tls-verify        If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
       --kube-context string             Directs the command to the given kube-context
-      --kubeconfig string               Path to a kube config. Only required if out-of-cluster
       --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")
-  -n, --namespace string                If present, the namespace scope for this CLI request
-      --password string                 Password for basic authentication to the API server
       --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
-      --proxy-url string                If provided, this URL will be used to connect via proxy
-      --request-timeout string          The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-      --server string                   The address and port of the Kubernetes API server
       --server-crt string               Server certificate file
-      --tls-server-name string          If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
-      --token string                    Bearer token for authentication to the API server
-      --user string                     The name of the kubeconfig user to use
-      --username string                 Username for basic authentication to the API server
 ```
 
 ### SEE ALSO
diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md
index 41b4d0546..b4a3f63c0 100644
--- a/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md
+++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md
@@ -9,51 +9,51 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags]
 ### Options
 
 ```
-      --cluster-resources         Indicates if cluster level resources should be managed.
-      --dry-run                   Print what will be performed (default true)
-  -h, --help                      help for enable-namespaced-mode
-      --max-namespace-count int   Max number of namespaces that cluster should managed managed namespaces is less or equal to specified count
+      --as string                      Username to impersonate for the operation
+      --as-group stringArray           Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
+      --as-uid string                  UID to impersonate for the operation
+      --certificate-authority string   Path to a cert file for the certificate authority
+      --client-certificate string      Path to a client certificate file for TLS
+      --client-key string              Path to a client key file for TLS
+      --cluster string                 The name of the kubeconfig cluster to use
+      --cluster-resources              Indicates if cluster level resources should be managed.
+      --context string                 The name of the kubeconfig context to use
+      --dry-run                        Print what will be performed (default true)
+  -h, --help                           help for enable-namespaced-mode
+      --insecure-skip-tls-verify       If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
+      --kubeconfig string              Path to a kube config. Only required if out-of-cluster
+      --max-namespace-count int        Max number of namespaces that cluster should managed managed namespaces is less or equal to specified count
+  -n, --namespace string               If present, the namespace scope for this CLI request
+      --password string                Password for basic authentication to the API server
+      --proxy-url string               If provided, this URL will be used to connect via proxy
+      --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
+      --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
+      --token string                   Bearer token for authentication to the API server
+      --user string                    The name of the kubeconfig user to use
+      --username string                Username for basic authentication to the API server
 ```
 
 ### Options inherited from parent commands
 
 ```
-      --as string                       Username to impersonate for the operation
-      --as-group stringArray            Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
-      --as-uid string                   UID to impersonate for the operation
       --auth-token string               Authentication token
-      --certificate-authority string    Path to a cert file for the certificate authority
-      --client-certificate string       Path to a client certificate file for TLS
       --client-crt string               Client certificate file
       --client-crt-key string           Client certificate key file
-      --client-key string               Path to a client key file for TLS
-      --cluster string                  The name of the kubeconfig cluster to use
       --config string                   Path to Argo CD config (default "/home/user/.config/argocd/config")
-      --context string                  The name of the kubeconfig context to use
       --core                            If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server
       --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)
       --http-retry-max int              Maximum number of retries to establish http connection to Argo CD server
       --insecure                        Skip server certificate and domain verification
-      --insecure-skip-tls-verify        If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
       --kube-context string             Directs the command to the given kube-context
-      --kubeconfig string               Path to a kube config. Only required if out-of-cluster
       --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")
-  -n, --namespace string                If present, the namespace scope for this CLI request
-      --password string                 Password for basic authentication to the API server
       --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
-      --proxy-url string                If provided, this URL will be used to connect via proxy
-      --request-timeout string          The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-      --server string                   The address and port of the Kubernetes API server
       --server-crt string               Server certificate file
-      --tls-server-name string          If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
-      --token string                    Bearer token for authentication to the API server
-      --user string                     The name of the kubeconfig user to use
-      --username string                 Username for basic authentication to the API server
 ```
 
 ### SEE ALSO
diff --git a/docs/user-guide/commands/argocd_admin_cluster_shards.md b/docs/user-guide/commands/argocd_admin_cluster_shards.md
index 299843052..be7cc36cc 100644
--- a/docs/user-guide/commands/argocd_admin_cluster_shards.md
+++ b/docs/user-guide/commands/argocd_admin_cluster_shards.md
@@ -38,6 +38,7 @@ argocd admin cluster shards [flags]
       --request-timeout string                The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
       --sentinel stringArray                  Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). 
       --sentinelmaster string                 Redis sentinel master group name. (default "master")
+      --server string                         The address and port of the Kubernetes API server
       --shard int                             Cluster shard filter (default -1)
       --tls-server-name string                If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                          Bearer token for authentication to the API server
@@ -64,7 +65,6 @@ argocd admin cluster shards [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md
index f58be54cd..586069e08 100644
--- a/docs/user-guide/commands/argocd_admin_cluster_stats.md
+++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md
@@ -38,6 +38,7 @@ argocd admin cluster stats [flags]
       --request-timeout string                The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
       --sentinel stringArray                  Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). 
       --sentinelmaster string                 Redis sentinel master group name. (default "master")
+      --server string                         The address and port of the Kubernetes API server
       --shard int                             Cluster shard filter (default -1)
       --tls-server-name string                If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                          Bearer token for authentication to the API server
@@ -64,7 +65,6 @@ argocd admin cluster stats [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_export.md b/docs/user-guide/commands/argocd_admin_export.md
index 667919be7..27ff5ad1f 100644
--- a/docs/user-guide/commands/argocd_admin_export.md
+++ b/docs/user-guide/commands/argocd_admin_export.md
@@ -25,6 +25,7 @@ argocd admin export [flags]
       --password string                Password for basic authentication to the API server
       --proxy-url string               If provided, this URL will be used to connect via proxy
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -50,7 +51,6 @@ argocd admin export [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_import.md b/docs/user-guide/commands/argocd_admin_import.md
index 731dfad14..62c9c9443 100644
--- a/docs/user-guide/commands/argocd_admin_import.md
+++ b/docs/user-guide/commands/argocd_admin_import.md
@@ -26,6 +26,7 @@ argocd admin import SOURCE [flags]
       --proxy-url string               If provided, this URL will be used to connect via proxy
       --prune                          Prune secrets, applications and projects which do not appear in the backup
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --stop-operation                 Stop any existing operations
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
@@ -53,7 +54,6 @@ argocd admin import SOURCE [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_initial-password.md b/docs/user-guide/commands/argocd_admin_initial-password.md
index 4f938f5f9..2f997d25d 100644
--- a/docs/user-guide/commands/argocd_admin_initial-password.md
+++ b/docs/user-guide/commands/argocd_admin_initial-password.md
@@ -24,6 +24,7 @@ argocd admin initial-password [flags]
       --password string                Password for basic authentication to the API server
       --proxy-url string               If provided, this URL will be used to connect via proxy
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -49,7 +50,6 @@ argocd admin initial-password [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_notifications.md b/docs/user-guide/commands/argocd_admin_notifications.md
index 9d257c44d..f2bb15b50 100644
--- a/docs/user-guide/commands/argocd_admin_notifications.md
+++ b/docs/user-guide/commands/argocd_admin_notifications.md
@@ -29,6 +29,7 @@ argocd admin notifications [flags]
       --proxy-url string                If provided, this URL will be used to connect via proxy
       --request-timeout string          The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
       --secret string                   argocd-notifications-secret.yaml file path. Use empty secret if provided value is ':empty'
+      --server string                   The address and port of the Kubernetes API server
       --tls-server-name string          If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                    Bearer token for authentication to the API server
       --user string                     The name of the kubeconfig user to use
@@ -54,7 +55,6 @@ argocd admin notifications [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_notifications_template_get.md b/docs/user-guide/commands/argocd_admin_notifications_template_get.md
index 278eff2df..58993c1ab 100644
--- a/docs/user-guide/commands/argocd_admin_notifications_template_get.md
+++ b/docs/user-guide/commands/argocd_admin_notifications_template_get.md
@@ -11,9 +11,9 @@ argocd admin notifications template get [flags]
 ```
 
 # prints all templates
-notifications template get
+argocd admin notifications template get
 # print YAML formatted app-sync-succeeded template definition
-notifications template get app-sync-succeeded -o=yaml
+argocd admin notifications template get app-sync-succeeded -o=yaml
 
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md
index dd5eed8be..c9098e594 100644
--- a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md
+++ b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md
@@ -11,10 +11,10 @@ argocd admin notifications template notify NAME RESOURCE_NAME [flags]
 ```
 
 # Trigger notification using in-cluster config map and secret
-notifications template notify app-sync-succeeded guestbook --recipient slack:my-slack-channel
+argocd admin notifications template notify app-sync-succeeded guestbook --recipient slack:my-slack-channel
 
 # Render notification render generated notification in console
-notifications template notify app-sync-succeeded guestbook
+argocd admin notifications template notify app-sync-succeeded guestbook
 
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md
index 47d392e51..625d71bd5 100644
--- a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md
+++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md
@@ -11,9 +11,9 @@ argocd admin notifications trigger get [flags]
 ```
 
 # prints all triggers
-notifications trigger get
+argocd admin notifications trigger get
 # print YAML formatted on-sync-failed trigger definition
-notifications trigger get on-sync-failed -o=yaml
+argocd admin notifications trigger get on-sync-failed -o=yaml
 
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md
index 077e05132..92f60bdcb 100644
--- a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md
+++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md
@@ -11,10 +11,10 @@ argocd admin notifications trigger run NAME RESOURCE_NAME [flags]
 ```
 
 # Execute trigger configured in 'argocd-notification-cm' ConfigMap
-notifications trigger run on-sync-status-unknown ./sample-app.yaml
+argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml
 
 # Execute trigger using my-config-map.yaml instead of 'argocd-notifications-cm' ConfigMap
-notifications trigger run on-sync-status-unknown ./sample-app.yaml \
+argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml \
     --config-map ./my-config-map.yaml
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md
index 251a3375b..a16531a20 100644
--- a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md
+++ b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md
@@ -25,6 +25,7 @@ argocd admin proj generate-allow-list CLUSTERROLE_PATH PROJ_NAME [flags]
       --password string                Password for basic authentication to the API server
       --proxy-url string               If provided, this URL will be used to connect via proxy
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -50,7 +51,6 @@ argocd admin proj generate-allow-list CLUSTERROLE_PATH PROJ_NAME [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md b/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md
index bbf182499..f26b4c511 100644
--- a/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md
+++ b/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md
@@ -40,6 +40,7 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags]
       --resource string                Resource e.g. 'applications'
       --role string                    Role name pattern e.g. '*deployer*' (default "*")
       --scope string                   Resource scope e.g. '*'
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -65,7 +66,6 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_settings.md b/docs/user-guide/commands/argocd_admin_settings.md
index 6f0e241d6..e1c9d36f2 100644
--- a/docs/user-guide/commands/argocd_admin_settings.md
+++ b/docs/user-guide/commands/argocd_admin_settings.md
@@ -27,6 +27,7 @@ argocd admin settings [flags]
       --password string                Password for basic authentication to the API server
       --proxy-url string               If provided, this URL will be used to connect via proxy
       --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
       --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
       --token string                   Bearer token for authentication to the API server
       --user string                    The name of the kubeconfig user to use
@@ -52,7 +53,6 @@ argocd admin settings [flags]
       --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
 ```
 
diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md
index 6ee5c2cdc..560539a52 100644
--- a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md
+++ b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md
@@ -39,12 +39,31 @@ argocd admin settings rbac can someuser create application 'default/app' --defau
 ### Options
 
 ```
-      --default-role string   name of the default role to use
-  -h, --help                  help for can
-      --policy-file string    path to the policy file to use
-  -q, --quiet                 quiet mode - do not print results to stdout
-      --strict                whether to perform strict check on action and resource names (default true)
-      --use-builtin-policy    whether to also use builtin-policy (default true)
+      --as string                      Username to impersonate for the operation
+      --as-group stringArray           Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
+      --as-uid string                  UID to impersonate for the operation
+      --certificate-authority string   Path to a cert file for the certificate authority
+      --client-certificate string      Path to a client certificate file for TLS
+      --client-key string              Path to a client key file for TLS
+      --cluster string                 The name of the kubeconfig cluster to use
+      --context string                 The name of the kubeconfig context to use
+      --default-role string            name of the default role to use
+  -h, --help                           help for can
+      --insecure-skip-tls-verify       If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
+      --kubeconfig string              Path to a kube config. Only required if out-of-cluster
+  -n, --namespace string               If present, the namespace scope for this CLI request
+      --password string                Password for basic authentication to the API server
+      --policy-file string             path to the policy file to use
+      --proxy-url string               If provided, this URL will be used to connect via proxy
+  -q, --quiet                          quiet mode - do not print results to stdout
+      --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
+      --server string                  The address and port of the Kubernetes API server
+      --strict                         whether to perform strict check on action and resource names (default true)
+      --tls-server-name string         If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
+      --token string                   Bearer token for authentication to the API server
+      --use-builtin-policy             whether to also use builtin-policy (default true)
+      --user string                    The name of the kubeconfig user to use
+      --username string                Username for basic authentication to the API server
 ```
 
 ### Options inherited from parent commands
@@ -52,43 +71,24 @@ argocd admin settings rbac can someuser create application 'default/app' --defau
 ```
       --argocd-cm-path string           Path to local argocd-cm.yaml file
       --argocd-secret-path string       Path to local argocd-secret.yaml file
-      --as string                       Username to impersonate for the operation
-      --as-group stringArray            Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
-      --as-uid string                   UID to impersonate for the operation
       --auth-token string               Authentication token
-      --certificate-authority string    Path to a cert file for the certificate authority
-      --client-certificate string       Path to a client certificate file for TLS
       --client-crt string               Client certificate file
       --client-crt-key string           Client certificate key file
-      --client-key string               Path to a client key file for TLS
-      --cluster string                  The name of the kubeconfig cluster to use
       --config string                   Path to Argo CD config (default "/home/user/.config/argocd/config")
-      --context string                  The name of the kubeconfig context to use
       --core                            If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server
       --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)
       --http-retry-max int              Maximum number of retries to establish http connection to Argo CD server
       --insecure                        Skip server certificate and domain verification
-      --insecure-skip-tls-verify        If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
       --kube-context string             Directs the command to the given kube-context
-      --kubeconfig string               Path to a kube config. Only required if out-of-cluster
       --load-cluster-settings           Indicates that config map and secret should be loaded from cluster unless local file path is provided
       --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")
-  -n, --namespace string                If present, the namespace scope for this CLI request
-      --password string                 Password for basic authentication to the API server
       --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
-      --proxy-url string                If provided, this URL will be used to connect via proxy
-      --request-timeout string          The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-      --server string                   The address and port of the Kubernetes API server
       --server-crt string               Server certificate file
-      --tls-server-name string          If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
-      --token string                    Bearer token for authentication to the API server
-      --user string                     The name of the kubeconfig user to use
-      --username string                 Username for basic authentication to the API server
 ```
 
 ### SEE ALSO
diff --git a/go.mod b/go.mod
index c070ebf1c..887d8c9bf 100644
--- a/go.mod
+++ b/go.mod
@@ -10,8 +10,8 @@ require (
 	github.com/alicebob/miniredis/v2 v2.14.2
 	github.com/argoproj/gitops-engine v0.7.1-0.20221108210551-e284fd71cb96
 	github.com/argoproj/notifications-engine v0.3.1-0.20220812180936-4d8552b0775f
-	github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0
-	github.com/aws/aws-sdk-go v1.38.49
+	github.com/argoproj/pkg v0.13.7-0.20221115212233-27bd8ce31415
+	github.com/aws/aws-sdk-go v1.44.129
 	github.com/bombsimon/logrusr/v2 v2.0.1
 	github.com/bradleyfalzon/ghinstallation/v2 v2.0.4
 	github.com/casbin/casbin/v2 v2.39.1
@@ -38,7 +38,7 @@ require (
 	github.com/google/go-github/v35 v35.3.0
 	github.com/google/go-jsonnet v0.18.0
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
-	github.com/google/uuid v1.1.2
+	github.com/google/uuid v1.3.0
 	github.com/gorilla/handlers v1.5.1
 	github.com/gorilla/websocket v1.4.2
 	github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
@@ -62,18 +62,18 @@ require (
 	github.com/prometheus/client_golang v1.12.1
 	github.com/r3labs/diff v1.1.0
 	github.com/rs/cors v1.8.0 // indirect
-	github.com/sirupsen/logrus v1.8.1
+	github.com/sirupsen/logrus v1.9.0
 	github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c
 	github.com/soheilhy/cmux v0.1.5
-	github.com/spf13/cobra v1.5.0
+	github.com/spf13/cobra v1.6.1
 	github.com/spf13/pflag v1.0.5
-	github.com/stretchr/testify v1.7.1
+	github.com/stretchr/testify v1.8.1
 	github.com/valyala/fasttemplate v1.2.1
 	github.com/whilp/git-urls v0.0.0-20191001220047-6db9661140c0
 	github.com/xanzy/go-gitlab v0.60.0
 	github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da
-	golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
-	golang.org/x/net v0.0.0-20220621193019-9d032be2e588 // indirect
+	golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
+	golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
 	golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
 	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
@@ -99,7 +99,7 @@ require (
 
 require (
 	github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e
-	github.com/stretchr/objx v0.3.0 // indirect
+	github.com/stretchr/objx v0.5.0 // indirect
 	gopkg.in/square/go-jose.v2 v2.6.0 // indirect
 	k8s.io/apiserver v0.24.2
 )
@@ -149,7 +149,7 @@ require (
 	github.com/emirpasic/gods v1.12.0 // indirect
 	github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
 	github.com/fatih/camelcase v1.0.0 // indirect
-	github.com/felixge/httpsnoop v1.0.1 // indirect
+	github.com/felixge/httpsnoop v1.0.3 // indirect
 	github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
 	github.com/fvbommel/sortorder v1.0.1 // indirect
 	github.com/go-errors/errors v1.0.1 // indirect
@@ -177,7 +177,7 @@ require (
 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
 	github.com/hashicorp/go-version v1.2.1 // indirect
 	github.com/huandu/xstrings v1.3.0 // indirect
-	github.com/inconshreveable/mousetrap v1.0.0 // indirect
+	github.com/inconshreveable/mousetrap v1.0.1 // indirect
 	github.com/itchyny/timefmt-go v0.1.2 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
@@ -185,7 +185,7 @@ require (
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
-	github.com/klauspost/compress v1.13.5 // indirect
+	github.com/klauspost/compress v1.15.9 // indirect
 	github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
 	github.com/mailru/easyjson v0.7.6 // indirect
 	github.com/mattn/go-runewidth v0.0.9 // indirect
@@ -226,7 +226,7 @@ require (
 	go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
 	golang.org/x/exp v0.0.0-20210901193431-a062eea981d2 // indirect
 	golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
-	golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
+	golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
 	golang.org/x/text v0.3.7 // indirect
 	golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
 	golang.org/x/tools v0.1.10 // indirect
@@ -239,7 +239,7 @@ require (
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
-	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 	k8s.io/cli-runtime v0.24.2 // indirect
 	k8s.io/component-base v0.24.2 // indirect
 	k8s.io/component-helpers v0.24.2 // indirect
diff --git a/go.sum b/go.sum
index e6781456a..464126aaf 100644
--- a/go.sum
+++ b/go.sum
@@ -146,8 +146,8 @@ github.com/argoproj/gitops-engine v0.7.1-0.20221108210551-e284fd71cb96 h1:4CQn3g
 github.com/argoproj/gitops-engine v0.7.1-0.20221108210551-e284fd71cb96/go.mod h1:WpA/B7tgwfz+sdNE3LqrTrb7ArEY1FOPI2pAGI0hfPc=
 github.com/argoproj/notifications-engine v0.3.1-0.20220812180936-4d8552b0775f h1:xTts6TJ/SBbY9zV8qpueokUd3+SlJN6Abt4W6lAjOKM=
 github.com/argoproj/notifications-engine v0.3.1-0.20220812180936-4d8552b0775f/go.mod h1:R3zlopt+/juYlebQc9Jarn9vBQ2xZruWOWjUNkfGY9M=
-github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc=
-github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0/go.mod h1:ra+bQPmbVAoEL+gYSKesuigt4m49i3Qa3mE/xQcjCiA=
+github.com/argoproj/pkg v0.13.7-0.20221115212233-27bd8ce31415 h1:/5UtDHntvwPxbe/j2+xmQgvG83PQueGHko+9sf8+FA0=
+github.com/argoproj/pkg v0.13.7-0.20221115212233-27bd8ce31415/go.mod h1:vqTRUU8ATWVtKog5bVg0zDrKxEjUaFnObZaqpY0oprQ=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
@@ -163,10 +163,10 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l
 github.com/auth0/go-jwt-middleware v1.0.1/go.mod h1:YSeUX3z6+TF2H+7padiEqNJ73Zy9vXW72U//IgN0BIM=
 github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
 github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
-github.com/aws/aws-sdk-go v1.33.16/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
 github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
-github.com/aws/aws-sdk-go v1.38.49 h1:E31vxjCe6a5I+mJLmUGaZobiWmg9KdWaud9IfceYeYQ=
 github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/aws/aws-sdk-go v1.44.129 h1:yld8Rc8OCahLtenY1mnve4w1jVeBu/rSiscGzodaDOs=
+github.com/aws/aws-sdk-go v1.44.129/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
 github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
 github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
@@ -333,8 +333,9 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
 github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
 github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
-github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
 github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
+github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/flosch/pongo2 v0.0.0-20181225140029-79872a7b2769/go.mod h1:tbAXHifHQWNSpWbiJHpJTZH5fi3XHhDMdP//vuz9WS4=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
@@ -459,7 +460,6 @@ github.com/go-redis/cache/v8 v8.4.2/go.mod h1:X7Jjd69Ssbrf3xBQLtIDE0g3WcSbFoQiSG
 github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8=
 github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc=
 github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
@@ -570,8 +570,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
@@ -674,8 +675,9 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
 github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a h1:RweVA0vnEyStwtAelyGmnU8ENDnwd1Q7pQr7U3J/rXo=
 github.com/improbable-eng/grpc-web v0.0.0-20181111100011-16092bd1d58a/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
+github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/ishidawataru/sctp v0.0.0-20190723014705-7c296d48a2b5/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8=
 github.com/itchyny/go-flags v1.5.0/go.mod h1:lenkYuCobuxLBAd/HGFE4LRoW8D3B6iXRQfWYJ+MNbA=
@@ -691,7 +693,6 @@ github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
 github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
 github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
@@ -731,9 +732,12 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4=
 github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
+github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
+github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -814,9 +818,9 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
 github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
 github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
 github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
-github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
-github.com/minio/minio-go/v7 v7.0.2/go.mod h1:dJ80Mv2HeGkYLH1sqS/ksz07ON6csH3S6JUMSQ2zAns=
-github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
+github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
+github.com/minio/minio-go/v7 v7.0.43/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
+github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
 github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
@@ -1006,6 +1010,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
 github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so=
 github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM=
 github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
 github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM=
 github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
 github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
@@ -1028,15 +1033,15 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
+github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI=
 github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
 github.com/slack-go/slack v0.10.1 h1:BGbxa0kMsGEvLOEoZmYs8T1wWfoZXwmQFBb6FgYCXUA=
 github.com/slack-go/slack v0.10.1/go.mod h1:wWL//kk0ho+FcQXcBTmEafUI5dz4qz5f4mMk8oIkioQ=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
-github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -1059,8 +1064,8 @@ github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSW
 github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
 github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
 github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
-github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
-github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
+github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
+github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -1081,8 +1086,9 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
-github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
-github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -1090,8 +1096,10 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
@@ -1230,7 +1238,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -1245,8 +1252,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
-golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1360,8 +1367,8 @@ golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220621193019-9d032be2e588 h1:9ubFuySsnAJYGyJrZ3koiEv8FyqofCBdz3G9Mbf2YFc=
-golang.org/x/net v0.0.0-20220621193019-9d032be2e588/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1507,8 +1514,11 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -1808,9 +1818,9 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkp
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
 gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
diff --git a/hack/gen-catalog/main.go b/hack/gen-catalog/main.go
index d07c4f34f..05f27406a 100644
--- a/hack/gen-catalog/main.go
+++ b/hack/gen-catalog/main.go
@@ -150,18 +150,27 @@ func generateBuiltInTriggersDocs(out io.Writer, triggers map[string][]triggers.C
 }
 
 func generateCommandsDocs(out io.Writer) error {
-	toolsCmd := admin.NewNotificationsCommand()
-	for _, subCommand := range toolsCmd.Commands() {
-		for _, c := range subCommand.Commands() {
-			var cmdDesc bytes.Buffer
-			if err := doc.GenMarkdown(c, &cmdDesc); err != nil {
-				return err
-			}
-			for _, line := range strings.Split(cmdDesc.String(), "\n") {
-				if strings.HasPrefix(line, "### SEE ALSO") {
-					break
+    // create parents so that CommandPath() is correctly resolved
+	mainCmd := &cobra.Command{Use: "argocd"}
+	adminCmd := &cobra.Command{Use: "admin"}
+	toolCmd := admin.NewNotificationsCommand()
+	adminCmd.AddCommand(toolCmd)
+	mainCmd.AddCommand(adminCmd)
+	for _, mainSubCommand := range mainCmd.Commands() {
+		for _, adminSubCommand := range mainSubCommand.Commands() {
+			for _, toolSubCommand := range adminSubCommand.Commands() {
+				for _, c := range toolSubCommand.Commands() {
+					var cmdDesc bytes.Buffer
+					if err := doc.GenMarkdown(c, &cmdDesc); err != nil {
+						return err
+					}
+					for _, line := range strings.Split(cmdDesc.String(), "\n") {
+						if strings.HasPrefix(line, "### SEE ALSO") {
+							break
+						}
+						_, _ = fmt.Fprintf(out, "%s\n", line)
+					}
 				}
-				_, _ = fmt.Fprintf(out, "%s\n", line)
 			}
 		}
 	}
diff --git a/manifests/base/redis/argocd-redis-network-policy.yaml b/manifests/base/redis/argocd-redis-network-policy.yaml
index a0f29d973..837b3e042 100644
--- a/manifests/base/redis/argocd-redis-network-policy.yaml
+++ b/manifests/base/redis/argocd-redis-network-policy.yaml
@@ -10,27 +10,22 @@ spec:
   - Ingress
   - Egress
   ingress:
-    - from:
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-server
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-repo-server
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-application-controller
-      ports:
-        - protocol: TCP
-          port: 6379
+  - from:
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-server
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-repo-server
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-application-controller
+    ports:
+    - protocol: TCP
+      port: 6379
   egress:
-    - to:
-      - ipBlock:
-          cidr: 0.0.0.0/0
-      ports:
-        - port: 53
-          protocol: UDP
-        - port: 53
-          protocol: TCP 
-    
-      
+  - ports:
+    - port: 53
+      protocol: UDP
+    - port: 53
+      protocol: TCP
diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml
index 15a9666f3..d5f9183dc 100644
--- a/manifests/core-install.yaml
+++ b/manifests/core-install.yaml
@@ -10544,9 +10544,6 @@ spec:
       protocol: UDP
     - port: 53
       protocol: TCP
-    to:
-    - ipBlock:
-        cidr: 0.0.0.0/0
   ingress:
   - from:
     - podSelector:
diff --git a/manifests/ha/base/redis-ha/argocd-redis-ha-proxy-network-policy.yaml b/manifests/ha/base/redis-ha/argocd-redis-ha-proxy-network-policy.yaml
index bf21d91f3..7732c0deb 100644
--- a/manifests/ha/base/redis-ha/argocd-redis-ha-proxy-network-policy.yaml
+++ b/manifests/ha/base/redis-ha/argocd-redis-ha-proxy-network-policy.yaml
@@ -10,36 +10,33 @@ spec:
   - Ingress
   - Egress
   ingress:
-    - from:
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-server
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-repo-server
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-application-controller
-      ports:
-        - port: 6379
-          protocol: TCP
-        - port: 26379
-          protocol: TCP
+  - from:
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-server
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-repo-server
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-application-controller
+    ports:
+    - port: 6379
+      protocol: TCP
+    - port: 26379
+      protocol: TCP
   egress:
-    - to:
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-redis-ha
-      ports:
-        - port: 6379
-          protocol: TCP
-        - port: 26379
-          protocol: TCP
-    - to:
-      - ipBlock:
-          cidr: 0.0.0.0/0
-      ports:
-        - port: 53
-          protocol: UDP
-        - port: 53
-          protocol: TCP
+  - to:
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-redis-ha
+    ports:
+    - port: 6379
+      protocol: TCP
+    - port: 26379
+      protocol: TCP
+  - ports:
+    - port: 53
+      protocol: UDP
+    - port: 53
+      protocol: TCP
diff --git a/manifests/ha/base/redis-ha/argocd-redis-ha-server-network-policy.yaml b/manifests/ha/base/redis-ha/argocd-redis-ha-server-network-policy.yaml
index 04c5ddd94..0fc937980 100644
--- a/manifests/ha/base/redis-ha/argocd-redis-ha-server-network-policy.yaml
+++ b/manifests/ha/base/redis-ha/argocd-redis-ha-server-network-policy.yaml
@@ -10,33 +10,30 @@ spec:
   - Ingress
   - Egress
   ingress:
-    - from:
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-redis-ha-haproxy
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-redis-ha
-      ports:
-        - port: 6379
-          protocol: TCP
-        - port: 26379
-          protocol: TCP
+  - from:
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-redis-ha-haproxy
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-redis-ha
+    ports:
+    - port: 6379
+      protocol: TCP
+    - port: 26379
+      protocol: TCP
   egress:
-    - to:
-      - podSelector:
-          matchLabels:
-            app.kubernetes.io/name: argocd-redis-ha
-      ports:
-        - port: 6379
-          protocol: TCP
-        - port: 26379
-          protocol: TCP
-    - to:
-      - ipBlock:
-          cidr: 0.0.0.0/0
-      ports:
-        - port: 53
-          protocol: UDP
-        - port: 53
-          protocol: TCP
\ No newline at end of file
+  - to:
+    - podSelector:
+        matchLabels:
+          app.kubernetes.io/name: argocd-redis-ha
+    ports:
+    - port: 6379
+      protocol: TCP
+    - port: 26379
+      protocol: TCP
+  - ports:
+    - port: 53
+      protocol: UDP
+    - port: 53
+      protocol: TCP
diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml
index ed635ee5c..441bd240b 100644
--- a/manifests/ha/install.yaml
+++ b/manifests/ha/install.yaml
@@ -12546,9 +12546,6 @@ spec:
       protocol: UDP
     - port: 53
       protocol: TCP
-    to:
-    - ipBlock:
-        cidr: 0.0.0.0/0
   ingress:
   - from:
     - podSelector:
@@ -12592,9 +12589,6 @@ spec:
       protocol: UDP
     - port: 53
       protocol: TCP
-    to:
-    - ipBlock:
-        cidr: 0.0.0.0/0
   ingress:
   - from:
     - podSelector:
diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml
index 9174dd36f..43b7c31b1 100644
--- a/manifests/ha/namespace-install.yaml
+++ b/manifests/ha/namespace-install.yaml
@@ -2968,9 +2968,6 @@ spec:
       protocol: UDP
     - port: 53
       protocol: TCP
-    to:
-    - ipBlock:
-        cidr: 0.0.0.0/0
   ingress:
   - from:
     - podSelector:
@@ -3014,9 +3011,6 @@ spec:
       protocol: UDP
     - port: 53
       protocol: TCP
-    to:
-    - ipBlock:
-        cidr: 0.0.0.0/0
   ingress:
   - from:
     - podSelector:
diff --git a/manifests/install.yaml b/manifests/install.yaml
index 5f0d1be65..ad5db1a9d 100644
--- a/manifests/install.yaml
+++ b/manifests/install.yaml
@@ -11361,9 +11361,6 @@ spec:
       protocol: UDP
     - port: 53
       protocol: TCP
-    to:
-    - ipBlock:
-        cidr: 0.0.0.0/0
   ingress:
   - from:
     - podSelector:
diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml
index 10ff420a1..6c86d3700 100644
--- a/manifests/namespace-install.yaml
+++ b/manifests/namespace-install.yaml
@@ -1783,9 +1783,6 @@ spec:
       protocol: UDP
     - port: 53
       protocol: TCP
-    to:
-    - ipBlock:
-        cidr: 0.0.0.0/0
   ingress:
   - from:
     - podSelector:
diff --git a/mkdocs.yml b/mkdocs.yml
index c3c294dcc..0a1da7183 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,6 +1,6 @@
 extra:
   analytics:
-    property: UA-105170809-2
+    property: G-5Z1VTPDL73
     provider: google
 extra_css:
 - assets/versions.css
@@ -57,9 +57,9 @@ nav:
     - operator-manual/notifications/catalog.md
     - operator-manual/notifications/monitoring.md
     - operator-manual/notifications/subscriptions.md
+    - operator-manual/notifications/troubleshooting.md
     - operator-manual/notifications/troubleshooting-commands.md
     - operator-manual/notifications/troubleshooting-errors.md
-    - operator-manual/notifications/troubleshooting.md
     - Notification Services:
       - operator-manual/notifications/services/alertmanager.md
       - operator-manual/notifications/services/email.md
diff --git a/pkg/apiclient/application/forwarder_overwrite.go b/pkg/apiclient/application/forwarder_overwrite.go
index 02d2d5b2a..d37e26bab 100644
--- a/pkg/apiclient/application/forwarder_overwrite.go
+++ b/pkg/apiclient/application/forwarder_overwrite.go
@@ -5,6 +5,7 @@ import (
 	"errors"
 	"fmt"
 	gohttp "net/http"
+	"strings"
 
 	"github.com/argoproj/argo-cd/v2/util/kube"
 
@@ -17,6 +18,86 @@ import (
 	"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
 )
 
+// appFields is a map of fields that can be selected from an application.
+// The manually maintained list is required because application list response might include thousands of applications
+// and JSON based field handling is too slow.
+var appFields = map[string]func(app *v1alpha1.Application) interface{}{
+	"metadata.name":              func(app *v1alpha1.Application) interface{} { return app.Name },
+	"metadata.namespace":         func(app *v1alpha1.Application) interface{} { return app.Namespace },
+	"metadata.annotations":       func(app *v1alpha1.Application) interface{} { return app.Annotations },
+	"metadata.labels":            func(app *v1alpha1.Application) interface{} { return app.Labels },
+	"metadata.creationTimestamp": func(app *v1alpha1.Application) interface{} { return app.CreationTimestamp },
+	"metadata.deletionTimestamp": func(app *v1alpha1.Application) interface{} { return app.DeletionTimestamp },
+	"spec":                       func(app *v1alpha1.Application) interface{} { return app.Spec },
+	"status.sync.status":         func(app *v1alpha1.Application) interface{} { return app.Status.Sync.Status },
+	"status.health":              func(app *v1alpha1.Application) interface{} { return app.Status.Health },
+	"status.summary":             func(app *v1alpha1.Application) interface{} { return app.Status.Summary },
+	"status.resources": func(app *v1alpha1.Application) interface{} {
+		if len(app.Status.Resources) > 0 {
+			return app.Status.Resources
+		}
+		return nil
+	},
+	"operation.sync": func(app *v1alpha1.Application) interface{} {
+		if app.Operation != nil {
+			return app.Operation.Sync
+		}
+		return nil
+	},
+	"status.operationState.phase": func(app *v1alpha1.Application) interface{} {
+		if app.Status.OperationState != nil {
+			return app.Status.OperationState.Phase
+		}
+		return nil
+	},
+	"status.operationState.operation.sync": func(app *v1alpha1.Application) interface{} {
+		if app.Status.OperationState != nil {
+			return app.Status.OperationState.SyncResult
+		}
+		return nil
+	},
+}
+
+func processApplicationListField(v interface{}, fields map[string]interface{}, exclude bool) (interface{}, error) {
+	if appList, ok := v.(*v1alpha1.ApplicationList); ok {
+		var items []map[string]interface{}
+		for _, app := range appList.Items {
+			converted := make(map[string]interface{})
+			items = append(items, converted)
+			for field, fn := range appFields {
+				if _, ok := fields["items."+field]; ok == exclude {
+					continue
+				}
+				value := fn(&app)
+				parts := strings.Split(field, ".")
+				item := converted
+				for i := 0; i < len(parts); i++ {
+					subField := parts[i]
+					if i == len(parts)-1 {
+						if value != nil {
+							item[subField] = value
+						}
+					} else {
+						if _, ok := item[subField]; !ok {
+							item[subField] = make(map[string]interface{})
+						}
+						nestedMap, ok := item[subField].(map[string]interface{})
+						if !ok {
+							return nil, fmt.Errorf("field %s is not a map", field)
+						}
+						item = nestedMap
+					}
+				}
+			}
+		}
+		return map[string]interface{}{
+			"items":    items,
+			"metadata": appList.ListMeta,
+		}, nil
+	}
+	return nil, errors.New("not an application list")
+}
+
 func init() {
 	logsForwarder := func(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w gohttp.ResponseWriter, req *gohttp.Request, recv func() (proto.Message, error), opts ...func(context.Context, gohttp.ResponseWriter, proto.Message) error) {
 		if req.URL.Query().Get("download") == "true" {
@@ -55,6 +136,6 @@ func init() {
 		}
 		return event.Application.Name, nil
 	})
-	forward_ApplicationService_List_0 = http.UnaryForwarder
+	forward_ApplicationService_List_0 = http.UnaryForwarderWithFieldProcessor(processApplicationListField)
 	forward_ApplicationService_ManagedResources_0 = http.UnaryForwarder
 }
diff --git a/pkg/apiclient/settings/settings.pb.go b/pkg/apiclient/settings/settings.pb.go
index 15fee300d..9fbbea430 100644
--- a/pkg/apiclient/settings/settings.pb.go
+++ b/pkg/apiclient/settings/settings.pb.go
@@ -84,24 +84,25 @@ type Settings struct {
 	GoogleAnalytics    *GoogleAnalyticsConfig                `protobuf:"bytes,7,opt,name=googleAnalytics,proto3" json:"googleAnalytics,omitempty"`
 	KustomizeOptions   *v1alpha1.KustomizeOptions            `protobuf:"bytes,8,opt,name=kustomizeOptions,proto3" json:"kustomizeOptions,omitempty"`
 	// Help settings
-	Help                    *Help                              `protobuf:"bytes,9,opt,name=help,proto3" json:"help,omitempty"`
-	Plugins                 []*Plugin                          `protobuf:"bytes,10,rep,name=plugins,proto3" json:"plugins,omitempty"`
-	UserLoginsDisabled      bool                               `protobuf:"varint,11,opt,name=userLoginsDisabled,proto3" json:"userLoginsDisabled,omitempty"`
-	ConfigManagementPlugins []*v1alpha1.ConfigManagementPlugin `protobuf:"bytes,12,rep,name=configManagementPlugins,proto3" json:"configManagementPlugins,omitempty"`
-	KustomizeVersions       []string                           `protobuf:"bytes,13,rep,name=kustomizeVersions,proto3" json:"kustomizeVersions,omitempty"`
-	UiCssURL                string                             `protobuf:"bytes,14,opt,name=uiCssURL,proto3" json:"uiCssURL,omitempty"`
-	UiBannerContent         string                             `protobuf:"bytes,15,opt,name=uiBannerContent,proto3" json:"uiBannerContent,omitempty"`
-	UiBannerURL             string                             `protobuf:"bytes,16,opt,name=uiBannerURL,proto3" json:"uiBannerURL,omitempty"`
-	PasswordPattern         string                             `protobuf:"bytes,17,opt,name=passwordPattern,proto3" json:"passwordPattern,omitempty"`
-	TrackingMethod          string                             `protobuf:"bytes,18,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"`
-	UiBannerPermanent       bool                               `protobuf:"varint,19,opt,name=uiBannerPermanent,proto3" json:"uiBannerPermanent,omitempty"`
-	UiBannerPosition        string                             `protobuf:"bytes,20,opt,name=uiBannerPosition,proto3" json:"uiBannerPosition,omitempty"`
-	StatusBadgeRootUrl      string                             `protobuf:"bytes,21,opt,name=statusBadgeRootUrl,proto3" json:"statusBadgeRootUrl,omitempty"`
-	ExecEnabled             bool                               `protobuf:"varint,22,opt,name=execEnabled,proto3" json:"execEnabled,omitempty"`
-	ControllerNamespace     string                             `protobuf:"bytes,23,opt,name=controllerNamespace,proto3" json:"controllerNamespace,omitempty"`
-	XXX_NoUnkeyedLiteral    struct{}                           `json:"-"`
-	XXX_unrecognized        []byte                             `json:"-"`
-	XXX_sizecache           int32                              `json:"-"`
+	Help                      *Help                              `protobuf:"bytes,9,opt,name=help,proto3" json:"help,omitempty"`
+	Plugins                   []*Plugin                          `protobuf:"bytes,10,rep,name=plugins,proto3" json:"plugins,omitempty"`
+	UserLoginsDisabled        bool                               `protobuf:"varint,11,opt,name=userLoginsDisabled,proto3" json:"userLoginsDisabled,omitempty"`
+	ConfigManagementPlugins   []*v1alpha1.ConfigManagementPlugin `protobuf:"bytes,12,rep,name=configManagementPlugins,proto3" json:"configManagementPlugins,omitempty"`
+	KustomizeVersions         []string                           `protobuf:"bytes,13,rep,name=kustomizeVersions,proto3" json:"kustomizeVersions,omitempty"`
+	UiCssURL                  string                             `protobuf:"bytes,14,opt,name=uiCssURL,proto3" json:"uiCssURL,omitempty"`
+	UiBannerContent           string                             `protobuf:"bytes,15,opt,name=uiBannerContent,proto3" json:"uiBannerContent,omitempty"`
+	UiBannerURL               string                             `protobuf:"bytes,16,opt,name=uiBannerURL,proto3" json:"uiBannerURL,omitempty"`
+	PasswordPattern           string                             `protobuf:"bytes,17,opt,name=passwordPattern,proto3" json:"passwordPattern,omitempty"`
+	TrackingMethod            string                             `protobuf:"bytes,18,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"`
+	UiBannerPermanent         bool                               `protobuf:"varint,19,opt,name=uiBannerPermanent,proto3" json:"uiBannerPermanent,omitempty"`
+	UiBannerPosition          string                             `protobuf:"bytes,20,opt,name=uiBannerPosition,proto3" json:"uiBannerPosition,omitempty"`
+	StatusBadgeRootUrl        string                             `protobuf:"bytes,21,opt,name=statusBadgeRootUrl,proto3" json:"statusBadgeRootUrl,omitempty"`
+	ExecEnabled               bool                               `protobuf:"varint,22,opt,name=execEnabled,proto3" json:"execEnabled,omitempty"`
+	ControllerNamespace       string                             `protobuf:"bytes,23,opt,name=controllerNamespace,proto3" json:"controllerNamespace,omitempty"`
+	AppsInAnyNamespaceEnabled bool                               `protobuf:"varint,24,opt,name=appsInAnyNamespaceEnabled,proto3" json:"appsInAnyNamespaceEnabled,omitempty"`
+	XXX_NoUnkeyedLiteral      struct{}                           `json:"-"`
+	XXX_unrecognized          []byte                             `json:"-"`
+	XXX_sizecache             int32                              `json:"-"`
 }
 
 func (m *Settings) Reset()         { *m = Settings{} }
@@ -298,6 +299,13 @@ func (m *Settings) GetControllerNamespace() string {
 	return ""
 }
 
+func (m *Settings) GetAppsInAnyNamespaceEnabled() bool {
+	if m != nil {
+		return m.AppsInAnyNamespaceEnabled
+	}
+	return false
+}
+
 type GoogleAnalyticsConfig struct {
 	TrackingID           string   `protobuf:"bytes,1,opt,name=trackingID,proto3" json:"trackingID,omitempty"`
 	AnonymizeUsers       bool     `protobuf:"varint,2,opt,name=anonymizeUsers,proto3" json:"anonymizeUsers,omitempty"`
@@ -675,78 +683,79 @@ func init() {
 func init() { proto.RegisterFile("server/settings/settings.proto", fileDescriptor_a480d494da040caa) }
 
 var fileDescriptor_a480d494da040caa = []byte{
-	// 1129 bytes of a gzipped FileDescriptorProto
+	// 1148 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
-	0x14, 0xd7, 0xd6, 0x69, 0x62, 0xbf, 0x34, 0x75, 0x32, 0x6d, 0xd3, 0xc5, 0x2a, 0x8e, 0xf1, 0xa1,
-	0x32, 0x08, 0xd6, 0x8d, 0x2b, 0x04, 0x42, 0xaa, 0x00, 0xdb, 0x55, 0x6b, 0xea, 0xb6, 0x61, 0xdb,
-	0xf4, 0x80, 0x84, 0xaa, 0xc9, 0xee, 0x63, 0xb3, 0x78, 0x3d, 0xb3, 0x9a, 0x99, 0x35, 0x75, 0x8f,
-	0xdc, 0xb8, 0x70, 0x81, 0x4f, 0xc3, 0x27, 0xe0, 0x88, 0xc4, 0x3d, 0x42, 0x16, 0x1f, 0x82, 0x23,
-	0x9a, 0xd9, 0x3f, 0xd9, 0xd8, 0xe6, 0x8f, 0xd4, 0xdb, 0xcc, 0xef, 0xf7, 0xfe, 0xcd, 0x9b, 0x37,
-	0xf3, 0x1e, 0x34, 0x25, 0x8a, 0x19, 0x8a, 0xae, 0x44, 0xa5, 0x42, 0x16, 0xc8, 0x62, 0xe1, 0xc4,
-	0x82, 0x2b, 0x4e, 0xb6, 0xbc, 0x28, 0x91, 0x0a, 0x45, 0xe3, 0x7a, 0xc0, 0x03, 0x6e, 0xb0, 0xae,
-	0x5e, 0xa5, 0x74, 0xe3, 0x56, 0xc0, 0x79, 0x10, 0x61, 0x97, 0xc6, 0x61, 0x97, 0x32, 0xc6, 0x15,
-	0x55, 0x21, 0x67, 0x99, 0x72, 0x63, 0x1c, 0x84, 0xea, 0x34, 0x39, 0x71, 0x3c, 0x3e, 0xed, 0x52,
-	0x61, 0xd4, 0xbf, 0x35, 0x8b, 0x0f, 0x3c, 0xbf, 0x3b, 0xeb, 0x75, 0xe3, 0x49, 0xa0, 0x35, 0x65,
-	0x97, 0xc6, 0x71, 0x14, 0x7a, 0x46, 0xb7, 0x3b, 0x3b, 0xa4, 0x51, 0x7c, 0x4a, 0x0f, 0xbb, 0x01,
-	0x32, 0x14, 0x54, 0xa1, 0x9f, 0x59, 0xfb, 0xec, 0x3f, 0xac, 0x2d, 0x9f, 0x84, 0x87, 0xbe, 0xd7,
-	0xf5, 0x22, 0x1a, 0x4e, 0xb3, 0x78, 0xda, 0x75, 0xd8, 0x79, 0x96, 0xb1, 0x5f, 0x26, 0x28, 0xe6,
-	0xed, 0xbf, 0x00, 0xaa, 0x39, 0x42, 0xde, 0x82, 0x4a, 0x22, 0x22, 0xdb, 0x6a, 0x59, 0x9d, 0x5a,
-	0x7f, 0x6b, 0x71, 0x76, 0x50, 0x39, 0x76, 0xc7, 0xae, 0xc6, 0xc8, 0x1d, 0xa8, 0xf9, 0xf8, 0x6a,
-	0xc0, 0xd9, 0x37, 0x61, 0x60, 0x5f, 0x6a, 0x59, 0x9d, 0xed, 0x1e, 0x71, 0xb2, 0xcc, 0x38, 0xc3,
-	0x9c, 0x71, 0xcf, 0x85, 0xc8, 0x00, 0x40, 0xfb, 0xcf, 0x54, 0x2a, 0x46, 0xe5, 0x5a, 0xa1, 0xf2,
-	0x74, 0x34, 0x1c, 0xa4, 0x54, 0xff, 0xea, 0xe2, 0xec, 0x00, 0xce, 0xf7, 0x6e, 0x49, 0x8d, 0xb4,
-	0x60, 0x9b, 0xc6, 0xf1, 0x98, 0x9e, 0x60, 0xf4, 0x08, 0xe7, 0xf6, 0x86, 0x8e, 0xcc, 0x2d, 0x43,
-	0xe4, 0x05, 0xec, 0x09, 0x94, 0x3c, 0x11, 0x1e, 0x3e, 0x9d, 0xa1, 0x10, 0xa1, 0x8f, 0xd2, 0xbe,
-	0xdc, 0xaa, 0x74, 0xb6, 0x7b, 0x9d, 0xc2, 0x5b, 0x7e, 0x42, 0xc7, 0x5d, 0x16, 0xbd, 0xcf, 0x94,
-	0x98, 0xbb, 0xab, 0x26, 0x88, 0x03, 0x44, 0x2a, 0xaa, 0x12, 0xd9, 0xa7, 0x7e, 0x80, 0xf7, 0x19,
-	0x3d, 0x89, 0xd0, 0xb7, 0x37, 0x5b, 0x56, 0xa7, 0xea, 0xae, 0x61, 0xc8, 0x43, 0xa8, 0xa7, 0x95,
-	0xf0, 0x39, 0xa3, 0xd1, 0x5c, 0x85, 0x9e, 0xb4, 0xb7, 0xcc, 0x99, 0x9b, 0x45, 0x14, 0x0f, 0x2e,
-	0xf2, 0xd9, 0x71, 0x97, 0xd5, 0xc8, 0x6b, 0xd8, 0x9d, 0x24, 0x52, 0xf1, 0x69, 0xf8, 0x1a, 0x9f,
-	0xc6, 0xa6, 0x9a, 0xec, 0xaa, 0x31, 0xf5, 0xc4, 0x39, 0x2f, 0x00, 0x27, 0x2f, 0x00, 0xb3, 0x78,
-	0xe9, 0xf9, 0xce, 0xac, 0xe7, 0xc4, 0x93, 0xc0, 0xd1, 0xe5, 0xe4, 0x94, 0xca, 0xc9, 0xc9, 0xcb,
-	0xc9, 0x79, 0xb4, 0x64, 0xd5, 0x5d, 0xf1, 0x43, 0xde, 0x81, 0x8d, 0x53, 0x8c, 0x62, 0xbb, 0x66,
-	0xfc, 0xed, 0x14, 0xa1, 0x3f, 0xc4, 0x28, 0x76, 0x0d, 0x45, 0xde, 0x85, 0xad, 0x38, 0x4a, 0x82,
-	0x90, 0x49, 0x1b, 0x4c, 0x9a, 0xeb, 0x85, 0xd4, 0x91, 0xc1, 0xdd, 0x9c, 0xd7, 0x39, 0x4c, 0x24,
-	0x8a, 0x31, 0xd7, 0xbb, 0x61, 0x28, 0xd3, 0x1c, 0x6e, 0xa7, 0x39, 0x5c, 0x65, 0xc8, 0x8f, 0x16,
-	0xdc, 0xf4, 0x4c, 0x56, 0x1e, 0x53, 0x46, 0x03, 0x9c, 0x22, 0x53, 0x47, 0x99, 0xaf, 0x2b, 0xc6,
-	0xd7, 0xf3, 0x37, 0xcb, 0xc0, 0x60, 0xad, 0x71, 0xf7, 0x9f, 0x9c, 0x92, 0xf7, 0x61, 0xaf, 0x48,
-	0xd1, 0x0b, 0x14, 0xd2, 0xdc, 0xc5, 0x4e, 0xab, 0xd2, 0xa9, 0xb9, 0xab, 0x04, 0x69, 0x40, 0x35,
-	0x09, 0x07, 0x52, 0x1e, 0xbb, 0x63, 0xfb, 0xaa, 0xa9, 0xd4, 0x62, 0x4f, 0x3a, 0x50, 0x4f, 0xc2,
-	0x3e, 0x65, 0x0c, 0xc5, 0x80, 0x33, 0x85, 0x4c, 0xd9, 0x75, 0x23, 0xb2, 0x0c, 0xeb, 0x92, 0xcf,
-	0x21, 0x6d, 0x68, 0x37, 0x2d, 0xf9, 0x12, 0xa4, 0x6d, 0xc5, 0x54, 0xca, 0xef, 0xb8, 0xf0, 0x8f,
-	0xa8, 0x52, 0x28, 0x98, 0xbd, 0x97, 0xda, 0x5a, 0x82, 0xc9, 0x6d, 0xb8, 0xaa, 0x04, 0xf5, 0x26,
-	0x21, 0x0b, 0x1e, 0xa3, 0x3a, 0xe5, 0xbe, 0x4d, 0x8c, 0xe0, 0x12, 0xaa, 0xcf, 0x99, 0x3b, 0x38,
-	0x42, 0x31, 0xa5, 0x4c, 0xc7, 0x77, 0xcd, 0xdc, 0xd3, 0x2a, 0x41, 0xde, 0x83, 0xdd, 0x02, 0xe4,
-	0x32, 0xd4, 0x29, 0xb6, 0xaf, 0x1b, 0xbb, 0x2b, 0xf8, 0xd2, 0x33, 0x72, 0x39, 0x57, 0xc7, 0x22,
-	0xb2, 0x6f, 0x18, 0xe9, 0x35, 0x8c, 0x3e, 0x3d, 0xbe, 0x42, 0x2f, 0x7f, 0x6f, 0xfb, 0x26, 0x86,
-	0x32, 0x44, 0xee, 0xc0, 0x35, 0x8f, 0x33, 0x25, 0x78, 0x14, 0xa1, 0x78, 0x42, 0xa7, 0x28, 0x63,
-	0xea, 0xa1, 0x7d, 0xd3, 0x98, 0x5c, 0x47, 0x35, 0x7e, 0xb6, 0x60, 0x7f, 0xfd, 0xc3, 0x27, 0xbb,
-	0x50, 0x99, 0xe0, 0x3c, 0xfd, 0xf1, 0x5c, 0xbd, 0x24, 0x3e, 0x5c, 0x9e, 0xd1, 0x28, 0xc1, 0xec,
-	0x93, 0x7b, 0xc3, 0x27, 0xb7, 0xec, 0xd6, 0x4d, 0x8d, 0x7f, 0x72, 0xe9, 0x63, 0xab, 0xfd, 0x12,
-	0x6e, 0xac, 0xfd, 0x11, 0x48, 0x13, 0x20, 0xbf, 0x9f, 0xd1, 0x30, 0x8b, 0xad, 0x84, 0xe8, 0x5b,
-	0xa5, 0x8c, 0xb3, 0xb9, 0x2e, 0xbe, 0x63, 0x89, 0x42, 0x9a, 0x58, 0xab, 0xee, 0x12, 0xda, 0xfe,
-	0xc5, 0x82, 0x0d, 0xfd, 0x70, 0x89, 0x0d, 0x5b, 0xde, 0x29, 0x35, 0x99, 0x4f, 0xad, 0xe5, 0x5b,
-	0x5d, 0xb2, 0x7a, 0xf9, 0x1c, 0x5f, 0x29, 0x63, 0xa4, 0xe6, 0x16, 0x7b, 0x72, 0x0f, 0xe0, 0x24,
-	0x64, 0x54, 0xcc, 0x8f, 0x45, 0x24, 0xed, 0x8a, 0x79, 0x7f, 0x6f, 0x5f, 0xf8, 0x11, 0x9c, 0x7e,
-	0xc1, 0xa7, 0xff, 0x68, 0x49, 0xa1, 0x71, 0x0f, 0xea, 0x4b, 0xf4, 0x9a, 0x6c, 0x5f, 0x2f, 0x67,
-	0xbb, 0x56, 0xce, 0xce, 0x2d, 0xd8, 0x4c, 0x5f, 0x21, 0x21, 0xb0, 0xc1, 0xe8, 0x14, 0x33, 0x35,
-	0xb3, 0x6e, 0x7f, 0x0a, 0xb5, 0xa2, 0xe9, 0x90, 0x1e, 0x80, 0xc7, 0x19, 0x43, 0x4f, 0x71, 0x21,
-	0x6d, 0xcb, 0x04, 0x7a, 0xde, 0x9c, 0x06, 0x39, 0xe5, 0x96, 0xa4, 0xda, 0x77, 0xa1, 0x56, 0x10,
-	0xeb, 0x3c, 0x68, 0x4c, 0xcd, 0xe3, 0x3c, 0x30, 0xb3, 0x6e, 0xff, 0x50, 0x81, 0x52, 0xa3, 0x5a,
-	0xab, 0xb6, 0x0f, 0x9b, 0xa1, 0x94, 0x09, 0x8a, 0x4c, 0x31, 0xdb, 0x91, 0x0e, 0x54, 0xbd, 0x28,
-	0x44, 0xa6, 0x46, 0x43, 0xd3, 0x0b, 0x6b, 0xfd, 0x2b, 0x8b, 0xb3, 0x83, 0xea, 0x20, 0xc3, 0xdc,
-	0x82, 0x25, 0x87, 0xb0, 0xed, 0x45, 0x61, 0x4e, 0xa4, 0x2d, 0xaf, 0x5f, 0x5f, 0x9c, 0x1d, 0x6c,
-	0x0f, 0xc6, 0xa3, 0x42, 0xbe, 0x2c, 0xa3, 0x9d, 0x4a, 0x8f, 0xc7, 0x59, 0xe3, 0xab, 0xb9, 0xd9,
-	0x8e, 0xbc, 0x84, 0x9d, 0xd0, 0x7f, 0xce, 0x27, 0xc8, 0x06, 0x66, 0x08, 0xb0, 0x37, 0x4d, 0x6e,
-	0x6e, 0xaf, 0xe9, 0xc2, 0xce, 0xa8, 0x2c, 0x68, 0xae, 0xab, 0xbf, 0xb7, 0x38, 0x3b, 0xd8, 0x19,
-	0x0d, 0x4b, 0xb8, 0x7b, 0xd1, 0x5e, 0x63, 0x0e, 0x64, 0x55, 0x6f, 0xcd, 0x35, 0x3f, 0xbe, 0xf8,
-	0xa8, 0x3e, 0xfa, 0xd7, 0x47, 0x95, 0x4e, 0x31, 0x4e, 0x31, 0x86, 0xe9, 0x71, 0xc0, 0x31, 0xf6,
-	0x4b, 0xf5, 0xd1, 0xfb, 0x1a, 0xea, 0x79, 0x57, 0x7f, 0x86, 0x62, 0x16, 0x7a, 0x48, 0xbe, 0x80,
-	0xca, 0x03, 0x54, 0x64, 0x7f, 0xa5, 0xed, 0x9b, 0x51, 0xa7, 0xb1, 0xb7, 0x82, 0xb7, 0xed, 0xef,
-	0x7f, 0xff, 0xf3, 0xa7, 0x4b, 0x84, 0xec, 0x9a, 0xf1, 0x6d, 0x76, 0x58, 0x8c, 0x4e, 0xfd, 0xc1,
-	0xaf, 0x8b, 0xa6, 0xf5, 0xdb, 0xa2, 0x69, 0xfd, 0xb1, 0x68, 0x5a, 0x5f, 0x7d, 0xf8, 0xff, 0xc6,
-	0xb8, 0xf4, 0x0e, 0x0b, 0x23, 0x27, 0x9b, 0x66, 0xe8, 0xba, 0xfb, 0x77, 0x00, 0x00, 0x00, 0xff,
-	0xff, 0x2a, 0xfc, 0x97, 0xee, 0x63, 0x0a, 0x00, 0x00,
+	0x14, 0xd7, 0xd6, 0x69, 0x62, 0x3f, 0x37, 0x75, 0x32, 0x6d, 0xd3, 0xad, 0x55, 0x92, 0xe0, 0x43,
+	0x65, 0x10, 0xac, 0x1b, 0x57, 0x08, 0x84, 0xa8, 0xa0, 0xb6, 0xab, 0xd6, 0xd4, 0x6d, 0xc3, 0xb6,
+	0xe9, 0x01, 0x09, 0x55, 0x93, 0xdd, 0xc7, 0x66, 0xf1, 0x7a, 0x66, 0x35, 0x33, 0x6b, 0xea, 0x1e,
+	0xb9, 0x71, 0xe1, 0x02, 0x9f, 0x85, 0x03, 0x9f, 0x80, 0x23, 0x12, 0xf7, 0x08, 0x59, 0x7c, 0x10,
+	0x34, 0xb3, 0x7f, 0xb2, 0xb1, 0x5d, 0x40, 0xea, 0x6d, 0xe6, 0xf7, 0x7b, 0xff, 0xe6, 0xcd, 0x7b,
+	0x33, 0x0f, 0x76, 0x25, 0x8a, 0x29, 0x8a, 0x8e, 0x44, 0xa5, 0x42, 0x16, 0xc8, 0x62, 0xe1, 0xc4,
+	0x82, 0x2b, 0x4e, 0x36, 0xbc, 0x28, 0x91, 0x0a, 0x45, 0xf3, 0x6a, 0xc0, 0x03, 0x6e, 0xb0, 0x8e,
+	0x5e, 0xa5, 0x74, 0xf3, 0x66, 0xc0, 0x79, 0x10, 0x61, 0x87, 0xc6, 0x61, 0x87, 0x32, 0xc6, 0x15,
+	0x55, 0x21, 0x67, 0x99, 0x72, 0x73, 0x14, 0x84, 0xea, 0x24, 0x39, 0x76, 0x3c, 0x3e, 0xe9, 0x50,
+	0x61, 0xd4, 0xbf, 0x33, 0x8b, 0x0f, 0x3d, 0xbf, 0x33, 0xed, 0x76, 0xe2, 0x71, 0xa0, 0x35, 0x65,
+	0x87, 0xc6, 0x71, 0x14, 0x7a, 0x46, 0xb7, 0x33, 0x3d, 0xa0, 0x51, 0x7c, 0x42, 0x0f, 0x3a, 0x01,
+	0x32, 0x14, 0x54, 0xa1, 0x9f, 0x59, 0xfb, 0xe2, 0x3f, 0xac, 0x2d, 0x9e, 0x84, 0x87, 0xbe, 0xd7,
+	0xf1, 0x22, 0x1a, 0x4e, 0xb2, 0x78, 0x5a, 0x0d, 0xd8, 0x7c, 0x96, 0xb1, 0x5f, 0x25, 0x28, 0x66,
+	0xad, 0x5f, 0xeb, 0x50, 0xcd, 0x11, 0x72, 0x03, 0x2a, 0x89, 0x88, 0x6c, 0x6b, 0xdf, 0x6a, 0xd7,
+	0x7a, 0x1b, 0xf3, 0xd3, 0xbd, 0xca, 0x91, 0x3b, 0x72, 0x35, 0x46, 0x6e, 0x43, 0xcd, 0xc7, 0x57,
+	0x7d, 0xce, 0xbe, 0x0d, 0x03, 0xfb, 0xc2, 0xbe, 0xd5, 0xae, 0x77, 0x89, 0x93, 0x65, 0xc6, 0x19,
+	0xe4, 0x8c, 0x7b, 0x26, 0x44, 0xfa, 0x00, 0xda, 0x7f, 0xa6, 0x52, 0x31, 0x2a, 0x57, 0x0a, 0x95,
+	0xa7, 0xc3, 0x41, 0x3f, 0xa5, 0x7a, 0x97, 0xe7, 0xa7, 0x7b, 0x70, 0xb6, 0x77, 0x4b, 0x6a, 0x64,
+	0x1f, 0xea, 0x34, 0x8e, 0x47, 0xf4, 0x18, 0xa3, 0x47, 0x38, 0xb3, 0xd7, 0x74, 0x64, 0x6e, 0x19,
+	0x22, 0x2f, 0x60, 0x5b, 0xa0, 0xe4, 0x89, 0xf0, 0xf0, 0xe9, 0x14, 0x85, 0x08, 0x7d, 0x94, 0xf6,
+	0xc5, 0xfd, 0x4a, 0xbb, 0xde, 0x6d, 0x17, 0xde, 0xf2, 0x13, 0x3a, 0xee, 0xa2, 0xe8, 0x7d, 0xa6,
+	0xc4, 0xcc, 0x5d, 0x36, 0x41, 0x1c, 0x20, 0x52, 0x51, 0x95, 0xc8, 0x1e, 0xf5, 0x03, 0xbc, 0xcf,
+	0xe8, 0x71, 0x84, 0xbe, 0xbd, 0xbe, 0x6f, 0xb5, 0xab, 0xee, 0x0a, 0x86, 0x3c, 0x84, 0x46, 0x5a,
+	0x09, 0xf7, 0x18, 0x8d, 0x66, 0x2a, 0xf4, 0xa4, 0xbd, 0x61, 0xce, 0xbc, 0x5b, 0x44, 0xf1, 0xe0,
+	0x3c, 0x9f, 0x1d, 0x77, 0x51, 0x8d, 0xbc, 0x86, 0xad, 0x71, 0x22, 0x15, 0x9f, 0x84, 0xaf, 0xf1,
+	0x69, 0x6c, 0xaa, 0xc9, 0xae, 0x1a, 0x53, 0x4f, 0x9c, 0xb3, 0x02, 0x70, 0xf2, 0x02, 0x30, 0x8b,
+	0x97, 0x9e, 0xef, 0x4c, 0xbb, 0x4e, 0x3c, 0x0e, 0x1c, 0x5d, 0x4e, 0x4e, 0xa9, 0x9c, 0x9c, 0xbc,
+	0x9c, 0x9c, 0x47, 0x0b, 0x56, 0xdd, 0x25, 0x3f, 0xe4, 0x5d, 0x58, 0x3b, 0xc1, 0x28, 0xb6, 0x6b,
+	0xc6, 0xdf, 0x66, 0x11, 0xfa, 0x43, 0x8c, 0x62, 0xd7, 0x50, 0xe4, 0x3d, 0xd8, 0x88, 0xa3, 0x24,
+	0x08, 0x99, 0xb4, 0xc1, 0xa4, 0xb9, 0x51, 0x48, 0x1d, 0x1a, 0xdc, 0xcd, 0x79, 0x9d, 0xc3, 0x44,
+	0xa2, 0x18, 0x71, 0xbd, 0x1b, 0x84, 0x32, 0xcd, 0x61, 0x3d, 0xcd, 0xe1, 0x32, 0x43, 0x7e, 0xb2,
+	0xe0, 0xba, 0x67, 0xb2, 0xf2, 0x98, 0x32, 0x1a, 0xe0, 0x04, 0x99, 0x3a, 0xcc, 0x7c, 0x5d, 0x32,
+	0xbe, 0x9e, 0xbf, 0x5d, 0x06, 0xfa, 0x2b, 0x8d, 0xbb, 0x6f, 0x72, 0x4a, 0x3e, 0x80, 0xed, 0x22,
+	0x45, 0x2f, 0x50, 0x48, 0x73, 0x17, 0x9b, 0xfb, 0x95, 0x76, 0xcd, 0x5d, 0x26, 0x48, 0x13, 0xaa,
+	0x49, 0xd8, 0x97, 0xf2, 0xc8, 0x1d, 0xd9, 0x97, 0x4d, 0xa5, 0x16, 0x7b, 0xd2, 0x86, 0x46, 0x12,
+	0xf6, 0x28, 0x63, 0x28, 0xfa, 0x9c, 0x29, 0x64, 0xca, 0x6e, 0x18, 0x91, 0x45, 0x58, 0x97, 0x7c,
+	0x0e, 0x69, 0x43, 0x5b, 0x69, 0xc9, 0x97, 0x20, 0x6d, 0x2b, 0xa6, 0x52, 0x7e, 0xcf, 0x85, 0x7f,
+	0x48, 0x95, 0x42, 0xc1, 0xec, 0xed, 0xd4, 0xd6, 0x02, 0x4c, 0x6e, 0xc1, 0x65, 0x25, 0xa8, 0x37,
+	0x0e, 0x59, 0xf0, 0x18, 0xd5, 0x09, 0xf7, 0x6d, 0x62, 0x04, 0x17, 0x50, 0x7d, 0xce, 0xdc, 0xc1,
+	0x21, 0x8a, 0x09, 0x65, 0x3a, 0xbe, 0x2b, 0xe6, 0x9e, 0x96, 0x09, 0xf2, 0x3e, 0x6c, 0x15, 0x20,
+	0x97, 0xa1, 0x4e, 0xb1, 0x7d, 0xd5, 0xd8, 0x5d, 0xc2, 0x17, 0xda, 0xc8, 0xe5, 0x5c, 0x1d, 0x89,
+	0xc8, 0xbe, 0x66, 0xa4, 0x57, 0x30, 0xfa, 0xf4, 0xf8, 0x0a, 0xbd, 0xbc, 0xdf, 0x76, 0x4c, 0x0c,
+	0x65, 0x88, 0xdc, 0x86, 0x2b, 0x1e, 0x67, 0x4a, 0xf0, 0x28, 0x42, 0xf1, 0x84, 0x4e, 0x50, 0xc6,
+	0xd4, 0x43, 0xfb, 0xba, 0x31, 0xb9, 0x8a, 0x22, 0x9f, 0xc1, 0x0d, 0x1a, 0xc7, 0x72, 0xc8, 0xee,
+	0xb1, 0x59, 0x81, 0xe6, 0x1e, 0x6c, 0xe3, 0xe1, 0xcd, 0x02, 0xcd, 0x5f, 0x2c, 0xd8, 0x59, 0xfd,
+	0x6c, 0x90, 0x2d, 0xa8, 0x8c, 0x71, 0x96, 0xbe, 0x97, 0xae, 0x5e, 0x12, 0x1f, 0x2e, 0x4e, 0x69,
+	0x94, 0x60, 0xf6, 0x44, 0xbe, 0x65, 0xc3, 0x2e, 0xba, 0x75, 0x53, 0xe3, 0x9f, 0x5e, 0xf8, 0xc4,
+	0x6a, 0xbd, 0x84, 0x6b, 0x2b, 0xdf, 0x13, 0xb2, 0x0b, 0x90, 0xdf, 0xee, 0x70, 0x90, 0xc5, 0x56,
+	0x42, 0x74, 0x4d, 0x50, 0xc6, 0xd9, 0x4c, 0x97, 0xee, 0x91, 0x44, 0x21, 0x4d, 0xac, 0x55, 0x77,
+	0x01, 0x6d, 0xfd, 0x66, 0xc1, 0x9a, 0x6e, 0x7b, 0x62, 0xc3, 0x86, 0x77, 0x42, 0xcd, 0xbd, 0xa5,
+	0xd6, 0xf2, 0xad, 0x2e, 0x78, 0xbd, 0x7c, 0x8e, 0xaf, 0x94, 0x31, 0x52, 0x73, 0x8b, 0x3d, 0xb9,
+	0x0b, 0x70, 0x1c, 0x32, 0x2a, 0x66, 0x47, 0x22, 0x92, 0x76, 0xc5, 0x74, 0xef, 0x3b, 0xe7, 0xde,
+	0x13, 0xa7, 0x57, 0xf0, 0xe9, 0x2b, 0x5c, 0x52, 0x68, 0xde, 0x85, 0xc6, 0x02, 0xbd, 0x22, 0xdb,
+	0x57, 0xcb, 0xd9, 0xae, 0x95, 0xb3, 0x73, 0x13, 0xd6, 0xd3, 0x1e, 0x26, 0x04, 0xd6, 0x18, 0x9d,
+	0x60, 0xa6, 0x66, 0xd6, 0xad, 0xcf, 0xa1, 0x56, 0x7c, 0x59, 0xa4, 0x0b, 0xe0, 0x71, 0xc6, 0xd0,
+	0x53, 0x5c, 0x48, 0xdb, 0x32, 0x81, 0x9e, 0x7d, 0x6d, 0xfd, 0x9c, 0x72, 0x4b, 0x52, 0xad, 0x3b,
+	0x50, 0x2b, 0x88, 0x55, 0x1e, 0x34, 0xa6, 0x66, 0x71, 0x1e, 0x98, 0x59, 0xb7, 0x7e, 0xac, 0x40,
+	0xe9, 0x9b, 0x5b, 0xa9, 0xb6, 0x03, 0xeb, 0xa1, 0x94, 0x09, 0x8a, 0x4c, 0x31, 0xdb, 0x91, 0x36,
+	0x54, 0xbd, 0x28, 0x44, 0xa6, 0x86, 0x03, 0xf3, 0x93, 0xd6, 0x7a, 0x97, 0xe6, 0xa7, 0x7b, 0xd5,
+	0x7e, 0x86, 0xb9, 0x05, 0x4b, 0x0e, 0xa0, 0xee, 0x45, 0x61, 0x4e, 0xa4, 0x1f, 0x66, 0xaf, 0x31,
+	0x3f, 0xdd, 0xab, 0xf7, 0x47, 0xc3, 0x42, 0xbe, 0x2c, 0xa3, 0x9d, 0x4a, 0x8f, 0xc7, 0xd9, 0xb7,
+	0x59, 0x73, 0xb3, 0x1d, 0x79, 0x09, 0x9b, 0xa1, 0xff, 0x9c, 0x8f, 0x91, 0xf5, 0xcd, 0x08, 0x61,
+	0xaf, 0x9b, 0xdc, 0xdc, 0x5a, 0xf1, 0x87, 0x3b, 0xc3, 0xb2, 0xa0, 0xb9, 0xae, 0xde, 0xf6, 0xfc,
+	0x74, 0x6f, 0x73, 0x38, 0x28, 0xe1, 0xee, 0x79, 0x7b, 0xcd, 0x19, 0x90, 0x65, 0xbd, 0x15, 0xd7,
+	0xfc, 0xf8, 0x7c, 0x53, 0x7d, 0xfc, 0xaf, 0x4d, 0x95, 0xce, 0x40, 0x4e, 0x31, 0xc4, 0xe9, 0x61,
+	0xc2, 0x31, 0xf6, 0x4b, 0xf5, 0xd1, 0xfd, 0x06, 0x1a, 0xf9, 0x4c, 0xf0, 0x0c, 0xc5, 0x34, 0xf4,
+	0x90, 0x7c, 0x09, 0x95, 0x07, 0xa8, 0xc8, 0xce, 0xd2, 0xd0, 0x60, 0x06, 0xa5, 0xe6, 0xf6, 0x12,
+	0xde, 0xb2, 0x7f, 0xf8, 0xf3, 0xef, 0x9f, 0x2f, 0x10, 0xb2, 0x65, 0x86, 0xbf, 0xe9, 0x41, 0x31,
+	0x78, 0xf5, 0xfa, 0xbf, 0xcf, 0x77, 0xad, 0x3f, 0xe6, 0xbb, 0xd6, 0x5f, 0xf3, 0x5d, 0xeb, 0xeb,
+	0x8f, 0xfe, 0xdf, 0x10, 0x98, 0xde, 0x61, 0x61, 0xe4, 0x78, 0xdd, 0x8c, 0x6c, 0x77, 0xfe, 0x09,
+	0x00, 0x00, 0xff, 0xff, 0xf0, 0x33, 0x47, 0xc2, 0xa1, 0x0a, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -882,6 +891,18 @@ func (m *Settings) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i -= len(m.XXX_unrecognized)
 		copy(dAtA[i:], m.XXX_unrecognized)
 	}
+	if m.AppsInAnyNamespaceEnabled {
+		i--
+		if m.AppsInAnyNamespaceEnabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xc0
+	}
 	if len(m.ControllerNamespace) > 0 {
 		i -= len(m.ControllerNamespace)
 		copy(dAtA[i:], m.ControllerNamespace)
@@ -1576,6 +1597,9 @@ func (m *Settings) Size() (n int) {
 	if l > 0 {
 		n += 2 + l + sovSettings(uint64(l))
 	}
+	if m.AppsInAnyNamespaceEnabled {
+		n += 3
+	}
 	if m.XXX_unrecognized != nil {
 		n += len(m.XXX_unrecognized)
 	}
@@ -2625,6 +2649,26 @@ func (m *Settings) Unmarshal(dAtA []byte) error {
 			}
 			m.ControllerNamespace = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
+		case 24:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AppsInAnyNamespaceEnabled", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSettings
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.AppsInAnyNamespaceEnabled = bool(v != 0)
 		default:
 			iNdEx = preIndex
 			skippy, err := skipSettings(dAtA[iNdEx:])
diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go
index 6e8fa34d6..8b31f660f 100644
--- a/reposerver/repository/repository.go
+++ b/reposerver/repository/repository.go
@@ -856,7 +856,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
 		for _, val := range appHelm.ValueFiles {
 
 			// This will resolve val to an absolute path (or an URL)
-			path, isRemote, err := pathutil.ResolveFilePath(appPath, repoRoot, env.Envsubst(val), q.GetValuesFileSchemes())
+			path, isRemote, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, env.Envsubst(val), q.GetValuesFileSchemes())
 			if err != nil {
 				return nil, err
 			}
@@ -896,7 +896,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
 			}
 		}
 		for _, p := range appHelm.FileParameters {
-			resolvedPath, _, err := pathutil.ResolveFilePath(appPath, repoRoot, env.Envsubst(p.Path), q.GetValuesFileSchemes())
+			resolvedPath, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, env.Envsubst(p.Path), q.GetValuesFileSchemes())
 			if err != nil {
 				return nil, err
 			}
@@ -1504,7 +1504,7 @@ func makeJsonnetVm(appPath string, repoRoot string, sourceJsonnet v1alpha1.Appli
 	jpaths := []string{appPath}
 	for _, p := range sourceJsonnet.Libs {
 		// the jsonnet library path is relative to the repository root, not application path
-		jpath, _, err := pathutil.ResolveFilePath(repoRoot, repoRoot, p, nil)
+		jpath, err := pathutil.ResolveFileOrDirectoryPath(repoRoot, repoRoot, p)
 		if err != nil {
 			return nil, err
 		}
@@ -1752,7 +1752,7 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
 		return err
 	}
 
-	if resolvedValuesPath, _, err := pathutil.ResolveFilePath(appPath, repoRoot, "values.yaml", []string{}); err == nil {
+	if resolvedValuesPath, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, "values.yaml", []string{}); err == nil {
 		if err := loadFileIntoIfExists(resolvedValuesPath, &res.Helm.Values); err != nil {
 			return err
 		}
@@ -1762,7 +1762,7 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
 	var resolvedSelectedValueFiles []pathutil.ResolvedFilePath
 	// drop not allowed values files
 	for _, file := range selectedValueFiles {
-		if resolvedFile, _, err := pathutil.ResolveFilePath(appPath, repoRoot, file, q.GetValuesFileSchemes()); err == nil {
+		if resolvedFile, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, file, q.GetValuesFileSchemes()); err == nil {
 			resolvedSelectedValueFiles = append(resolvedSelectedValueFiles, resolvedFile)
 		} else {
 			log.Warnf("Values file %s is not allowed: %v", file, err)
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/health.lua b/resource_customizations/work.karmada.io/ClusterResourceBinding/health.lua
new file mode 100644
index 000000000..5098ae9fe
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/health.lua
@@ -0,0 +1,37 @@
+health_status = {}
+if obj.status == nil then
+  health_status.status = "Progressing"
+  health_status.message = "Current resource status is insufficient"
+  return health_status
+end
+
+if obj.spec.clusters == nil or #obj.spec.clusters == 0 then
+  health_status.status = "Progressing"
+  health_status.message = "Current resource status is insufficient"
+  return health_status
+end
+
+if obj.status.aggregatedStatus == nil or #obj.spec.clusters ~= #obj.status.aggregatedStatus then
+  health_status.status = "Progressing"
+  health_status.message = "Current resource status is insufficient"
+  return health_status
+end
+
+for i, status in ipairs(obj.status.aggregatedStatus) do
+  if status.health == "Unhealthy" then
+    health_status.status = "Degraded"
+    health_status.message = "Current resource status is unhealthy"
+    return health_status
+  end
+
+  if status.health == "Unknown" then
+    if status.applied ~= true then
+      health_status.status = "Degraded"
+      health_status.message = "Current resource status is unhealthy"
+      return health_status
+    end
+  end
+end
+
+health_status.status = "Healthy"
+return health_status
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/health.lua b/resource_customizations/work.karmada.io/ResourceBinding/health.lua
new file mode 100644
index 000000000..5098ae9fe
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/health.lua
@@ -0,0 +1,37 @@
+health_status = {}
+if obj.status == nil then
+  health_status.status = "Progressing"
+  health_status.message = "Current resource status is insufficient"
+  return health_status
+end
+
+if obj.spec.clusters == nil or #obj.spec.clusters == 0 then
+  health_status.status = "Progressing"
+  health_status.message = "Current resource status is insufficient"
+  return health_status
+end
+
+if obj.status.aggregatedStatus == nil or #obj.spec.clusters ~= #obj.status.aggregatedStatus then
+  health_status.status = "Progressing"
+  health_status.message = "Current resource status is insufficient"
+  return health_status
+end
+
+for i, status in ipairs(obj.status.aggregatedStatus) do
+  if status.health == "Unhealthy" then
+    health_status.status = "Degraded"
+    health_status.message = "Current resource status is unhealthy"
+    return health_status
+  end
+
+  if status.health == "Unknown" then
+    if status.applied ~= true then
+      health_status.status = "Degraded"
+      health_status.message = "Current resource status is unhealthy"
+      return health_status
+    end
+  end
+end
+
+health_status.status = "Healthy"
+return health_status
diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go
index 151a88450..2225a5d6f 100644
--- a/server/cluster/cluster.go
+++ b/server/cluster/cluster.go
@@ -1,6 +1,7 @@
 package cluster
 
 import (
+	"net/url"
 	"time"
 
 	"context"
@@ -145,6 +146,12 @@ func (s *Server) getCluster(ctx context.Context, q *cluster.ClusterQuery) (*appv
 		q.Name = ""
 		if q.Id.Type == "name" {
 			q.Name = q.Id.Value
+		} else if q.Id.Type == "name_escaped" {
+			nameUnescaped, err := url.QueryUnescape(q.Id.Value)
+			if err != nil {
+				return nil, err
+			}
+			q.Name = nameUnescaped
 		} else {
 			q.Server = q.Id.Value
 		}
diff --git a/server/server.go b/server/server.go
index 6497646f4..1855fc99b 100644
--- a/server/server.go
+++ b/server/server.go
@@ -2,6 +2,7 @@ package server
 
 import (
 	"context"
+	netCtx "context"
 	"crypto/tls"
 	"fmt"
 	goio "io"
@@ -24,8 +25,6 @@ import (
 	// nolint:staticcheck
 	golang_proto "github.com/golang/protobuf/proto"
 
-	netCtx "context"
-
 	"github.com/argoproj/notifications-engine/pkg/api"
 	"github.com/argoproj/pkg/sync"
 	"github.com/go-redis/redis/v8"
@@ -61,6 +60,8 @@ import (
 	accountpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/account"
 	applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
 
+	"github.com/pkg/errors"
+
 	applicationsetpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset"
 	certificatepkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate"
 	clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
@@ -121,7 +122,6 @@ import (
 	"github.com/argoproj/argo-cd/v2/util/swagger"
 	tlsutil "github.com/argoproj/argo-cd/v2/util/tls"
 	"github.com/argoproj/argo-cd/v2/util/webhook"
-	"github.com/pkg/errors"
 )
 
 const maxConcurrentLoginRequestsCountEnv = "ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT"
@@ -733,7 +733,8 @@ func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTre
 
 	applicationSetService := applicationset.NewServer(a.db, a.KubeClientset, a.enf, a.Cache, a.AppClientset, a.appLister, a.appsetInformer, a.appsetLister, a.projLister, a.settingsMgr, a.Namespace, projectLock)
 	projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db)
-	settingsService := settings.NewServer(a.settingsMgr, a, a.DisableAuth)
+	appsInAnyNamespaceEnabled := len(a.ArgoCDServerOpts.ApplicationNamespaces) > 0
+	settingsService := settings.NewServer(a.settingsMgr, a, a.DisableAuth, appsInAnyNamespaceEnabled)
 	accountService := account.NewServer(a.sessionMgr, a.settingsMgr, a.enf)
 
 	notificationService := notification.NewServer(a.apiFactory)
diff --git a/server/settings/settings.go b/server/settings/settings.go
index ba16aa7c0..59e7f999d 100644
--- a/server/settings/settings.go
+++ b/server/settings/settings.go
@@ -2,6 +2,7 @@ package settings
 
 import (
 	"context"
+
 	"github.com/ghodss/yaml"
 
 	sessionmgr "github.com/argoproj/argo-cd/v2/util/session"
@@ -13,9 +14,10 @@ import (
 
 // Server provides a Settings service
 type Server struct {
-	mgr           *settings.SettingsManager
-	authenticator Authenticator
-	disableAuth   bool
+	mgr                       *settings.SettingsManager
+	authenticator             Authenticator
+	disableAuth               bool
+	appsInAnyNamespaceEnabled bool
 }
 
 type Authenticator interface {
@@ -23,8 +25,8 @@ type Authenticator interface {
 }
 
 // NewServer returns a new instance of the Settings service
-func NewServer(mgr *settings.SettingsManager, authenticator Authenticator, disableAuth bool) *Server {
-	return &Server{mgr: mgr, authenticator: authenticator, disableAuth: disableAuth}
+func NewServer(mgr *settings.SettingsManager, authenticator Authenticator, disableAuth, appsInAnyNamespaceEnabled bool) *Server {
+	return &Server{mgr: mgr, authenticator: authenticator, disableAuth: disableAuth, appsInAnyNamespaceEnabled: appsInAnyNamespaceEnabled}
 }
 
 // Get returns Argo CD settings
@@ -102,13 +104,14 @@ func (s *Server) Get(ctx context.Context, q *settingspkg.SettingsQuery) (*settin
 			ChatText:   help.ChatText,
 			BinaryUrls: help.BinaryURLs,
 		},
-		Plugins:            plugins,
-		UserLoginsDisabled: userLoginsDisabled,
-		KustomizeVersions:  kustomizeVersions,
-		UiCssURL:           argoCDSettings.UiCssURL,
-		PasswordPattern:    argoCDSettings.PasswordPattern,
-		TrackingMethod:     trackingMethod,
-		ExecEnabled:        argoCDSettings.ExecEnabled,
+		Plugins:                   plugins,
+		UserLoginsDisabled:        userLoginsDisabled,
+		KustomizeVersions:         kustomizeVersions,
+		UiCssURL:                  argoCDSettings.UiCssURL,
+		PasswordPattern:           argoCDSettings.PasswordPattern,
+		TrackingMethod:            trackingMethod,
+		ExecEnabled:               argoCDSettings.ExecEnabled,
+		AppsInAnyNamespaceEnabled: s.appsInAnyNamespaceEnabled,
 	}
 
 	if sessionmgr.LoggedIn(ctx) || s.disableAuth {
diff --git a/server/settings/settings.proto b/server/settings/settings.proto
index 6183632d0..0e9ab9951 100644
--- a/server/settings/settings.proto
+++ b/server/settings/settings.proto
@@ -40,6 +40,7 @@ message Settings {
     string statusBadgeRootUrl = 21;
     bool execEnabled = 22;
     string controllerNamespace = 23;
+    bool appsInAnyNamespaceEnabled = 24;
 }
 
 message GoogleAnalyticsConfig {
diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx
index 3bc60fffa..b96d74506 100644
--- a/ui/src/app/app.tsx
+++ b/ui/src/app/app.tsx
@@ -10,12 +10,13 @@ import login from './login';
 import settings from './settings';
 import {Layout} from './shared/components/layout/layout';
 import {VersionPanel} from './shared/components/version-info/version-info-panel';
-import {Provider} from './shared/context';
+import {AuthSettingsCtx, Provider} from './shared/context';
 import {services} from './shared/services';
 import requests from './shared/services/requests';
 import {hashCode} from './shared/utils';
 import {Banner} from './ui-banner/ui-banner';
 import userInfo from './user-info';
+import {AuthSettings} from './shared/models';
 
 services.viewPreferences.init();
 const bases = document.getElementsByTagName('base');
@@ -71,8 +72,8 @@ const versionLoader = services.version.version();
 async function isExpiredSSO() {
     try {
         const {iss} = await services.users.get();
+        const authSettings = React.useContext(AuthSettingsCtx);
         if (iss && iss !== 'argocd') {
-            const authSettings = await services.authService.settings();
             return ((authSettings.dexConfig && authSettings.dexConfig.connectors) || []).length > 0 || authSettings.oidcConfig;
         }
     } catch {
@@ -106,7 +107,10 @@ requests.onError.subscribe(async err => {
     }
 });
 
-export class App extends React.Component<{}, {popupProps: PopupProps; showVersionPanel: boolean; error: Error; navItems: NavItem[]; routes: Routes; extensionsLoaded: boolean}> {
+export class App extends React.Component<
+    {},
+    {popupProps: PopupProps; showVersionPanel: boolean; error: Error; navItems: NavItem[]; routes: Routes; extensionsLoaded: boolean; authSettings: AuthSettings}
+> {
     public static childContextTypes = {
         history: PropTypes.object,
         apis: PropTypes.object
@@ -124,7 +128,7 @@ export class App extends React.Component<{}, {popupProps: PopupProps; showVersio
 
     constructor(props: {}) {
         super(props);
-        this.state = {popupProps: null, error: null, showVersionPanel: false, navItems: [], routes: null, extensionsLoaded: false};
+        this.state = {popupProps: null, error: null, showVersionPanel: false, navItems: [], routes: null, extensionsLoaded: false, authSettings: null};
         this.popupManager = new PopupManager();
         this.notificationsManager = new NotificationsManager();
         this.navigationManager = new NavigationManager(history);
@@ -181,7 +185,7 @@ export class App extends React.Component<{}, {popupProps: PopupProps; showVersio
             };
         }
 
-        this.setState({...this.state, navItems: extendedNavItems, routes: extendedRoutes, extensionsLoaded: true});
+        this.setState({...this.state, navItems: extendedNavItems, routes: extendedRoutes, extensionsLoaded: true, authSettings});
     }
 
     public render() {
@@ -211,42 +215,44 @@ export class App extends React.Component<{}, {popupProps: PopupProps; showVersio
                 <PageContext.Provider value={{title: 'Argo CD'}}>
                     <Provider value={{history, popup: this.popupManager, notifications: this.notificationsManager, navigation: this.navigationManager, baseHref: base}}>
                         {this.state.popupProps && <Popup {...this.state.popupProps} />}
-                        <Router history={history}>
-                            <Switch>
-                                <Redirect exact={true} path='/' to='/applications' />
-                                {Object.keys(this.routes).map(path => {
-                                    const route = this.routes[path];
-                                    return (
-                                        <Route
-                                            key={path}
-                                            path={path}
-                                            render={routeProps =>
-                                                route.noLayout ? (
-                                                    <div>
-                                                        <route.component {...routeProps} />
-                                                    </div>
-                                                ) : (
-                                                    <DataLoader load={() => services.viewPreferences.getPreferences()}>
-                                                        {pref => (
-                                                            <Layout
-                                                                onVersionClick={() => this.setState({showVersionPanel: true})}
-                                                                navItems={this.navItems}
-                                                                pref={pref}
-                                                                isExtension={route.extension}>
-                                                                <Banner>
-                                                                    <route.component {...routeProps} />
-                                                                </Banner>
-                                                            </Layout>
-                                                        )}
-                                                    </DataLoader>
-                                                )
-                                            }
-                                        />
-                                    );
-                                })}
-                                {this.state.extensionsLoaded && <Redirect path='*' to='/' />}
-                            </Switch>
-                        </Router>
+                        <AuthSettingsCtx.Provider value={this.state.authSettings}>
+                            <Router history={history}>
+                                <Switch>
+                                    <Redirect exact={true} path='/' to='/applications' />
+                                    {Object.keys(this.routes).map(path => {
+                                        const route = this.routes[path];
+                                        return (
+                                            <Route
+                                                key={path}
+                                                path={path}
+                                                render={routeProps =>
+                                                    route.noLayout ? (
+                                                        <div>
+                                                            <route.component {...routeProps} />
+                                                        </div>
+                                                    ) : (
+                                                        <DataLoader load={() => services.viewPreferences.getPreferences()}>
+                                                            {pref => (
+                                                                <Layout
+                                                                    onVersionClick={() => this.setState({showVersionPanel: true})}
+                                                                    navItems={this.navItems}
+                                                                    pref={pref}
+                                                                    isExtension={route.extension}>
+                                                                    <Banner>
+                                                                        <route.component {...routeProps} />
+                                                                    </Banner>
+                                                                </Layout>
+                                                            )}
+                                                        </DataLoader>
+                                                    )
+                                                }
+                                            />
+                                        );
+                                    })}
+                                    {this.state.extensionsLoaded && <Redirect path='*' to='/' />}
+                                </Switch>
+                            </Router>
+                        </AuthSettingsCtx.Provider>
                     </Provider>
                 </PageContext.Provider>
                 <Notifications notifications={this.notificationsManager.notifications} />
diff --git a/ui/src/app/applications/components/application-parameters/application-parameters.tsx b/ui/src/app/applications/components/application-parameters/application-parameters.tsx
index 84cbcd392..2e47f0714 100644
--- a/ui/src/app/applications/components/application-parameters/application-parameters.tsx
+++ b/ui/src/app/applications/components/application-parameters/application-parameters.tsx
@@ -23,7 +23,10 @@ function distinct<T>(first: IterableIterator<T>, second: IterableIterator<T>) {
     return Array.from(new Set(Array.from(first).concat(Array.from(second))));
 }
 
-function overridesFirst(first: {overrideIndex: number}, second: {overrideIndex: number}) {
+function overridesFirst(first: {overrideIndex: number; metadata: {name: string}}, second: {overrideIndex: number; metadata: {name: string}}) {
+    if (first.overrideIndex === second.overrideIndex) {
+        return first.metadata.name.localeCompare(second.metadata.name);
+    }
     if (first.overrideIndex < 0) {
         return 1;
     } else if (second.overrideIndex < 0) {
@@ -57,7 +60,7 @@ function getParamsEditableItems(
                 </span>
             ),
             edit: (formApi: FormApi) => {
-                const labelStyle = {position: 'absolute', right: 0, top: 0, zIndex: 1} as any;
+                const labelStyle = {position: 'absolute', right: 0, top: 0, zIndex: 11} as any;
                 const overrideRemoved = removedOverrides[i];
                 const fieldItemPath = `${fieldsPath}[${i}]`;
                 return (
@@ -98,11 +101,6 @@ function getParamsEditableItems(
                 );
             }
         }))
-        .sort((first, second) => {
-            const firstSortBy = first.key || first.title;
-            const secondSortBy = second.key || second.title;
-            return firstSortBy.localeCompare(secondSortBy);
-        })
         .map((item, i) => ({...item, before: (i === 0 && <p style={{marginTop: '1em'}}>{title}</p>) || null}));
 }
 
@@ -192,29 +190,31 @@ export const ApplicationParameters = (props: {
                 />
             )
         });
-        attributes.push({
-            title: 'VALUES',
-            view: app.spec.source.helm && (
-                <Expandable>
-                    <pre>{app.spec.source.helm.values}</pre>
-                </Expandable>
-            ),
-            edit: (formApi: FormApi) => (
-                <div>
-                    <pre>
-                        <FormField formApi={formApi} field='spec.source.helm.values' component={TextArea} />
-                    </pre>
-                    {props.details.helm.values && (
-                        <div>
-                            <label>values.yaml</label>
-                            <Expandable>
-                                <pre>{props.details.helm.values}</pre>
-                            </Expandable>
-                        </div>
-                    )}
-                </div>
-            )
-        });
+        if (app?.spec?.source?.helm?.values) {
+            attributes.push({
+                title: 'VALUES',
+                view: app.spec.source.helm && (
+                    <Expandable>
+                        <pre>{app.spec.source.helm.values}</pre>
+                    </Expandable>
+                ),
+                edit: (formApi: FormApi) => (
+                    <div>
+                        <pre>
+                            <FormField formApi={formApi} field='spec.source.helm.values' component={TextArea} />
+                        </pre>
+                        {props.details.helm.values && (
+                            <div>
+                                <label>values.yaml</label>
+                                <Expandable>
+                                    <pre>{props.details.helm.values}</pre>
+                                </Expandable>
+                            </div>
+                        )}
+                    </div>
+                )
+            });
+        }
         const paramsByName = new Map<string, models.HelmParameter>();
         (props.details.helm.parameters || []).forEach(param => paramsByName.set(param.name, param));
         const overridesByName = new Map<string, number>();
diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx
index c9f1af6a7..e8422c0f3 100644
--- a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx
+++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx
@@ -90,16 +90,17 @@ export const ApplicationStatusPanel = ({application, showOperation, showConditio
                         </div>
                         <div className='application-status-panel__item-value__revision'>{syncStatusMessage(application)}</div>
                     </div>
-                    <div className='application-status-panel__item-name'>
-                        {application.status && application.status.sync && application.status.sync.revision && (
+                    {application.status && application.status.sync && application.status.sync.revision && !application.spec.source.chart && (
+                        <div className='application-status-panel__item-name'>
                             <RevisionMetadataPanel
                                 appName={application.metadata.name}
                                 appNamespace={application.metadata.namespace}
                                 type={application.spec.source.chart && 'helm'}
                                 revision={application.status.sync.revision}
                             />
-                        )}
-                    </div>
+                        </div>
+                    )}
+                    <div className='application-status-panel__item-name'>{application.spec.syncPolicy?.automated ? 'Auto sync is enabled.' : 'Auto sync is not enabled.'}</div>
                 </React.Fragment>
             </div>
             {appOperationState && (
diff --git a/ui/src/app/applications/components/applications-list/applications-filter.tsx b/ui/src/app/applications/components/applications-list/applications-filter.tsx
index 8fea3b15d..6d50b7c65 100644
--- a/ui/src/app/applications/components/applications-list/applications-filter.tsx
+++ b/ui/src/app/applications/components/applications-list/applications-filter.tsx
@@ -2,7 +2,7 @@ import {useData, Checkbox} from 'argo-ui/v2';
 import * as minimatch from 'minimatch';
 import * as React from 'react';
 import {Context} from '../../../shared/context';
-import {Application, ApplicationDestination, Cluster, HealthStatusCode, HealthStatuses, SyncStatusCode, SyncStatuses} from '../../../shared/models';
+import {Application, ApplicationDestination, Cluster, HealthStatusCode, HealthStatuses, SyncPolicy, SyncStatusCode, SyncStatuses} from '../../../shared/models';
 import {AppsListPreferences, services} from '../../../shared/services';
 import {Filter, FiltersGroup} from '../filter/filter';
 import * as LabelSelector from '../label-selector';
@@ -11,6 +11,7 @@ import {ComparisonStatusIcon, HealthStatusIcon} from '../utils';
 export interface FilterResult {
     repos: boolean;
     sync: boolean;
+    autosync: boolean;
     health: boolean;
     namespaces: boolean;
     clusters: boolean;
@@ -22,12 +23,20 @@ export interface FilteredApp extends Application {
     filterResult: FilterResult;
 }
 
+function getAutoSyncStatus(syncPolicy?: SyncPolicy) {
+    if (!syncPolicy || !syncPolicy.automated) {
+        return 'Disabled';
+    }
+    return 'Enabled';
+}
+
 export function getFilterResults(applications: Application[], pref: AppsListPreferences): FilteredApp[] {
     return applications.map(app => ({
         ...app,
         filterResult: {
             repos: pref.reposFilter.length === 0 || pref.reposFilter.includes(app.spec.source.repoURL),
             sync: pref.syncFilter.length === 0 || pref.syncFilter.includes(app.status.sync.status),
+            autosync: pref.autoSyncFilter.length === 0 || pref.autoSyncFilter.includes(getAutoSyncStatus(app.spec.syncPolicy)),
             health: pref.healthFilter.length === 0 || pref.healthFilter.includes(app.status.health.status),
             namespaces: pref.namespacesFilter.length === 0 || pref.namespacesFilter.some(ns => app.spec.destination.namespace && minimatch(app.spec.destination.namespace, ns)),
             favourite: !pref.showFavorites || (pref.favoritesAppList && pref.favoritesAppList.includes(app.metadata.name)),
@@ -241,6 +250,32 @@ const FavoriteFilter = (props: AppFilterProps) => {
     );
 };
 
+function getAutoSyncOptions(apps: FilteredApp[]) {
+    const counts = getCounts(apps, 'autosync', app => getAutoSyncStatus(app.spec.syncPolicy), ['Enabled', 'Disabled']);
+    return [
+        {
+            label: 'Enabled',
+            icon: <i className='fa fa-circle-play' />,
+            count: counts.get('Enabled')
+        },
+        {
+            label: 'Disabled',
+            icon: <i className='fa fa-ban' />,
+            count: counts.get('Disabled')
+        }
+    ];
+}
+
+const AutoSyncFilter = (props: AppFilterProps) => (
+    <Filter
+        label='AUTO SYNC'
+        selected={props.pref.autoSyncFilter}
+        setSelected={s => props.onChange({...props.pref, autoSyncFilter: s})}
+        options={getAutoSyncOptions(props.apps)}
+        collapsed={props.collapsed || false}
+    />
+);
+
 export const ApplicationsFilter = (props: AppFilterProps) => {
     return (
         <FiltersGroup content={props.children} collapsed={props.collapsed}>
@@ -251,6 +286,7 @@ export const ApplicationsFilter = (props: AppFilterProps) => {
             <ProjectFilter {...props} />
             <ClusterFilter {...props} />
             <NamespaceFilter {...props} />
+            <AutoSyncFilter {...props} collapsed={true} />
         </FiltersGroup>
     );
 };
diff --git a/ui/src/app/applications/components/applications-list/applications-list.tsx b/ui/src/app/applications/components/applications-list/applications-list.tsx
index bcb1436d4..d3f76ffd7 100644
--- a/ui/src/app/applications/components/applications-list/applications-list.tsx
+++ b/ui/src/app/applications/components/applications-list/applications-list.tsx
@@ -27,6 +27,9 @@ import './flex-top-bar.scss';
 
 const EVENTS_BUFFER_TIMEOUT = 500;
 const WATCH_RETRY_TIMEOUT = 500;
+
+// The applications list/watch API supports only selected set of fields.
+// Make sure to register any new fields in the `appFields` map of `pkg/apiclient/application/forwarder_overwrite.go`.
 const APP_FIELDS = [
     'metadata.name',
     'metadata.namespace',
@@ -108,6 +111,12 @@ const ViewPref = ({children}: {children: (pref: AppsListPreferences & {page: num
                                     .split(',')
                                     .filter(item => !!item);
                             }
+                            if (params.get('autoSync') != null) {
+                                viewPref.autosyncFilter = params
+                                    .get('autoSync')
+                                    .split(',')
+                                    .filter(item => !!item);
+                            }
                             if (params.get('health') != null) {
                                 viewPref.healthFilter = params
                                     .get('health')
@@ -329,6 +338,7 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => {
             {
                 proj: newPref.projectsFilter.join(','),
                 sync: newPref.syncFilter.join(','),
+                autoSync: newPref.autoSyncFilter.join(','),
                 health: newPref.healthFilter.join(','),
                 namespace: newPref.namespacesFilter.join(','),
                 cluster: newPref.clustersFilter.join(','),
diff --git a/ui/src/app/applications/components/applications-list/applications-tiles.tsx b/ui/src/app/applications/components/applications-list/applications-tiles.tsx
index de212ebd2..d8c0c081a 100644
--- a/ui/src/app/applications/components/applications-list/applications-tiles.tsx
+++ b/ui/src/app/applications/components/applications-list/applications-tiles.tsx
@@ -3,7 +3,7 @@ import * as classNames from 'classnames';
 import * as React from 'react';
 import {Key, KeybindingContext, NumKey, NumKeyToNumber, NumPadKey, useNav} from 'argo-ui/v2';
 import {Cluster} from '../../../shared/components';
-import {Consumer, Context} from '../../../shared/context';
+import {Consumer, Context, AuthSettingsCtx} from '../../../shared/context';
 import * as models from '../../../shared/models';
 import {ApplicationURLs} from '../application-urls';
 import * as AppUtils from '../utils';
@@ -53,6 +53,7 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
     const appRef = {ref: React.useRef(null), set: false};
     const appContainerRef = React.useRef(null);
     const appsPerRow = useItemsPerContainer(appRef.ref, appContainerRef);
+    const authSettingsCtx = React.useContext(AuthSettingsCtx);
 
     const {useKeybinding} = React.useContext(KeybindingContext);
 
@@ -97,7 +98,6 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
             return navApp(NumKeyToNumber(n));
         }
     });
-
     return (
         <Consumer>
             {ctx => (
@@ -130,7 +130,9 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
                                                             }>
                                                             <i className={'icon argo-icon-' + (app.spec.source.chart != null ? 'helm' : 'git')} />
                                                             <Tooltip content={AppUtils.appInstanceName(app)}>
-                                                                <span className='applications-list__title'>{AppUtils.appQualifiedName(app)}</span>
+                                                                <span className='applications-list__title'>
+                                                                    {AppUtils.appQualifiedName(app, authSettingsCtx?.appsInAnyNamespaceEnabled)}
+                                                                </span>
                                                             </Tooltip>
                                                         </div>
                                                         <div
diff --git a/ui/src/app/applications/components/filter/filter.tsx b/ui/src/app/applications/components/filter/filter.tsx
index 2200fb707..b33302251 100644
--- a/ui/src/app/applications/components/filter/filter.tsx
+++ b/ui/src/app/applications/components/filter/filter.tsx
@@ -15,6 +15,7 @@ interface FilterProps {
     retry?: () => void;
     loading?: boolean;
     radio?: boolean;
+    collapsed?: boolean;
 }
 
 export interface CheckboxOption {
@@ -77,7 +78,7 @@ export const Filter = (props: FilterProps) => {
     const [values, setValues] = React.useState(init);
     const [tags, setTags] = React.useState([]);
     const [input, setInput] = React.useState('');
-    const [collapsed, setCollapsed] = React.useState(false);
+    const [collapsed, setCollapsed] = React.useState(props.collapsed || false);
     const [options, setOptions] = React.useState(props.options);
 
     React.useEffect(() => {
diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx
index 2822aec54..0a7975499 100644
--- a/ui/src/app/applications/components/utils.tsx
+++ b/ui/src/app/applications/components/utils.tsx
@@ -491,7 +491,7 @@ function getActionItems(
         })
         .catch(() => [] as MenuItem[]);
 
-    const resourceActions = getResourceActionsMenuItems(resource, application, appContext);
+    const resourceActions = getResourceActionsMenuItems(resource, application.metadata, appContext);
 
     return combineLatest(
         from([items]), // this resolves immediately
@@ -1150,8 +1150,8 @@ export const urlPattern = new RegExp(
     )
 );
 
-export function appQualifiedName(app: appModels.Application): string {
-    return app.metadata.namespace + '/' + app.metadata.name;
+export function appQualifiedName(app: appModels.Application, nsEnabled: boolean): string {
+    return (nsEnabled ? app.metadata.namespace + '/' : '') + app.metadata.name;
 }
 
 export function appInstanceName(app: appModels.Application): string {
diff --git a/ui/src/app/shared/components/application-selector/application-selector.tsx b/ui/src/app/shared/components/application-selector/application-selector.tsx
index a5c4f50b2..6b7b74212 100644
--- a/ui/src/app/shared/components/application-selector/application-selector.tsx
+++ b/ui/src/app/shared/components/application-selector/application-selector.tsx
@@ -3,8 +3,10 @@ import {FormFunctionProps} from 'react-form';
 import {CheckboxField} from '..';
 import * as models from '../../models';
 import {appInstanceName, appQualifiedName, ComparisonStatusIcon, HealthStatusIcon, OperationPhaseIcon} from '../../../applications/components/utils';
+import {AuthSettingsCtx} from '../../context';
 
 export const ApplicationSelector = ({apps, formApi}: {apps: models.Application[]; formApi: FormFunctionProps}) => {
+    const authSettingsCtx = React.useContext(AuthSettingsCtx);
     return (
         <>
             <label>
@@ -18,7 +20,9 @@ export const ApplicationSelector = ({apps, formApi}: {apps: models.Application[]
                     <label key={appInstanceName(app)} style={{marginTop: '0.5em', cursor: 'pointer'}}>
                         <CheckboxField field={`app/${i}`} />
                         &nbsp;
-                        {app.isAppOfAppsPattern ? `(App of Apps) ${appQualifiedName(app)}` : appQualifiedName(app)}
+                        {app.isAppOfAppsPattern
+                            ? `(App of Apps) ${appQualifiedName(app, authSettingsCtx?.appsInAnyNamespaceEnabled)}`
+                            : appQualifiedName(app, authSettingsCtx?.appsInAnyNamespaceEnabled)}
                         &nbsp;
                         <ComparisonStatusIcon status={app.status.sync.status} />
                         &nbsp;
diff --git a/ui/src/app/shared/context.ts b/ui/src/app/shared/context.ts
index 941211855..0277254a1 100644
--- a/ui/src/app/shared/context.ts
+++ b/ui/src/app/shared/context.ts
@@ -1,6 +1,7 @@
 import {AppContext as ArgoAppContext, NavigationApi, NotificationsApi, PopupApi} from 'argo-ui';
 import {History} from 'history';
 import * as React from 'react';
+import * as models from './models';
 
 export type AppContext = ArgoAppContext & {apis: {popup: PopupApi; notifications: NotificationsApi; navigation: NavigationApi; baseHref: string}};
 
@@ -11,4 +12,6 @@ export interface ContextApis {
     baseHref: string;
 }
 export const Context = React.createContext<ContextApis & {history: History}>(null);
-export const {Provider, Consumer} = Context;
+export let {Provider, Consumer} = Context;
+
+export const AuthSettingsCtx = React.createContext<models.AuthSettings>(null);
diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts
index 956ec4c31..c055c8a76 100644
--- a/ui/src/app/shared/models.ts
+++ b/ui/src/app/shared/models.ts
@@ -456,6 +456,7 @@ export interface AuthSettings {
     uiBannerPermanent: boolean;
     uiBannerPosition: string;
     execEnabled: boolean;
+    appsInAnyNamespaceEnabled: boolean;
 }
 
 export interface UserInfo {
diff --git a/ui/src/app/shared/services/clusters-service.ts b/ui/src/app/shared/services/clusters-service.ts
index 5c367aa5f..b806a5fb6 100644
--- a/ui/src/app/shared/services/clusters-service.ts
+++ b/ui/src/app/shared/services/clusters-service.ts
@@ -10,7 +10,7 @@ export class ClustersService {
     }
 
     public get(url: string, name: string): Promise<models.Cluster> {
-        const requestUrl = `/clusters/${url ? encodeURIComponent(url) : name}?id.type=${url ? 'url' : 'name'}`;
+        const requestUrl = `/clusters/${url ? encodeURIComponent(url) : encodeURIComponent(name)}?id.type=${url ? 'url' : 'name_escaped'}`;
         return requests.get(requestUrl).then(res => res.body as models.Cluster);
     }
 
diff --git a/ui/src/app/shared/services/view-preferences-service.ts b/ui/src/app/shared/services/view-preferences-service.ts
index 1c6a08a6f..937f1bd4a 100644
--- a/ui/src/app/shared/services/view-preferences-service.ts
+++ b/ui/src/app/shared/services/view-preferences-service.ts
@@ -67,6 +67,7 @@ export class AppsListPreferences {
         pref.projectsFilter = [];
         pref.reposFilter = [];
         pref.syncFilter = [];
+        pref.autoSyncFilter = [];
         pref.showFavorites = false;
     }
 
@@ -74,6 +75,7 @@ export class AppsListPreferences {
     public projectsFilter: string[];
     public reposFilter: string[];
     public syncFilter: string[];
+    public autoSyncFilter: string[];
     public healthFilter: string[];
     public namespacesFilter: string[];
     public clustersFilter: string[];
@@ -127,6 +129,7 @@ const DEFAULT_PREFERENCES: ViewPreferences = {
         clustersFilter: new Array<string>(),
         reposFilter: new Array<string>(),
         syncFilter: new Array<string>(),
+        autoSyncFilter: new Array<string>(),
         healthFilter: new Array<string>(),
         hideFilters: false,
         showFavorites: false,
diff --git a/util/helm/cmd.go b/util/helm/cmd.go
index 8e915aa93..1f6c68efc 100644
--- a/util/helm/cmd.go
+++ b/util/helm/cmd.go
@@ -58,7 +58,7 @@ func (c Cmd) run(args ...string) (string, error) {
 			fmt.Sprintf("XDG_CACHE_HOME=%s/cache", c.helmHome),
 			fmt.Sprintf("XDG_CONFIG_HOME=%s/config", c.helmHome),
 			fmt.Sprintf("XDG_DATA_HOME=%s/data", c.helmHome),
-			fmt.Sprintf("HELM_HOME=%s", c.helmHome))
+			fmt.Sprintf("HELM_CONFIG_HOME=%s/config", c.helmHome))
 	}
 
 	if c.IsHelmOci {
diff --git a/util/helm/helm.go b/util/helm/helm.go
index baa898b2c..e997d9f61 100644
--- a/util/helm/helm.go
+++ b/util/helm/helm.go
@@ -133,7 +133,7 @@ func Version(shortForm bool) (string, error) {
 func (h *helm) GetParameters(valuesFiles []pathutil.ResolvedFilePath, appPath, repoRoot string) (map[string]string, error) {
 	var values []string
 	// Don't load values.yaml if it's an out-of-bounds link.
-	if _, _, err := pathutil.ResolveFilePath(appPath, repoRoot, "values.yaml", []string{}); err == nil {
+	if _, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, "values.yaml", []string{}); err == nil {
 		out, err := h.cmd.inspectValues(".")
 		if err != nil {
 			return nil, err
diff --git a/util/io/path/resolved.go b/util/io/path/resolved.go
index 4dedba0d5..d18df45e2 100644
--- a/util/io/path/resolved.go
+++ b/util/io/path/resolved.go
@@ -10,10 +10,14 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
-// ResolvedFilePath represents a resolved file path and intended to prevent unintentional use of not verified file path.
-// It is always either a URL or an absolute path.
+// ResolvedFilePath represents a resolved file path and is intended to prevent unintentional use of an unverified file
+// path. It is always either a URL or an absolute path.
 type ResolvedFilePath string
 
+// ResolvedFileOrDirectoryPath represents a resolved file or directory path and is intended to prevent unintentional use
+// of an unverified file or directory path. It is an absolute path.
+type ResolvedFileOrDirectoryPath string
+
 // resolveSymbolicLinkRecursive resolves the symlink path recursively to its
 // canonical path on the file system, with a maximum nesting level of maxDepth.
 // If path is not a symlink, returns the verbatim copy of path and err of nil.
@@ -60,7 +64,24 @@ func isURLSchemeAllowed(scheme string, allowed []string) bool {
 	return isAllowed && scheme != ""
 }
 
-// ResolveFilePath will inspect and resolve given file, and make sure that its final path is within the boundaries of
+// We do not provide the path in the error message, because it will be
+// returned to the user and could be used for information gathering.
+// Instead, we log the concrete error details.
+func resolveFailure(path string, err error) error {
+	log.Errorf("failed to resolve path '%s': %v", path, err)
+	return fmt.Errorf("internal error: failed to resolve path. Check logs for more details")
+}
+
+func ResolveFileOrDirectoryPath(appPath, repoRoot, dir string) (ResolvedFileOrDirectoryPath, error) {
+	path, err := resolveFileOrDirectory(appPath, repoRoot, dir, true)
+	if err != nil {
+		return "", err
+	}
+
+	return ResolvedFileOrDirectoryPath(path), nil
+}
+
+// ResolveValueFilePathOrUrl will inspect and resolve given file, and make sure that its final path is within the boundaries of
 // the path specified in repoRoot.
 //
 // appPath is the path we're operating in, e.g. where a Helm chart was unpacked
@@ -88,15 +109,7 @@ func isURLSchemeAllowed(scheme string, allowed []string) bool {
 //
 // isRemote will be set to true if valueFile is an URL using an allowed
 // protocol scheme, or to false if it resolved to a local file.
-func ResolveFilePath(appPath, repoRoot, valueFile string, allowedURLSchemes []string) (resolvedPath ResolvedFilePath, isRemote bool, err error) {
-	// We do not provide the path in the error message, because it will be
-	// returned to the user and could be used for information gathering.
-	// Instead, we log the concrete error details.
-	resolveFailure := func(path string, err error) error {
-		log.Errorf("failed to resolve path '%s': %v", path, err)
-		return fmt.Errorf("internal error: failed to resolve path. Check logs for more details")
-	}
-
+func ResolveValueFilePathOrUrl(appPath, repoRoot, valueFile string, allowedURLSchemes []string) (resolvedPath ResolvedFilePath, isRemote bool, err error) {
 	// A value file can be specified as an URL to a remote resource.
 	// We only allow certain URL schemes for remote value files.
 	url, err := url.Parse(valueFile)
@@ -111,36 +124,45 @@ func ResolveFilePath(appPath, repoRoot, valueFile string, allowedURLSchemes []st
 		}
 	}
 
+	path, err := resolveFileOrDirectory(appPath, repoRoot, valueFile, false)
+	if err != nil {
+		return "", false, err
+	}
+
+	return ResolvedFilePath(path), false, nil
+}
+
+func resolveFileOrDirectory(appPath string, repoRoot string, fileOrDirectory string, allowResolveToRoot bool) (string, error) {
 	// Ensure that our repository root is absolute
 	absRepoPath, err := filepath.Abs(repoRoot)
 	if err != nil {
-		return "", false, resolveFailure(repoRoot, err)
+		return "", resolveFailure(repoRoot, err)
 	}
 
-	// If the path to the file is relative, join it with the current working directory (appPath)
+	// If the path to the file or directory is relative, join it with the current working directory (appPath)
 	// Otherwise, join it with the repository's root
-	path := valueFile
+	path := fileOrDirectory
 	if !filepath.IsAbs(path) {
 		absWorkDir, err := filepath.Abs(appPath)
 		if err != nil {
-			return "", false, resolveFailure(repoRoot, err)
+			return "", resolveFailure(repoRoot, err)
 		}
 		path = filepath.Join(absWorkDir, path)
 	} else {
 		path = filepath.Join(absRepoPath, path)
 	}
 
-	// Ensure any symbolic link is resolved before we
+	// Ensure any symbolic link is resolved before we evaluate the path
 	delinkedPath, err := resolveSymbolicLinkRecursive(path, 10)
 	if err != nil {
-		return "", false, resolveFailure(path, err)
+		return "", resolveFailure(repoRoot, err)
 	}
 	path = delinkedPath
 
 	// Resolve the joined path to an absolute path
 	path, err = filepath.Abs(path)
 	if err != nil {
-		return "", false, resolveFailure(path, err)
+		return "", resolveFailure(repoRoot, err)
 	}
 
 	// Ensure our root path has a trailing slash, otherwise the following check
@@ -150,10 +172,17 @@ func ResolveFilePath(appPath, repoRoot, valueFile string, allowedURLSchemes []st
 		requiredRootPath += string(os.PathSeparator)
 	}
 
-	// Make sure that the resolved path to values file is within the repository's root path
-	if !strings.HasPrefix(path, requiredRootPath) {
-		return "", false, fmt.Errorf("value file '%s' resolved to outside repository root", valueFile)
+	resolvedToRoot := path+string(os.PathSeparator) == requiredRootPath
+	if resolvedToRoot {
+		if !allowResolveToRoot {
+			return "", resolveFailure(path, fmt.Errorf("path resolved to repository root, which is not allowed"))
+		}
+	} else {
+		// Make sure that the resolved path to file is within the repository's root path
+		if !strings.HasPrefix(path, requiredRootPath) {
+			return "", fmt.Errorf("file '%s' resolved to outside repository root", fileOrDirectory)
+		}
 	}
 
-	return ResolvedFilePath(path), false, nil
+	return path, nil
 }
diff --git a/util/settings/settings.go b/util/settings/settings.go
index 640503fad..80a1c6da4 100644
--- a/util/settings/settings.go
+++ b/util/settings/settings.go
@@ -108,6 +108,8 @@ type ArgoCDSettings struct {
 	// token verification to pass despite the OIDC provider having an invalid certificate. Only set to `true` if you
 	// understand the risks.
 	OIDCTLSInsecureSkipVerify bool `json:"oidcTLSInsecureSkipVerify"`
+	// AppsInAnyNamespaceEnabled indicates whether applications are allowed to be created in any namespace
+	AppsInAnyNamespaceEnabled bool `json:"appsInAnyNamespaceEnabled"`
 }
 
 type GoogleAnalytics struct {
@@ -367,6 +369,8 @@ const (
 	resourceExclusionsKey = "resource.exclusions"
 	// resourceInclusions is the key to the list of explicitly watched resources
 	resourceInclusionsKey = "resource.inclusions"
+	// resourceCustomLabelKey is the key to a custom label to show in node info, if present
+	resourceCustomLabelsKey = "resource.customLabels"
 	// configManagementPluginsKey is the key to the list of config management plugins
 	configManagementPluginsKey = "configManagementPlugins"
 	// kustomizeBuildOptionsKey is a string of kustomize build parameters
@@ -1576,7 +1580,7 @@ func (a *ArgoCDSettings) IsDexConfigured() bool {
 	}
 	dexCfg, err := UnmarshalDexConfig(a.DexConfig)
 	if err != nil {
-		log.Warn("invalid dex yaml config")
+		log.Warnf("invalid dex yaml config: %s", err.Error())
 		return false
 	}
 	return len(dexCfg) > 0
@@ -1885,3 +1889,15 @@ func (mgr *SettingsManager) GetGlobalProjectsSettings() ([]GlobalProjectSettings
 func (mgr *SettingsManager) GetNamespace() string {
 	return mgr.namespace
 }
+
+func (mgr *SettingsManager) GetResourceCustomLabels() ([]string, error) {
+	argoCDCM, err := mgr.getConfigMap()
+	if err != nil {
+		return []string{}, fmt.Errorf("failed getting configmap: %v", err)
+	}
+	labels := argoCDCM.Data[resourceCustomLabelsKey]
+	if labels != "" {
+		return strings.Split(labels, ","), nil
+	}
+	return []string{}, nil
+}


Test patch:
diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go
index 6113d4898..037af67ef 100644
--- a/controller/appcontroller_test.go
+++ b/controller/appcontroller_test.go
@@ -1068,6 +1068,34 @@ func TestUpdateReconciledAt(t *testing.T) {
 
 }
 
+func TestProjectErrorToCondition(t *testing.T) {
+	app := newFakeApp()
+	app.Spec.Project = "wrong project"
+	ctrl := newFakeController(&fakeData{
+		apps: []runtime.Object{app, &defaultProj},
+		manifestResponse: &apiclient.ManifestResponse{
+			Manifests: []string{},
+			Namespace: test.FakeDestNamespace,
+			Server:    test.FakeClusterURL,
+			Revision:  "abc123",
+		},
+		managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured),
+	})
+	key, _ := cache.MetaNamespaceKeyFunc(app)
+	ctrl.appRefreshQueue.Add(key)
+	ctrl.requestAppRefresh(app.Name, CompareWithRecent.Pointer(), nil)
+
+	ctrl.processAppRefreshQueueItem()
+
+	obj, ok, err := ctrl.appInformer.GetIndexer().GetByKey(key)
+	assert.True(t, ok)
+	assert.NoError(t, err)
+	updatedApp := obj.(*argoappv1.Application)
+	assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, updatedApp.Status.Conditions[0].Type)
+	assert.Equal(t, "Application referencing project wrong project which does not exist", updatedApp.Status.Conditions[0].Message)
+	assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, updatedApp.Status.Conditions[0].Type)
+}
+
 func TestFinalizeProjectDeletion_HasApplications(t *testing.T) {
 	app := newFakeApp()
 	proj := &argoappv1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace}}
diff --git a/controller/cache/info_test.go b/controller/cache/info_test.go
index a4b6f3147..6c9977876 100644
--- a/controller/cache/info_test.go
+++ b/controller/cache/info_test.go
@@ -271,7 +271,7 @@ func TestGetPodInfo(t *testing.T) {
 `)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(pod, info)
+	populateNodeInfo(pod, info, []string{})
 	assert.Equal(t, []v1alpha1.InfoItem{
 		{Name: "Node", Value: "minikube"},
 		{Name: "Containers", Value: "0/1"},
@@ -302,7 +302,7 @@ status:
 `)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(node, info)
+	populateNodeInfo(node, info, []string{})
 	assert.Equal(t, &NodeInfo{
 		Name:       "minikube",
 		Capacity:   v1.ResourceList{v1.ResourceMemory: resource.MustParse("6091320Ki"), v1.ResourceCPU: resource.MustParse("6")},
@@ -312,7 +312,7 @@ status:
 
 func TestGetServiceInfo(t *testing.T) {
 	info := &ResourceInfo{}
-	populateNodeInfo(testService, info)
+	populateNodeInfo(testService, info, []string{})
 	assert.Equal(t, 0, len(info.Info))
 	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
 		TargetLabels: map[string]string{"app": "guestbook"},
@@ -322,7 +322,7 @@ func TestGetServiceInfo(t *testing.T) {
 
 func TestGetLinkAnnotatedServiceInfo(t *testing.T) {
 	info := &ResourceInfo{}
-	populateNodeInfo(testLinkAnnotatedService, info)
+	populateNodeInfo(testLinkAnnotatedService, info, []string{})
 	assert.Equal(t, 0, len(info.Info))
 	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
 		TargetLabels: map[string]string{"app": "guestbook"},
@@ -333,7 +333,7 @@ func TestGetLinkAnnotatedServiceInfo(t *testing.T) {
 
 func TestGetIstioVirtualServiceInfo(t *testing.T) {
 	info := &ResourceInfo{}
-	populateNodeInfo(testIstioVirtualService, info)
+	populateNodeInfo(testIstioVirtualService, info, []string{})
 	assert.Equal(t, 0, len(info.Info))
 	require.NotNil(t, info.NetworkingInfo)
 	require.NotNil(t, info.NetworkingInfo.TargetRefs)
@@ -363,7 +363,7 @@ func TestGetIngressInfo(t *testing.T) {
 	}
 	for _, tc := range tests {
 		info := &ResourceInfo{}
-		populateNodeInfo(tc.Ingress, info)
+		populateNodeInfo(tc.Ingress, info, []string{})
 		assert.Equal(t, 0, len(info.Info))
 		sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
 			return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
@@ -388,7 +388,7 @@ func TestGetIngressInfo(t *testing.T) {
 
 func TestGetLinkAnnotatedIngressInfo(t *testing.T) {
 	info := &ResourceInfo{}
-	populateNodeInfo(testLinkAnnotatedIngress, info)
+	populateNodeInfo(testLinkAnnotatedIngress, info, []string{})
 	assert.Equal(t, 0, len(info.Info))
 	sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
 		return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
@@ -412,7 +412,7 @@ func TestGetLinkAnnotatedIngressInfo(t *testing.T) {
 
 func TestGetIngressInfoWildCardPath(t *testing.T) {
 	info := &ResourceInfo{}
-	populateNodeInfo(testIngressWildCardPath, info)
+	populateNodeInfo(testIngressWildCardPath, info, []string{})
 	assert.Equal(t, 0, len(info.Info))
 	sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
 		return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
@@ -436,7 +436,7 @@ func TestGetIngressInfoWildCardPath(t *testing.T) {
 
 func TestGetIngressInfoWithoutTls(t *testing.T) {
 	info := &ResourceInfo{}
-	populateNodeInfo(testIngressWithoutTls, info)
+	populateNodeInfo(testIngressWithoutTls, info, []string{})
 	assert.Equal(t, 0, len(info.Info))
 	sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
 		return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
@@ -481,7 +481,7 @@ func TestGetIngressInfoWithHost(t *testing.T) {
       - ip: 107.178.210.11`)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(ingress, info)
+	populateNodeInfo(ingress, info, []string{})
 
 	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
 		Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
@@ -514,7 +514,7 @@ func TestGetIngressInfoNoHost(t *testing.T) {
       `)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(ingress, info)
+	populateNodeInfo(ingress, info, []string{})
 
 	assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
 		TargetRefs: []v1alpha1.ResourceRef{{
@@ -549,7 +549,7 @@ func TestExternalUrlWithSubPath(t *testing.T) {
       - ip: 107.178.210.11`)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(ingress, info)
+	populateNodeInfo(ingress, info, []string{})
 
 	expectedExternalUrls := []string{"https://107.178.210.11/my/sub/path/"}
 	assert.Equal(t, expectedExternalUrls, info.NetworkingInfo.ExternalURLs)
@@ -585,7 +585,7 @@ func TestExternalUrlWithMultipleSubPaths(t *testing.T) {
       - ip: 107.178.210.11`)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(ingress, info)
+	populateNodeInfo(ingress, info, []string{})
 
 	expectedExternalUrls := []string{"https://helm-guestbook.com/my/sub/path/", "https://helm-guestbook.com/my/sub/path/2", "https://helm-guestbook.com"}
 	actualURLs := info.NetworkingInfo.ExternalURLs
@@ -615,7 +615,7 @@ func TestExternalUrlWithNoSubPath(t *testing.T) {
       - ip: 107.178.210.11`)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(ingress, info)
+	populateNodeInfo(ingress, info, []string{})
 
 	expectedExternalUrls := []string{"https://107.178.210.11"}
 	assert.Equal(t, expectedExternalUrls, info.NetworkingInfo.ExternalURLs)
@@ -643,8 +643,54 @@ func TestExternalUrlWithNetworkingApi(t *testing.T) {
       - ip: 107.178.210.11`)
 
 	info := &ResourceInfo{}
-	populateNodeInfo(ingress, info)
+	populateNodeInfo(ingress, info, []string{})
 
 	expectedExternalUrls := []string{"https://107.178.210.11"}
 	assert.Equal(t, expectedExternalUrls, info.NetworkingInfo.ExternalURLs)
 }
+
+func TestCustomLabel(t *testing.T) {
+	configmap := strToUnstructured(`
+  apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: cm`)
+
+	info := &ResourceInfo{}
+	populateNodeInfo(configmap, info, []string{"my-label"})
+
+	assert.Equal(t, 0, len(info.Info))
+
+	configmap = strToUnstructured(`
+  apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: cm
+    labels:
+      my-label: value`)
+
+	info = &ResourceInfo{}
+	populateNodeInfo(configmap, info, []string{"my-label", "other-label"})
+
+	assert.Equal(t, 1, len(info.Info))
+	assert.Equal(t, "my-label", info.Info[0].Name)
+	assert.Equal(t, "value", info.Info[0].Value)
+
+	configmap = strToUnstructured(`
+  apiVersion: v1
+  kind: ConfigMap
+  metadata:
+    name: cm
+    labels:
+      my-label: value
+      other-label: value2`)
+
+	info = &ResourceInfo{}
+	populateNodeInfo(configmap, info, []string{"my-label", "other-label"})
+
+	assert.Equal(t, 2, len(info.Info))
+	assert.Equal(t, "my-label", info.Info[0].Name)
+	assert.Equal(t, "value", info.Info[0].Value)
+	assert.Equal(t, "other-label", info.Info[1].Name)
+	assert.Equal(t, "value2", info.Info[1].Value)
+}
diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go
index 65acc9369..d8cbab3cd 100644
--- a/reposerver/repository/repository_test.go
+++ b/reposerver/repository/repository_test.go
@@ -342,6 +342,27 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) {
 	assert.Equal(t, 2, len(res1.Manifests))
 }
 
+func TestGenerateJsonnetManifestInRootDir(t *testing.T) {
+	service := newService("testdata/jsonnet-1")
+
+	q := apiclient.ManifestRequest{
+		Repo: &argoappv1.Repository{},
+		ApplicationSource: &argoappv1.ApplicationSource{
+			Path: ".",
+			Directory: &argoappv1.ApplicationSourceDirectory{
+				Jsonnet: argoappv1.ApplicationSourceJsonnet{
+					ExtVars: []argoappv1.JsonnetVar{{Name: "extVarString", Value: "extVarString"}, {Name: "extVarCode", Value: "\"extVarCode\"", Code: true}},
+					TLAs:    []argoappv1.JsonnetVar{{Name: "tlaString", Value: "tlaString"}, {Name: "tlaCode", Value: "\"tlaCode\"", Code: true}},
+					Libs:    []string{"."},
+				},
+			},
+		},
+	}
+	res1, err := service.GenerateManifest(context.Background(), &q)
+	assert.Nil(t, err)
+	assert.Equal(t, 2, len(res1.Manifests))
+}
+
 func TestGenerateJsonnetLibOutside(t *testing.T) {
 	service := newService(".")
 
@@ -358,7 +379,7 @@ func TestGenerateJsonnetLibOutside(t *testing.T) {
 	}
 	_, err := service.GenerateManifest(context.Background(), &q)
 	require.Error(t, err)
-	require.Contains(t, err.Error(), "value file '../../../testdata/jsonnet/vendor' resolved to outside repository root")
+	require.Contains(t, err.Error(), "file '../../../testdata/jsonnet/vendor' resolved to outside repository root")
 }
 
 func TestManifestGenErrorCacheByNumRequests(t *testing.T) {
diff --git a/reposerver/repository/testdata/jsonnet-1/guestbook-ui.jsonnet b/reposerver/repository/testdata/jsonnet-1/guestbook-ui.jsonnet
new file mode 100644
index 000000000..683dd18e5
--- /dev/null
+++ b/reposerver/repository/testdata/jsonnet-1/guestbook-ui.jsonnet
@@ -0,0 +1,47 @@
+local service = import 'vendor/nested/service.libsonnet';
+local params = import 'params.libsonnet';
+
+function(tlaString, tlaCode)
+  [
+    service.new(params),
+    {
+      apiVersion: 'apps/v1beta2',
+      kind: 'Deployment',
+      metadata: {
+        name: params.name,
+      },
+      spec: {
+        replicas: params.replicas,
+        selector: {
+          matchLabels: {
+            app: params.name,
+          },
+        },
+        template: {
+          metadata: {
+            labels: {
+              app: params.name,
+              tlaString: tlaString,
+              tlaCode: tlaCode,
+              extVarString: std.extVar('extVarString'),
+              extVarCode: std.extVar('extVarCode'),
+            },
+          },
+          spec: {
+            containers: [
+              {
+                image: params.image,
+                name: params.name,
+                ports: [
+                  {
+                    containerPort: params.containerPort,
+                  },
+                ],
+              },
+            ],
+          },
+        },
+      },
+    },
+    null,
+  ]
diff --git a/reposerver/repository/testdata/jsonnet-1/params.libsonnet b/reposerver/repository/testdata/jsonnet-1/params.libsonnet
new file mode 100644
index 000000000..ef968d6a4
--- /dev/null
+++ b/reposerver/repository/testdata/jsonnet-1/params.libsonnet
@@ -0,0 +1,8 @@
+{
+  containerPort: 80,
+  image: "gcr.io/heptio-images/ks-guestbook-demo:0.2",
+  name: "guestbook-ui",
+  replicas: 1,
+  servicePort: 80,
+  type: "ClusterIP",
+}
diff --git a/reposerver/repository/testdata/jsonnet-1/vendor/nested/service.libsonnet b/reposerver/repository/testdata/jsonnet-1/vendor/nested/service.libsonnet
new file mode 100644
index 000000000..e5da978c7
--- /dev/null
+++ b/reposerver/repository/testdata/jsonnet-1/vendor/nested/service.libsonnet
@@ -0,0 +1,23 @@
+local new(params) = {
+  apiVersion: 'v1',
+  kind: 'Service',
+  metadata: {
+    name: params.name,
+  },
+  spec: {
+    ports: [
+      {
+        port: params.servicePort,
+        targetPort: params.containerPort,
+      },
+    ],
+    selector: {
+      app: params.name,
+    },
+    type: params.type,
+  },
+};
+
+{
+  new:: new,
+}
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/health_test.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/health_test.yaml
new file mode 100644
index 000000000..3ebee0ec8
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/health_test.yaml
@@ -0,0 +1,31 @@
+tests:
+  - healthStatus:
+      status: Progressing
+      message: "Current resource status is insufficient"
+    inputPath: testdata/progressing.yaml
+  - healthStatus:
+      status: Progressing
+      message: "Current resource status is insufficient"
+    inputPath: testdata/progressing_aggregatedStatus.yaml
+  - healthStatus:
+      status: Progressing
+      message: "Current resource status is insufficient"
+    inputPath: testdata/progressing_cluster.yaml
+  - healthStatus:
+      status: Degraded
+      message: "Current resource status is unhealthy"
+    inputPath: testdata/degraded_unapplied.yaml
+  - healthStatus:
+      status: Degraded
+      message: "Current resource status is unhealthy"
+    inputPath: testdata/degraded_unknown.yaml
+  - healthStatus:
+      status: Degraded
+      message: "Current resource status is unhealthy"
+    inputPath: testdata/degraded_unhealth.yaml
+  - healthStatus:
+      status: Healthy
+    inputPath: testdata/health.yaml
+  - healthStatus:
+      status: Healthy
+    inputPath: testdata/health_unknown.yaml
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unapplied.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unapplied.yaml
new file mode 100644
index 000000000..94d73705c
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unapplied.yaml
@@ -0,0 +1,46 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters:
+    - name: member1
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: false
+      clusterName: member1
+      health: Unhealthy
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unhealth.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unhealth.yaml
new file mode 100644
index 000000000..6c39b88eb
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unhealth.yaml
@@ -0,0 +1,46 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters:
+    - name: member1
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Unhealthy
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unknown.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unknown.yaml
new file mode 100644
index 000000000..b87e39e87
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/degraded_unknown.yaml
@@ -0,0 +1,46 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters:
+    - name: member1
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: false
+      clusterName: member1
+      health: Unknown
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/health.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/health.yaml
new file mode 100644
index 000000000..9e8a87de4
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/health.yaml
@@ -0,0 +1,83 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters:
+    - name: member1
+    - name: member2
+    - name: member3
+  replicaRequirements:
+    nodeClaim:
+      tolerations:
+        - effect: NoExecute
+          key: node.kubernetes.io/not-ready
+          operator: Exists
+          tolerationSeconds: 300
+        - effect: NoExecute
+          key: node.kubernetes.io/unreachable
+          operator: Exists
+          tolerationSeconds: 300
+    resourceRequest:
+      cpu: 250m
+      memory: 512Mi
+  replicas: 1
+  resource:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: test1
+    namespace: default
+    resourceVersion: "3663243"
+    uid: 58ccb955-4da6-4167-9b65-dddadcef569e
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Healthy
+      status:
+        availableReplicas: 1
+        readyReplicas: 1
+        replicas: 1
+        updatedReplicas: 1
+    - applied: true
+      clusterName: member2
+      health: Healthy
+      status:
+        replicas: 1
+        unavailableReplicas: 1
+        updatedReplicas: 1
+    - applied: true
+      clusterName: member3
+      health: Healthy
+      status:
+        availableReplicas: 1
+        readyReplicas: 1
+        replicas: 1
+        updatedReplicas: 1
+  conditions:
+    - lastTransitionTime: "2022-11-02T02:49:06Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-10-28T09:56:31Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 7
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/health_unknown.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/health_unknown.yaml
new file mode 100644
index 000000000..4a356a9ff
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/health_unknown.yaml
@@ -0,0 +1,46 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters:
+    - name: member1
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Unknown
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing.yaml
new file mode 100644
index 000000000..8d4c5f224
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing.yaml
@@ -0,0 +1,41 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: test
+    namespace: default
+    resourceVersion: "2605059"
+    uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+status:
+  conditions:
+    - lastTransitionTime: "2022-10-27T07:19:50Z"
+      message: '0/3 clusters are available: 3 cluster(s) didn''t match the placement
+      cluster affinity constraint.'
+      reason: BindingFailedScheduling
+      status: "False"
+      type: Scheduled
+    - lastTransitionTime: "2022-10-27T07:19:52Z"
+      message: Failed to apply all works, see status.aggregatedStatus for details
+      reason: FullyAppliedFailed
+      status: "False"
+      type: FullyApplied
+  schedulerObservedGeneration: 4
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing_aggregatedStatus.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing_aggregatedStatus.yaml
new file mode 100644
index 000000000..5e7e85185
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing_aggregatedStatus.yaml
@@ -0,0 +1,46 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters:
+    - name: member1
+    - name: member2
+    - name: member3
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Healthy
+      status:
+        availableReplicas: 1
+        readyReplicas: 1
+        replicas: 1
+        updatedReplicas: 1
+  conditions:
+  - ansibleResult:
+      changed: 1
+      completion: 2020-06-08T13:41:20.133525
+      failures: 0
+      ok: 56
+      skipped: 82
+    lastTransitionTime: "2020-06-04T17:47:31Z"
+    message: Reconciling
+    reason: Running
+    status: "True"
+    type: Running
diff --git a/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing_cluster.yaml b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing_cluster.yaml
new file mode 100644
index 000000000..08d63e3a9
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ClusterResourceBinding/testdata/progressing_cluster.yaml
@@ -0,0 +1,34 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ClusterResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    clusterpropagationpolicy.karmada.io/name: service-testk4j5t
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters: []
+status:
+  conditions:
+  - ansibleResult:
+      changed: 1
+      completion: 2020-06-08T13:41:20.133525
+      failures: 0
+      ok: 56
+      skipped: 82
+    lastTransitionTime: "2020-06-04T17:47:31Z"
+    message: Reconciling
+    reason: Running
+    status: "True"
+    type: Running
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/health_test.yaml b/resource_customizations/work.karmada.io/ResourceBinding/health_test.yaml
new file mode 100644
index 000000000..3ebee0ec8
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/health_test.yaml
@@ -0,0 +1,31 @@
+tests:
+  - healthStatus:
+      status: Progressing
+      message: "Current resource status is insufficient"
+    inputPath: testdata/progressing.yaml
+  - healthStatus:
+      status: Progressing
+      message: "Current resource status is insufficient"
+    inputPath: testdata/progressing_aggregatedStatus.yaml
+  - healthStatus:
+      status: Progressing
+      message: "Current resource status is insufficient"
+    inputPath: testdata/progressing_cluster.yaml
+  - healthStatus:
+      status: Degraded
+      message: "Current resource status is unhealthy"
+    inputPath: testdata/degraded_unapplied.yaml
+  - healthStatus:
+      status: Degraded
+      message: "Current resource status is unhealthy"
+    inputPath: testdata/degraded_unknown.yaml
+  - healthStatus:
+      status: Degraded
+      message: "Current resource status is unhealthy"
+    inputPath: testdata/degraded_unhealth.yaml
+  - healthStatus:
+      status: Healthy
+    inputPath: testdata/health.yaml
+  - healthStatus:
+      status: Healthy
+    inputPath: testdata/health_unknown.yaml
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unapplied.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unapplied.yaml
new file mode 100644
index 000000000..f36b1d330
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unapplied.yaml
@@ -0,0 +1,50 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 2
+  labels:
+    propagationpolicy.karmada.io/name: service-service-testn7qfx
+    propagationpolicy.karmada.io/namespace: default
+  name: service-test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: service-test
+      uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+  resourceVersion: "3943290"
+  uid: 1459071b-e460-4038-8a5d-d2a4803ad6f1
+spec:
+  clusters:
+    - name: member1
+    - name: member2
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: false
+      clusterName: member1
+      health: Unhealthy
+    - clusterName: member2
+      health: Unhealthy
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unhealth.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unhealth.yaml
new file mode 100644
index 000000000..c4100598d
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unhealth.yaml
@@ -0,0 +1,47 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 2
+  labels:
+    propagationpolicy.karmada.io/name: service-service-testn7qfx
+    propagationpolicy.karmada.io/namespace: default
+  name: service-test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: service-test
+      uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+  resourceVersion: "3943290"
+  uid: 1459071b-e460-4038-8a5d-d2a4803ad6f1
+spec:
+  clusters:
+    - name: member1
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Unhealthy
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unknown.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unknown.yaml
new file mode 100644
index 000000000..6c447fd97
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/degraded_unknown.yaml
@@ -0,0 +1,47 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 2
+  labels:
+    propagationpolicy.karmada.io/name: service-service-testn7qfx
+    propagationpolicy.karmada.io/namespace: default
+  name: service-test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: service-test
+      uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+  resourceVersion: "3943290"
+  uid: 1459071b-e460-4038-8a5d-d2a4803ad6f1
+spec:
+  clusters:
+    - name: member1
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: false
+      clusterName: member1
+      health: Unknown
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/health.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/health.yaml
new file mode 100644
index 000000000..428cf4f1b
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/health.yaml
@@ -0,0 +1,84 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 7
+  labels:
+    propagationpolicy.karmada.io/name: test1-57dcd6489f
+    propagationpolicy.karmada.io/namespace: default
+  name: test1-deployment
+  namespace: default
+  ownerReferences:
+    - apiVersion: apps/v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Deployment
+      name: test1
+      uid: 58ccb955-4da6-4167-9b65-dddadcef569e
+  resourceVersion: "3903091"
+  uid: a46f5454-f8c5-4c9e-9119-3022aa5943b1
+spec:
+  clusters:
+    - name: member1
+    - name: member2
+    - name: member3
+  replicaRequirements:
+    nodeClaim:
+      tolerations:
+        - effect: NoExecute
+          key: node.kubernetes.io/not-ready
+          operator: Exists
+          tolerationSeconds: 300
+        - effect: NoExecute
+          key: node.kubernetes.io/unreachable
+          operator: Exists
+          tolerationSeconds: 300
+    resourceRequest:
+      cpu: 250m
+      memory: 512Mi
+  replicas: 1
+  resource:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: test1
+    namespace: default
+    resourceVersion: "3663243"
+    uid: 58ccb955-4da6-4167-9b65-dddadcef569e
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Healthy
+      status:
+        availableReplicas: 1
+        readyReplicas: 1
+        replicas: 1
+        updatedReplicas: 1
+    - applied: true
+      clusterName: member2
+      health: Healthy
+      status:
+        replicas: 1
+        unavailableReplicas: 1
+        updatedReplicas: 1
+    - applied: true
+      clusterName: member3
+      health: Healthy
+      status:
+        availableReplicas: 1
+        readyReplicas: 1
+        replicas: 1
+        updatedReplicas: 1
+  conditions:
+    - lastTransitionTime: "2022-11-02T02:49:06Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-10-28T09:56:31Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 7
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/health_unknown.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/health_unknown.yaml
new file mode 100644
index 000000000..47d18438e
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/health_unknown.yaml
@@ -0,0 +1,47 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 2
+  labels:
+    propagationpolicy.karmada.io/name: service-service-testn7qfx
+    propagationpolicy.karmada.io/namespace: default
+  name: service-test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: service-test
+      uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+  resourceVersion: "3943290"
+  uid: 1459071b-e460-4038-8a5d-d2a4803ad6f1
+spec:
+  clusters:
+    - name: member1
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: service-test
+    namespace: default
+    resourceVersion: "3943220"
+    uid: 9c2b39b9-4607-4795-87db-1a54680939d0
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Unknown
+  conditions:
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: All works have been successfully applied
+      reason: FullyAppliedSuccess
+      status: "True"
+      type: FullyApplied
+    - lastTransitionTime: "2022-11-03T10:56:30Z"
+      message: Binding has been scheduled
+      reason: BindingScheduled
+      status: "True"
+      type: Scheduled
+  schedulerObservedGeneration: 2
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing.yaml
new file mode 100644
index 000000000..5c8d8a392
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing.yaml
@@ -0,0 +1,42 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    propagationpolicy.karmada.io/name: service-testk4j5t
+    propagationpolicy.karmada.io/namespace: default
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  resource:
+    apiVersion: v1
+    kind: Service
+    name: test
+    namespace: default
+    resourceVersion: "2605059"
+    uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+status:
+  conditions:
+    - lastTransitionTime: "2022-10-27T07:19:50Z"
+      message: '0/3 clusters are available: 3 cluster(s) didn''t match the placement
+      cluster affinity constraint.'
+      reason: BindingFailedScheduling
+      status: "False"
+      type: Scheduled
+    - lastTransitionTime: "2022-10-27T07:19:52Z"
+      message: Failed to apply all works, see status.aggregatedStatus for details
+      reason: FullyAppliedFailed
+      status: "False"
+      type: FullyApplied
+  schedulerObservedGeneration: 4
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing_aggregatedStatus.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing_aggregatedStatus.yaml
new file mode 100644
index 000000000..d4ba59ca0
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing_aggregatedStatus.yaml
@@ -0,0 +1,47 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    propagationpolicy.karmada.io/name: service-testk4j5t
+    propagationpolicy.karmada.io/namespace: default
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters:
+    - name: member1
+    - name: member2
+    - name: member3
+status:
+  aggregatedStatus:
+    - applied: true
+      clusterName: member1
+      health: Healthy
+      status:
+        availableReplicas: 1
+        readyReplicas: 1
+        replicas: 1
+        updatedReplicas: 1
+  conditions:
+  - ansibleResult:
+      changed: 1
+      completion: 2020-06-08T13:41:20.133525
+      failures: 0
+      ok: 56
+      skipped: 82
+    lastTransitionTime: "2020-06-04T17:47:31Z"
+    message: Reconciling
+    reason: Running
+    status: "True"
+    type: Running
diff --git a/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing_cluster.yaml b/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing_cluster.yaml
new file mode 100644
index 000000000..0463820ba
--- /dev/null
+++ b/resource_customizations/work.karmada.io/ResourceBinding/testdata/progressing_cluster.yaml
@@ -0,0 +1,35 @@
+apiVersion: work.karmada.io/v1alpha2
+kind: ResourceBinding
+metadata:
+  finalizers:
+    - karmada.io/binding-controller
+  generation: 5
+  labels:
+    propagationpolicy.karmada.io/name: service-testk4j5t
+    propagationpolicy.karmada.io/namespace: default
+  name: test-service
+  namespace: default
+  ownerReferences:
+    - apiVersion: v1
+      blockOwnerDeletion: true
+      controller: true
+      kind: Service
+      name: test
+      uid: 039b0d1a-05cb-40b4-b43a-438b0de386af
+  resourceVersion: "4106772"
+  uid: 3932ee50-4c2b-4e77-9bfb-45eeb4ec220f
+spec:
+  clusters: []
+status:
+  conditions:
+  - ansibleResult:
+      changed: 1
+      completion: 2020-06-08T13:41:20.133525
+      failures: 0
+      ok: 56
+      skipped: 82
+    lastTransitionTime: "2020-06-04T17:47:31Z"
+    message: Reconciling
+    reason: Running
+    status: "True"
+    type: Running
diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go
index 6aad6d5cf..dec7d97b8 100644
--- a/server/cluster/cluster_test.go
+++ b/server/cluster/cluster_test.go
@@ -49,6 +49,66 @@ func newNoopEnforcer() *rbac.Enforcer {
 	return enf
 }
 
+func TestGetCluster_UrlEncodedName(t *testing.T) {
+	db := &dbmocks.ArgoDB{}
+
+	mockCluster := v1alpha1.Cluster{
+		Name:       "test/ing",
+		Server:     "https://127.0.0.1",
+		Namespaces: []string{"default", "kube-system"},
+	}
+	mockClusterList := v1alpha1.ClusterList{
+		ListMeta: v1.ListMeta{},
+		Items: []v1alpha1.Cluster{
+			mockCluster,
+		},
+	}
+
+	db.On("ListClusters", mock.Anything).Return(&mockClusterList, nil)
+
+	server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{})
+
+	cluster, err := server.Get(context.Background(), &clusterapi.ClusterQuery{
+		Id: &clusterapi.ClusterID{
+			Type:  "name_escaped",
+			Value: "test%2fing",
+		},
+	})
+	require.NoError(t, err)
+
+	assert.Equal(t, cluster.Name, "test/ing")
+}
+
+func TestGetCluster_NameWithUrlEncodingButShouldNotBeUnescaped(t *testing.T) {
+	db := &dbmocks.ArgoDB{}
+
+	mockCluster := v1alpha1.Cluster{
+		Name:       "test%2fing",
+		Server:     "https://127.0.0.1",
+		Namespaces: []string{"default", "kube-system"},
+	}
+	mockClusterList := v1alpha1.ClusterList{
+		ListMeta: v1.ListMeta{},
+		Items: []v1alpha1.Cluster{
+			mockCluster,
+		},
+	}
+
+	db.On("ListClusters", mock.Anything).Return(&mockClusterList, nil)
+
+	server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{})
+
+	cluster, err := server.Get(context.Background(), &clusterapi.ClusterQuery{
+		Id: &clusterapi.ClusterID{
+			Type:  "name",
+			Value: "test%2fing",
+		},
+	})
+	require.NoError(t, err)
+
+	assert.Equal(t, cluster.Name, "test%2fing")
+}
+
 func TestUpdateCluster_NoFieldsPaths(t *testing.T) {
 	db := &dbmocks.ArgoDB{}
 	var updated *v1alpha1.Cluster
diff --git a/util/helm/helm_test.go b/util/helm/helm_test.go
index bee3cdbdd..ab8e3bc58 100644
--- a/util/helm/helm_test.go
+++ b/util/helm/helm_test.go
@@ -59,7 +59,7 @@ func TestHelmTemplateValues(t *testing.T) {
 	require.NoError(t, err)
 	h, err := NewHelmApp(repoRootAbs, []HelmRepository{}, false, "", "", false)
 	assert.NoError(t, err)
-	valuesPath, _, err := path.ResolveFilePath(repoRootAbs, repoRootAbs, "values-production.yaml", nil)
+	valuesPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-production.yaml", nil)
 	require.NoError(t, err)
 	opts := TemplateOpts{
 		Name:   "test",
@@ -98,7 +98,7 @@ func TestHelmGetParamsValueFiles(t *testing.T) {
 	require.NoError(t, err)
 	h, err := NewHelmApp(repoRootAbs, nil, false, "", "", false)
 	assert.NoError(t, err)
-	valuesPath, _, err := path.ResolveFilePath(repoRootAbs, repoRootAbs, "values-production.yaml", nil)
+	valuesPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-production.yaml", nil)
 	require.NoError(t, err)
 	params, err := h.GetParameters([]path.ResolvedFilePath{valuesPath}, repoRootAbs, repoRootAbs)
 	assert.Nil(t, err)
@@ -113,9 +113,9 @@ func TestHelmGetParamsValueFilesThatExist(t *testing.T) {
 	require.NoError(t, err)
 	h, err := NewHelmApp(repoRootAbs, nil, false, "", "", false)
 	assert.NoError(t, err)
-	valuesMissingPath, _, err := path.ResolveFilePath(repoRootAbs, repoRootAbs, "values-missing.yaml", nil)
+	valuesMissingPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-missing.yaml", nil)
 	require.NoError(t, err)
-	valuesProductionPath, _, err := path.ResolveFilePath(repoRootAbs, repoRootAbs, "values-production.yaml", nil)
+	valuesProductionPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-production.yaml", nil)
 	require.NoError(t, err)
 	params, err := h.GetParameters([]path.ResolvedFilePath{valuesMissingPath, valuesProductionPath}, repoRootAbs, repoRootAbs)
 	assert.Nil(t, err)
diff --git a/util/io/path/resolved_test.go b/util/io/path/resolved_test.go
index fc9583377..afa7292fc 100644
--- a/util/io/path/resolved_test.go
+++ b/util/io/path/resolved_test.go
@@ -98,19 +98,19 @@ var allowedRemoteProtocols = []string{"http", "https"}
 
 func Test_resolveFilePath(t *testing.T) {
 	t.Run("Resolve normal relative path into absolute path", func(t *testing.T) {
-		p, remote, err := ResolveFilePath("/foo/bar", "/foo", "baz/bim.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", "baz/bim.yaml", allowedRemoteProtocols)
 		assert.NoError(t, err)
 		assert.False(t, remote)
 		assert.Equal(t, "/foo/bar/baz/bim.yaml", string(p))
 	})
 	t.Run("Resolve normal relative path into absolute path", func(t *testing.T) {
-		p, remote, err := ResolveFilePath("/foo/bar", "/foo", "baz/../../bim.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", "baz/../../bim.yaml", allowedRemoteProtocols)
 		assert.NoError(t, err)
 		assert.False(t, remote)
 		assert.Equal(t, "/foo/bim.yaml", string(p))
 	})
 	t.Run("Error on path resolving outside repository root", func(t *testing.T) {
-		p, remote, err := ResolveFilePath("/foo/bar", "/foo", "baz/../../../bim.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", "baz/../../../bim.yaml", allowedRemoteProtocols)
 		assert.Error(t, err)
 		assert.Contains(t, err.Error(), "outside repository root")
 		assert.False(t, remote)
@@ -118,26 +118,26 @@ func Test_resolveFilePath(t *testing.T) {
 	})
 	t.Run("Return verbatim URL", func(t *testing.T) {
 		url := "https://some.where/foo,yaml"
-		p, remote, err := ResolveFilePath("/foo/bar", "/foo", url, allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", url, allowedRemoteProtocols)
 		assert.NoError(t, err)
 		assert.True(t, remote)
 		assert.Equal(t, url, string(p))
 	})
 	t.Run("URL scheme not allowed", func(t *testing.T) {
 		url := "file:///some.where/foo,yaml"
-		p, remote, err := ResolveFilePath("/foo/bar", "/foo", url, allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", url, allowedRemoteProtocols)
 		assert.Error(t, err)
 		assert.False(t, remote)
 		assert.Equal(t, "", string(p))
 	})
 	t.Run("Implicit URL by absolute path", func(t *testing.T) {
-		p, remote, err := ResolveFilePath("/foo/bar", "/foo", "/baz.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", "/baz.yaml", allowedRemoteProtocols)
 		assert.NoError(t, err)
 		assert.False(t, remote)
 		assert.Equal(t, "/foo/baz.yaml", string(p))
 	})
 	t.Run("Relative app path", func(t *testing.T) {
-		p, remote, err := ResolveFilePath(".", "/foo", "/baz.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl(".", "/foo", "/baz.yaml", allowedRemoteProtocols)
 		assert.NoError(t, err)
 		assert.False(t, remote)
 		assert.Equal(t, "/foo/baz.yaml", string(p))
@@ -145,37 +145,42 @@ func Test_resolveFilePath(t *testing.T) {
 	t.Run("Relative repo path", func(t *testing.T) {
 		c, err := os.Getwd()
 		require.NoError(t, err)
-		p, remote, err := ResolveFilePath(".", ".", "baz.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl(".", ".", "baz.yaml", allowedRemoteProtocols)
 		assert.NoError(t, err)
 		assert.False(t, remote)
 		assert.Equal(t, c+"/baz.yaml", string(p))
 	})
 	t.Run("Overlapping root prefix without trailing slash", func(t *testing.T) {
-		p, remote, err := ResolveFilePath(".", "/foo", "../foo2/baz.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl(".", "/foo", "../foo2/baz.yaml", allowedRemoteProtocols)
 		assert.Error(t, err)
 		assert.Contains(t, err.Error(), "outside repository root")
 		assert.False(t, remote)
 		assert.Equal(t, "", string(p))
 	})
 	t.Run("Overlapping root prefix with trailing slash", func(t *testing.T) {
-		p, remote, err := ResolveFilePath(".", "/foo/", "../foo2/baz.yaml", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl(".", "/foo/", "../foo2/baz.yaml", allowedRemoteProtocols)
 		assert.Error(t, err)
 		assert.Contains(t, err.Error(), "outside repository root")
 		assert.False(t, remote)
 		assert.Equal(t, "", string(p))
 	})
 	t.Run("Garbage input as values file", func(t *testing.T) {
-		p, remote, err := ResolveFilePath(".", "/foo/", "kfdj\\ks&&&321209.,---e32908923%$§!\"", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl(".", "/foo/", "kfdj\\ks&&&321209.,---e32908923%$§!\"", allowedRemoteProtocols)
 		assert.Error(t, err)
 		assert.Contains(t, err.Error(), "outside repository root")
 		assert.False(t, remote)
 		assert.Equal(t, "", string(p))
 	})
 	t.Run("NUL-byte path input as values file", func(t *testing.T) {
-		p, remote, err := ResolveFilePath(".", "/foo/", "\000", allowedRemoteProtocols)
+		p, remote, err := ResolveValueFilePathOrUrl(".", "/foo/", "\000", allowedRemoteProtocols)
 		assert.Error(t, err)
 		assert.Contains(t, err.Error(), "outside repository root")
 		assert.False(t, remote)
 		assert.Equal(t, "", string(p))
 	})
+	t.Run("Resolve root path into absolute path - jsonnet library path", func(t *testing.T) {
+		p, err := ResolveFileOrDirectoryPath("/foo", "/foo", "./")
+		assert.NoError(t, err)
+		assert.Equal(t, "/foo", string(p))
+	})
 }