Compare commits

...

26 Commits

Author SHA1 Message Date
Ishita Sequeira
ab1d5b6f94 fix appset-in-any-namespace issue with git generators (#19553)
Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>
2024-08-15 20:06:32 +03:00
pasha-codefresh
116180b182 feat: Support context switch for argocd-util (#19549)
* feat: Support context switch for argocd-util

Signed-off-by: Atsushi Neki <nekiaiken@gmail.com>

* execute codegen

Signed-off-by: pashakostohrys <pavel@codefresh.io>

---------

Signed-off-by: Atsushi Neki <nekiaiken@gmail.com>
Signed-off-by: Dan Garfield <dan@codefresh.io>
Signed-off-by: pasha-codefresh <pavel@codefresh.io>
Signed-off-by: pashakostohrys <pavel@codefresh.io>
Co-authored-by: Atsushi Neki <nekiaiken@gmail.com>
Co-authored-by: Dan Garfield <dan@codefresh.io>
2024-08-15 11:47:58 -04:00
Jayendra Parsai
6ed7410cf6 fix: notifications triggered from CLI fails for repo functions (#19213)
Signed-off-by: Jayendra Parsai <jparsai@jparsai-thinkpadp1gen4i.remote.csb>
Co-authored-by: Jayendra Parsai <jparsai@jparsai-thinkpadp1gen4i.remote.csb>
2024-08-15 10:22:55 -04:00
dependabot[bot]
1ce5824ff4 chore(deps): bump library/registry in /test/container (#19207)
Bumps library/registry from `79b2959` to `1212042`.

---
updated-dependencies:
- dependency-name: library/registry
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 07:39:04 -04:00
Eric Lin
5a7bf2ef66 fix: selfHeal should always be respected with Multi-Source Apps #19452 (#19512)
* fix(controller): selfHeal respected in multi-source apps
when there is object change in cluster

Signed-off-by: Eric Lin <38420555+Ezzahhh@users.noreply.github.com>

* fix: tests for multi source selfheal

Signed-off-by: Ezzahhh <38420555+Ezzahhh@users.noreply.github.com>

---------

Signed-off-by: Eric Lin <38420555+Ezzahhh@users.noreply.github.com>
Signed-off-by: Ezzahhh <38420555+Ezzahhh@users.noreply.github.com>
2024-08-15 07:38:35 -04:00
Michael Crenshaw
6aa4de62c8 chore: remove unused params (#19473)
* chore: remove unused params

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* more

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

---------

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2024-08-15 07:29:51 -04:00
Michael Crenshaw
fe8dcb60fc feat(ci): upload Webpack bundle analysis to codecov (#19478) (#19479)
* feat(ci): upload Webpack bundle analysis to codecov (##19478)

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* only upload report on master branch

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

---------

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2024-08-15 07:27:44 -04:00
xcelxlorx
b2c92c7b6e chore: wrap error objets (#19511)
Signed-off-by: xcelxlorx <xcelxlorx@gmail.com>
2024-08-15 07:26:42 -04:00
dependabot[bot]
39cb06281f chore(deps): bump chromedriver from 126.0.5 to 127.0.3 in /ui-test (#19542)
Bumps [chromedriver](https://github.com/giggio/node-chromedriver) from 126.0.5 to 127.0.3.
- [Commits](https://github.com/giggio/node-chromedriver/compare/126.0.5...127.0.3)

---
updated-dependencies:
- dependency-name: chromedriver
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pasha-codefresh <pavel@codefresh.io>
2024-08-15 13:58:06 +03:00
dependabot[bot]
f7840c73b3 chore(deps-dev): bump @types/node from 22.1.0 to 22.3.0 in /ui-test (#19543)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.1.0 to 22.3.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 13:57:52 +03:00
Regina Voloshin
4835e5008a fix: Exec with disable auth not logged in #17114 (#19529)
* initial with tests

Signed-off-by: reggie-k <regina.voloshin@codefresh.io>

* refactor

Signed-off-by: reggie-k <regina.voloshin@codefresh.io>

* cleanup

Signed-off-by: reggie-k <regina.voloshin@codefresh.io>

* made TerminalOpts public and lint

Signed-off-by: reggie-k <regina.voloshin@codefresh.io>

* pass reference

Signed-off-by: reggie-k <regina.voloshin@codefresh.io>

---------

Signed-off-by: reggie-k <regina.voloshin@codefresh.io>
Co-authored-by: pasha-codefresh <pavel@codefresh.io>
2024-08-15 10:48:45 +00:00
Jessie Teng
9fc93c670a bugfix-19134: fix plugin select icon issue (#19532)
Signed-off-by: Jessie Teng <jessie.teng@fmr.com>
Co-authored-by: Jessie Teng <jessie.teng@fmr.com>
2024-08-15 12:28:22 +03:00
thisishwan2
afc2fe7172 modify ui in dark mode in source selection tag (#19482)
Signed-off-by: thisishwan2 <feel000617@gmail.com>
2024-08-15 11:10:29 +03:00
dependabot[bot]
31249489bf chore(deps): bump library/golang from 1.23rc1 to 1.23 in /test/container (#19525)
Bumps library/golang from 1.23rc1 to 1.23.

---
updated-dependencies:
- dependency-name: library/golang
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 01:56:40 +00:00
Siddhesh Ghadi
58543f3835 fix: Parse hostname correctly from repoURL to fetch correct CA cert (#19488)
Signed-off-by: Siddhesh Ghadi <sghadi1203@gmail.com>
Co-authored-by: Jann Fischer <jann@mistrust.net>
2024-08-14 20:47:59 +00:00
Adrian Berger
6296b178df feat: Add suspended status in custom resource health for flux resources (#19508)
Signed-off-by: Adrian Berger <adrian.berger@bedag.ch>
2024-08-14 14:21:29 -04:00
John
ea362766db doc(upgrading): add missing links to the sidebar (#19500)
Signed-off-by: John Malc <cincenko@outlook.com>
Signed-off-by: John <cincenko@outlook.com>
2024-08-14 10:30:08 -06:00
Ishita Sequeira
159da3c936 fix: appset gpg limitation for templated project fields (#19492)
* document templating project field while using applicationset git generator and signature verification

Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>

* revert changes to generated mocks

Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>

* Add check for templated project field and add limitation to the docs

Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>

* optimize checks and rephrase documentation

Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>

* remove unwanted variable declaration

Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>

* Add unit tests

Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>

---------

Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>
2024-08-14 10:11:31 -04:00
dependabot[bot]
7601833527 chore(deps): bump docker/build-push-action from 6.6.1 to 6.7.0 (#19523)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.6.1 to 6.7.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](16ebe778df...5cd11c3a4c)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-14 09:57:34 -04:00
dependabot[bot]
b34628db9d chore(deps): bump github.com/dlclark/regexp2 from 1.11.2 to 1.11.4 (#19526)
Bumps [github.com/dlclark/regexp2](https://github.com/dlclark/regexp2) from 1.11.2 to 1.11.4.
- [Commits](https://github.com/dlclark/regexp2/compare/v1.11.2...v1.11.4)

---
updated-dependencies:
- dependency-name: github.com/dlclark/regexp2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-14 09:47:23 -04:00
Justin Kulikauskas
d2231577c7 feat: Add open-cluster-management.io healthchecks (#19411)
Healthchecks for several Policy types.

Signed-off-by: Justin Kulikauskas <jkulikau@redhat.com>
2024-08-13 15:38:30 -04:00
ilia-medvedev-codefresh
2cb7616d51 fix: admin export and import applications and applicationsets from other namespaces (#19510)
* add support for all namespaces for apps and appsets in export and import

Signed-off-by: Ilia Medvedev <ilia.medvedev@codefresh.io>

* cleanup accidental merge issue

Signed-off-by: Ilia Medvedev <ilia.medvedev@codefresh.io>

* address comments and run lint

Signed-off-by: Ilia Medvedev <ilia.medvedev@codefresh.io>

* small fix

Signed-off-by: Ilia Medvedev <ilia.medvedev@codefresh.io>

* switch to make for slice

Signed-off-by: Ilia Medvedev <ilia.medvedev@codefresh.io>

* remove new line in command flags

Signed-off-by: Ilia Medvedev <ilia.medvedev@codefresh.io>

---------

Signed-off-by: Ilia Medvedev <ilia.medvedev@codefresh.io>
2024-08-13 17:30:00 +00:00
Arthur Vardevanyan
6dc559a3e5 fix(AnyNameSpaceRegex): Additional Functions Glob to Regexexp (#19516)
Signed-off-by: Arthur <arthur@arthurvardevanyan.com>
2024-08-13 19:14:16 +03:00
pasha-codefresh
33e0dda53c chore: add Regina Voloshin as release champion for 2.13 (#19515)
* add Regina Voloshin as release champion for 2.13

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* add Regina Voloshin as release champion for 2.13

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* add Regina Voloshin as release champion for 2.13

Signed-off-by: pashakostohrys <pavel@codefresh.io>

---------

Signed-off-by: pashakostohrys <pavel@codefresh.io>
2024-08-13 17:04:11 +03:00
Arthur Vardevanyan
588b251acc feat(sourceNamespace): Regex Support (#19016) (#19017)
* feat(sourceNamespace): Regex Support

Signed-off-by: Arthur <arthur@arthurvardevanyan.com>

* feat(sourceNamespace): Separate exactMatch into patternMatch

Signed-off-by: Arthur <arthur@arthurvardevanyan.com>

---------

Signed-off-by: Arthur <arthur@arthurvardevanyan.com>
2024-08-13 08:46:25 -04:00
Nitish Kumar
3ef05b31ff add label flag to the argocd set command (#19384)
add annotation flag to the argocd cluster set command



update the cli docs

Signed-off-by: nitishfy <justnitish06@gmail.com>
2024-08-13 11:45:38 +00:00
258 changed files with 2381 additions and 374 deletions

View File

@@ -323,6 +323,8 @@ jobs:
NODE_ENV: production
NODE_ONLINE_ENV: online
HOST_ARCH: amd64
# If we're on the master branch, set the codecov token so that we upload bundle analysis
CODECOV_TOKEN: ${{ github.ref == 'refs/heads/master' && secrets.CODECOV_TOKEN || '' }}
working-directory: ui/
- name: Run ESLint
run: yarn lint

View File

@@ -143,7 +143,7 @@ jobs:
- name: Build and push container image
id: image
uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 #v6.6.1
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 #v6.7.0
with:
context: .
platforms: ${{ inputs.platforms }}

View File

@@ -4,6 +4,10 @@ issues:
- SA5011
max-issues-per-linter: 0
max-same-issues: 0
exclude-rules:
- path: '(.+)_test\.go'
linters:
- unparam
linters:
enable:
- errcheck
@@ -17,6 +21,7 @@ linters:
- misspell
- staticcheck
- testifylint
- unparam
- unused
- whitespace
linters-settings:

View File

@@ -242,20 +242,8 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
if r.EnableProgressiveSyncs {
// trigger appropriate application syncs if RollingSync strategy is enabled
if progressiveSyncsStrategyEnabled(&applicationSetInfo, "RollingSync") {
validApps, err = r.syncValidApplications(logCtx, &applicationSetInfo, appSyncMap, appMap, validApps)
if err != nil {
_ = r.setApplicationSetStatusCondition(ctx,
&applicationSetInfo,
argov1alpha1.ApplicationSetCondition{
Type: argov1alpha1.ApplicationSetConditionErrorOccurred,
Message: err.Error(),
Reason: argov1alpha1.ApplicationSetReasonSyncApplicationError,
Status: argov1alpha1.ApplicationSetConditionStatusTrue,
}, parametersGenerated,
)
return ctrl.Result{}, err
}
if progressiveSyncsRollingSyncStrategyEnabled(&applicationSetInfo) {
validApps = r.syncValidApplications(logCtx, &applicationSetInfo, appSyncMap, appMap, validApps)
}
}
@@ -503,7 +491,7 @@ func (r *ApplicationSetReconciler) getMinRequeueAfter(applicationSetInfo *argov1
func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate {
return predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
return glob.MatchStringInList(namespaces, e.Object.GetNamespace(), false)
return glob.MatchStringInList(namespaces, e.Object.GetNamespace(), glob.REGEXP)
},
}
}
@@ -859,12 +847,9 @@ func (r *ApplicationSetReconciler) removeOwnerReferencesOnDeleteAppSet(ctx conte
}
func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, logCtx *log.Entry, appset argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, desiredApplications []argov1alpha1.Application, appMap map[string]argov1alpha1.Application) (map[string]bool, error) {
appDependencyList, appStepMap, err := r.buildAppDependencyList(logCtx, appset, desiredApplications)
if err != nil {
return nil, fmt.Errorf("failed to build app dependency list: %w", err)
}
appDependencyList, appStepMap := r.buildAppDependencyList(logCtx, appset, desiredApplications)
_, err = r.updateApplicationSetApplicationStatus(ctx, logCtx, &appset, applications, appStepMap)
_, err := r.updateApplicationSetApplicationStatus(ctx, logCtx, &appset, applications, appStepMap)
if err != nil {
return nil, fmt.Errorf("failed to update applicationset app status: %w", err)
}
@@ -874,34 +859,27 @@ func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context,
logCtx.Infof("step %v: %+v", i+1, step)
}
appSyncMap, err := r.buildAppSyncMap(ctx, appset, appDependencyList, appMap)
if err != nil {
return nil, fmt.Errorf("failed to build app sync map: %w", err)
}
appSyncMap := r.buildAppSyncMap(appset, appDependencyList, appMap)
logCtx.Infof("Application allowed to sync before maxUpdate?: %+v", appSyncMap)
_, err = r.updateApplicationSetApplicationStatusProgress(ctx, logCtx, &appset, appSyncMap, appStepMap, appMap)
_, err = r.updateApplicationSetApplicationStatusProgress(ctx, logCtx, &appset, appSyncMap, appStepMap)
if err != nil {
return nil, fmt.Errorf("failed to update applicationset application status progress: %w", err)
}
_, err = r.updateApplicationSetApplicationStatusConditions(ctx, &appset)
if err != nil {
return nil, fmt.Errorf("failed to update applicationset application status conditions: %w", err)
}
_ = r.updateApplicationSetApplicationStatusConditions(ctx, &appset)
return appSyncMap, nil
}
// this list tracks which Applications belong to each RollingUpdate step
func (r *ApplicationSetReconciler) buildAppDependencyList(logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, applications []argov1alpha1.Application) ([][]string, map[string]int, error) {
func (r *ApplicationSetReconciler) buildAppDependencyList(logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, applications []argov1alpha1.Application) ([][]string, map[string]int) {
if applicationSet.Spec.Strategy == nil || applicationSet.Spec.Strategy.Type == "" || applicationSet.Spec.Strategy.Type == "AllAtOnce" {
return [][]string{}, map[string]int{}, nil
return [][]string{}, map[string]int{}
}
steps := []argov1alpha1.ApplicationSetRolloutStep{}
if progressiveSyncsStrategyEnabled(&applicationSet, "RollingSync") {
if progressiveSyncsRollingSyncStrategyEnabled(&applicationSet) {
steps = applicationSet.Spec.Strategy.RollingSync.Steps
}
@@ -942,7 +920,7 @@ func (r *ApplicationSetReconciler) buildAppDependencyList(logCtx *log.Entry, app
}
}
return appDependencyList, appStepMap, nil
return appDependencyList, appStepMap
}
func labelMatchedExpression(logCtx *log.Entry, val string, matchExpression argov1alpha1.ApplicationMatchExpression) bool {
@@ -966,7 +944,7 @@ func labelMatchedExpression(logCtx *log.Entry, val string, matchExpression argov
}
// this map is used to determine which stage of Applications are ready to be updated in the reconciler loop
func (r *ApplicationSetReconciler) buildAppSyncMap(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, appDependencyList [][]string, appMap map[string]argov1alpha1.Application) (map[string]bool, error) {
func (r *ApplicationSetReconciler) buildAppSyncMap(applicationSet argov1alpha1.ApplicationSet, appDependencyList [][]string, appMap map[string]argov1alpha1.Application) map[string]bool {
appSyncMap := map[string]bool{}
syncEnabled := true
@@ -1003,11 +981,11 @@ func (r *ApplicationSetReconciler) buildAppSyncMap(ctx context.Context, applicat
}
}
return appSyncMap, nil
return appSyncMap
}
func appSyncEnabledForNextStep(appset *argov1alpha1.ApplicationSet, app argov1alpha1.Application, appStatus argov1alpha1.ApplicationSetApplicationStatus) bool {
if progressiveSyncsStrategyEnabled(appset, "RollingSync") {
if progressiveSyncsRollingSyncStrategyEnabled(appset) {
// we still need to complete the current step if the Application is not yet Healthy or there are still pending Application changes
return isApplicationHealthy(app) && appStatus.Status == "Healthy"
}
@@ -1015,16 +993,8 @@ func appSyncEnabledForNextStep(appset *argov1alpha1.ApplicationSet, app argov1al
return true
}
func progressiveSyncsStrategyEnabled(appset *argov1alpha1.ApplicationSet, strategyType string) bool {
if appset.Spec.Strategy == nil || appset.Spec.Strategy.Type != strategyType {
return false
}
if strategyType == "RollingSync" && appset.Spec.Strategy.RollingSync == nil {
return false
}
return true
func progressiveSyncsRollingSyncStrategyEnabled(appset *argov1alpha1.ApplicationSet) bool {
return appset.Spec.Strategy != nil && appset.Spec.Strategy.RollingSync != nil && appset.Spec.Strategy.Type == "RollingSync"
}
func isApplicationHealthy(app argov1alpha1.Application) bool {
@@ -1082,7 +1052,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con
}
appOutdated := false
if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") {
if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) {
appOutdated = syncStatusString == "OutOfSync"
}
@@ -1148,7 +1118,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con
}
// check Applications that are in Waiting status and promote them to Pending if needed
func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appStepMap map[string]int, appMap map[string]argov1alpha1.Application) ([]argov1alpha1.ApplicationSetApplicationStatus, error) {
func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appStepMap map[string]int) ([]argov1alpha1.ApplicationSetApplicationStatus, error) {
now := metav1.Now()
appStatuses := make([]argov1alpha1.ApplicationSetApplicationStatus, 0, len(applicationSet.Status.ApplicationStatus))
@@ -1159,7 +1129,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress
totalCountMap := []int{}
length := 0
if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") {
if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) {
length = len(applicationSet.Spec.Strategy.RollingSync.Steps)
}
for s := 0; s < length; s++ {
@@ -1171,7 +1141,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress
for _, appStatus := range applicationSet.Status.ApplicationStatus {
totalCountMap[appStepMap[appStatus.Application]] += 1
if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") {
if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) {
if appStatus.Status == "Pending" || appStatus.Status == "Progressing" {
updateCountMap[appStepMap[appStatus.Application]] += 1
}
@@ -1181,7 +1151,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress
for _, appStatus := range applicationSet.Status.ApplicationStatus {
maxUpdateAllowed := true
maxUpdate := &intstr.IntOrString{}
if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") {
if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) {
maxUpdate = applicationSet.Spec.Strategy.RollingSync.Steps[appStepMap[appStatus.Application]].MaxUpdate
}
@@ -1225,7 +1195,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress
return appStatuses, nil
}
func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusConditions(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet) ([]argov1alpha1.ApplicationSetCondition, error) {
func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusConditions(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet) []argov1alpha1.ApplicationSetCondition {
appSetProgressing := false
for _, appStatus := range applicationSet.Status.ApplicationStatus {
if appStatus.Status != "Healthy" {
@@ -1264,7 +1234,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusConditio
)
}
return applicationSet.Status.Conditions, nil
return applicationSet.Status.Conditions
}
func findApplicationStatusIndex(appStatuses []argov1alpha1.ApplicationSetApplicationStatus, application string) int {
@@ -1374,7 +1344,7 @@ func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Contex
return nil
}
func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appMap map[string]argov1alpha1.Application, validApps []argov1alpha1.Application) ([]argov1alpha1.Application, error) {
func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appMap map[string]argov1alpha1.Application, validApps []argov1alpha1.Application) []argov1alpha1.Application {
rolloutApps := []argov1alpha1.Application{}
for i := range validApps {
pruneEnabled := false
@@ -1395,15 +1365,15 @@ func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, appl
// check appSyncMap to determine which Applications are ready to be updated and which should be skipped
if appSyncMap[validApps[i].Name] && appMap[validApps[i].Name].Status.Sync.Status == "OutOfSync" && appSetStatusPending {
logCtx.Infof("triggering sync for application: %v, prune enabled: %v", validApps[i].Name, pruneEnabled)
validApps[i], _ = syncApplication(validApps[i], pruneEnabled)
validApps[i] = syncApplication(validApps[i], pruneEnabled)
}
rolloutApps = append(rolloutApps, validApps[i])
}
return rolloutApps, nil
return rolloutApps
}
// used by the RollingSync Progressive Sync strategy to trigger a sync of a particular Application resource
func syncApplication(application argov1alpha1.Application, prune bool) (argov1alpha1.Application, error) {
func syncApplication(application argov1alpha1.Application, prune bool) argov1alpha1.Application {
operation := argov1alpha1.Operation{
InitiatedBy: argov1alpha1.OperationInitiator{
Username: "applicationset-controller",
@@ -1429,7 +1399,7 @@ func syncApplication(application argov1alpha1.Application, prune bool) (argov1al
}
application.Operation = &operation
return application, nil
return application
}
func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs {

View File

@@ -3666,8 +3666,7 @@ func TestBuildAppDependencyList(t *testing.T) {
KubeClientset: kubeclientset,
}
appDependencyList, appStepMap, err := r.buildAppDependencyList(log.NewEntry(log.StandardLogger()), cc.appSet, cc.apps)
require.NoError(t, err, "expected no errors, but errors occurred")
appDependencyList, appStepMap := r.buildAppDependencyList(log.NewEntry(log.StandardLogger()), cc.appSet, cc.apps)
assert.Equal(t, cc.expectedList, appDependencyList, "expected appDependencyList did not match actual")
assert.Equal(t, cc.expectedStepMap, appStepMap, "expected appStepMap did not match actual")
})
@@ -4257,8 +4256,7 @@ func TestBuildAppSyncMap(t *testing.T) {
KubeClientset: kubeclientset,
}
appSyncMap, err := r.buildAppSyncMap(context.TODO(), cc.appSet, cc.appDependencyList, cc.appMap)
require.NoError(t, err, "expected no errors, but errors occurred")
appSyncMap := r.buildAppSyncMap(cc.appSet, cc.appDependencyList, cc.appMap)
assert.Equal(t, cc.expectedMap, appSyncMap, "expected appSyncMap did not match actual")
})
}
@@ -5800,7 +5798,7 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) {
KubeClientset: kubeclientset,
}
appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap, cc.appMap)
appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap)
// opt out of testing the LastTransitionTime is accurate
for i := range appStatuses {

View File

@@ -60,7 +60,7 @@ func TestRequeueAfter(t *testing.T) {
terminalGenerators := map[string]generators.Generator{
"List": generators.NewListGenerator(),
"Clusters": generators.NewClusterGenerator(k8sClient, ctx, appClientset, "argocd"),
"Git": generators.NewGitGenerator(mockServer),
"Git": generators.NewGitGenerator(mockServer, "namespace"),
"SCMProvider": generators.NewSCMProviderGenerator(fake.NewClientBuilder().WithObjects(&corev1.Secret{}).Build(), scmConfig),
"ClusterDecisionResource": generators.NewDuckTypeGenerator(ctx, fakeDynClient, appClientset, "argocd"),
"PullRequest": generators.NewPullRequestGenerator(k8sClient, scmConfig),

View File

@@ -346,7 +346,7 @@ func getMockClusterGenerator() Generator {
func getMockGitGenerator() Generator {
argoCDServiceMock := mocks.Repos{}
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything).Return([]string{"app1", "app2", "app_3", "p1/app4"}, nil)
gitGenerator := NewGitGenerator(&argoCDServiceMock)
gitGenerator := NewGitGenerator(&argoCDServiceMock, "namespace")
return gitGenerator
}

View File

@@ -24,13 +24,16 @@ import (
var _ Generator = (*GitGenerator)(nil)
type GitGenerator struct {
repos services.Repos
repos services.Repos
namespace string
}
func NewGitGenerator(repos services.Repos) Generator {
func NewGitGenerator(repos services.Repos, namespace string) Generator {
g := &GitGenerator{
repos: repos,
repos: repos,
namespace: namespace,
}
return g
}
@@ -59,21 +62,25 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic
noRevisionCache := appSet.RefreshRequired()
var project string
if strings.Contains(appSet.Spec.Template.Spec.Project, "{{") {
project = appSetGenerator.Git.Template.Spec.Project
} else {
project = appSet.Spec.Template.Spec.Project
}
verifyCommit := false
appProject := &argoprojiov1alpha1.AppProject{}
if err := client.Get(context.TODO(), types.NamespacedName{Name: appSet.Spec.Template.Spec.Project, Namespace: appSet.Namespace}, appProject); err != nil {
return nil, fmt.Errorf("error getting project %s: %w", project, err)
// When the project field is templated, the contents of the git repo are required to run the git generator and get the templated value,
// but git generator cannot be called without verifying the commit signature.
// In this case, we skip the signature verification.
if !strings.Contains(appSet.Spec.Template.Spec.Project, "{{") {
project := appSet.Spec.Template.Spec.Project
appProject := &argoprojiov1alpha1.AppProject{}
namespace := g.namespace
if namespace == "" {
namespace = appSet.Namespace
}
if err := client.Get(context.TODO(), types.NamespacedName{Name: project, Namespace: namespace}, appProject); err != nil {
return nil, fmt.Errorf("error getting project %s: %w", project, err)
}
// we need to verify the signature on the Git revision if GPG is enabled
verifyCommit = appProject.Spec.SignatureKeys != nil && len(appProject.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled()
}
// we need to verify the signature on the Git revision if GPG is enabled
verifyCommit := appProject.Spec.SignatureKeys != nil && len(appProject.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled()
var err error
var res []map[string]interface{}
if len(appSetGenerator.Git.Directories) != 0 {

View File

@@ -323,7 +323,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError)
gitGenerator := NewGitGenerator(&argoCDServiceMock)
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
@@ -624,7 +624,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) {
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError)
gitGenerator := NewGitGenerator(&argoCDServiceMock)
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
@@ -989,7 +989,7 @@ cluster:
argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError)
gitGenerator := NewGitGenerator(&argoCDServiceMock)
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
@@ -1345,7 +1345,7 @@ cluster:
argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError)
gitGenerator := NewGitGenerator(&argoCDServiceMock)
gitGenerator := NewGitGenerator(&argoCDServiceMock, "")
applicationSetInfo := argoprojiov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
@@ -1383,3 +1383,114 @@ cluster:
})
}
}
func TestGitGenerator_GenerateParams(t *testing.T) {
cases := []struct {
name string
directories []argoprojiov1alpha1.GitDirectoryGeneratorItem
pathParamPrefix string
repoApps []string
repoPathsError error
repoFileContents map[string][]byte
values map[string]string
expected []map[string]interface{}
expectedError error
appset argoprojiov1alpha1.ApplicationSet
callGetDirectories bool
}{
{
name: "Signature Verification - ignores templated project field",
repoApps: []string{
"app1",
},
repoPathsError: nil,
appset: argoprojiov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
Namespace: "namespace",
},
Spec: argoprojiov1alpha1.ApplicationSetSpec{
Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{
Git: &argoprojiov1alpha1.GitGenerator{
RepoURL: "RepoURL",
Revision: "Revision",
Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}},
PathParamPrefix: "",
Values: map[string]string{
"foo": "bar",
},
},
}},
Template: argoprojiov1alpha1.ApplicationSetTemplate{
Spec: argoprojiov1alpha1.ApplicationSpec{
Project: "{{.project}}",
},
},
},
},
callGetDirectories: true,
expected: []map[string]interface{}{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}},
expectedError: nil,
},
{
name: "Signature Verification - Checks for non-templated project field",
repoApps: []string{
"app1",
},
repoPathsError: nil,
appset: argoprojiov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
Namespace: "namespace",
},
Spec: argoprojiov1alpha1.ApplicationSetSpec{
Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{
Git: &argoprojiov1alpha1.GitGenerator{
RepoURL: "RepoURL",
Revision: "Revision",
Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}},
PathParamPrefix: "",
Values: map[string]string{
"foo": "bar",
},
},
}},
Template: argoprojiov1alpha1.ApplicationSetTemplate{
Spec: argoprojiov1alpha1.ApplicationSpec{
Project: "project",
},
},
},
},
callGetDirectories: false,
expected: []map[string]interface{}{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}},
expectedError: fmt.Errorf("error getting project project: appprojects.argoproj.io \"project\" not found"),
},
}
for _, testCase := range cases {
argoCDServiceMock := mocks.Repos{}
if testCase.callGetDirectories {
argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCase.repoApps, testCase.repoPathsError)
}
gitGenerator := NewGitGenerator(&argoCDServiceMock, "namespace")
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
appProject := argoprojiov1alpha1.AppProject{}
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build()
got, err := gitGenerator.GenerateParams(&testCase.appset.Spec.Generators[0], &testCase.appset, client)
if testCase.expectedError != nil {
require.EqualError(t, err, testCase.expectedError.Error())
} else {
require.NoError(t, err)
assert.Equal(t, testCase.expected, got)
}
argoCDServiceMock.AssertExpectations(t)
}
}

View File

@@ -1089,7 +1089,7 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) {
repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{
"some/path.json": []byte("test: content"),
}, nil)
gitGenerator := NewGitGenerator(repoServiceMock)
gitGenerator := NewGitGenerator(repoServiceMock, "")
matrixGenerator := NewMatrixGenerator(map[string]Generator{
"List": listGeneratorMock,

View File

@@ -14,7 +14,7 @@ func GetGenerators(ctx context.Context, c client.Client, k8sClient kubernetes.In
terminalGenerators := map[string]Generator{
"List": NewListGenerator(),
"Clusters": NewClusterGenerator(c, ctx, k8sClient, namespace),
"Git": NewGitGenerator(argoCDService),
"Git": NewGitGenerator(argoCDService, namespace),
"SCMProvider": NewSCMProviderGenerator(c, scmConfig),
"ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, namespace),
"PullRequest": NewPullRequestGenerator(c, scmConfig),

View File

@@ -1,10 +1,13 @@
package admin
import (
"context"
"reflect"
"strings"
"github.com/spf13/cobra"
apiv1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -83,11 +86,12 @@ func newArgoCDClientsets(config *rest.Config, namespace string) *argoCDClientset
dynamicIf, err := dynamic.NewForConfig(config)
errors.CheckError(err)
return &argoCDClientsets{
configMaps: dynamicIf.Resource(configMapResource).Namespace(namespace),
secrets: dynamicIf.Resource(secretResource).Namespace(namespace),
applications: dynamicIf.Resource(applicationsResource).Namespace(namespace),
configMaps: dynamicIf.Resource(configMapResource).Namespace(namespace),
secrets: dynamicIf.Resource(secretResource).Namespace(namespace),
// To support applications and applicationsets in any namespace we will watch all namespaces and filter them afterwards
applications: dynamicIf.Resource(applicationsResource),
projects: dynamicIf.Resource(appprojectsResource).Namespace(namespace),
applicationSets: dynamicIf.Resource(appplicationSetResource).Namespace(namespace),
applicationSets: dynamicIf.Resource(appplicationSetResource),
}
}
@@ -218,3 +222,52 @@ func specsEqual(left, right unstructured.Unstructured) bool {
}
return false
}
type argocdAdditonalNamespaces struct {
applicationNamespaces []string
applicationsetNamespaces []string
}
const (
applicationsetNamespacesCmdParamsKey = "applicationsetcontroller.namespaces"
applicationNamespacesCmdParamsKey = "application.namespaces"
)
// Get additional namespaces from argocd-cmd-params
func getAdditionalNamespaces(ctx context.Context, argocdClientsets *argoCDClientsets) *argocdAdditonalNamespaces {
applicationNamespaces := make([]string, 0)
applicationsetNamespaces := make([]string, 0)
un, err := argocdClientsets.configMaps.Get(ctx, common.ArgoCDCmdParamsConfigMapName, v1.GetOptions{})
errors.CheckError(err)
var cm apiv1.ConfigMap
err = runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &cm)
errors.CheckError(err)
namespacesListFromString := func(namespaces string) []string {
listOfNamespaces := []string{}
ss := strings.Split(namespaces, ",")
for _, namespace := range ss {
if namespace != "" {
listOfNamespaces = append(listOfNamespaces, strings.TrimSpace(namespace))
}
}
return listOfNamespaces
}
if strNamespaces, ok := cm.Data[applicationNamespacesCmdParamsKey]; ok {
applicationNamespaces = namespacesListFromString(strNamespaces)
}
if strNamespaces, ok := cm.Data[applicationsetNamespacesCmdParamsKey]; ok {
applicationsetNamespaces = namespacesListFromString(strNamespaces)
}
return &argocdAdditonalNamespaces{
applicationNamespaces: applicationNamespaces,
applicationsetNamespaces: applicationsetNamespaces,
}
}

View File

@@ -0,0 +1,75 @@
package admin
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
dynfake "k8s.io/client-go/dynamic/fake"
)
func TestGetAdditionalNamespaces(t *testing.T) {
createArgoCDCmdCMWithKeys := func(data map[string]interface{}) *unstructured.Unstructured {
return &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "argocd-cmd-params-cm",
"namespace": "argocd",
},
"data": data,
},
}
}
testCases := []struct {
CmdParamsKeys map[string]interface{}
expected argocdAdditonalNamespaces
description string
}{
{
description: "empty configmap should return no additional namespaces",
CmdParamsKeys: map[string]interface{}{},
expected: argocdAdditonalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{}},
},
{
description: "empty strings in respective keys in cm shoud return empty namespace list",
CmdParamsKeys: map[string]interface{}{applicationsetNamespacesCmdParamsKey: "", applicationNamespacesCmdParamsKey: ""},
expected: argocdAdditonalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{}},
},
{
description: "when only one of the keys in the cm is set only correct respective list of namespaces should be returned",
CmdParamsKeys: map[string]interface{}{applicationNamespacesCmdParamsKey: "foo, bar*"},
expected: argocdAdditonalNamespaces{applicationsetNamespaces: []string{}, applicationNamespaces: []string{"foo", "bar*"}},
},
{
description: "when only one of the keys in the cm is set only correct respective list of namespaces should be returned",
CmdParamsKeys: map[string]interface{}{applicationsetNamespacesCmdParamsKey: "foo, bar*"},
expected: argocdAdditonalNamespaces{applicationNamespaces: []string{}, applicationsetNamespaces: []string{"foo", "bar*"}},
},
{
description: "whitespaces are removed for both multiple and single namespace",
CmdParamsKeys: map[string]interface{}{applicationNamespacesCmdParamsKey: " bar ", applicationsetNamespacesCmdParamsKey: " foo , bar* "},
expected: argocdAdditonalNamespaces{applicationNamespaces: []string{"bar"}, applicationsetNamespaces: []string{"foo", "bar*"}},
},
}
for _, c := range testCases {
fakeDynClient := dynfake.NewSimpleDynamicClient(runtime.NewScheme(), createArgoCDCmdCMWithKeys(c.CmdParamsKeys))
argoCDClientsets := &argoCDClientsets{
configMaps: fakeDynClient.Resource(configMapResource).Namespace("argocd"),
applications: fakeDynClient.Resource(schema.GroupVersionResource{}),
applicationSets: fakeDynClient.Resource(schema.GroupVersionResource{}),
secrets: fakeDynClient.Resource(schema.GroupVersionResource{}),
projects: fakeDynClient.Resource(schema.GroupVersionResource{}),
}
result := getAdditionalNamespaces(context.TODO(), argoCDClientsets)
assert.Equal(t, c.expected, *result)
}
}

View File

@@ -20,13 +20,16 @@ import (
"github.com/argoproj/argo-cd/v2/pkg/apis/application"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/errors"
secutil "github.com/argoproj/argo-cd/v2/util/security"
)
// NewExportCommand defines a new command for exporting Kubernetes and Argo CD resources.
func NewExportCommand() *cobra.Command {
var (
clientConfig clientcmd.ClientConfig
out string
clientConfig clientcmd.ClientConfig
out string
applicationNamespaces []string
applicationsetNamespaces []string
)
command := cobra.Command{
Use: "export",
@@ -58,34 +61,47 @@ func NewExportCommand() *cobra.Command {
acdClients := newArgoCDClientsets(config, namespace)
acdConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDConfigMapName, v1.GetOptions{})
errors.CheckError(err)
export(writer, *acdConfigMap)
export(writer, *acdConfigMap, namespace)
acdRBACConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDRBACConfigMapName, v1.GetOptions{})
errors.CheckError(err)
export(writer, *acdRBACConfigMap)
export(writer, *acdRBACConfigMap, namespace)
acdKnownHostsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDKnownHostsConfigMapName, v1.GetOptions{})
errors.CheckError(err)
export(writer, *acdKnownHostsConfigMap)
export(writer, *acdKnownHostsConfigMap, namespace)
acdTLSCertsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDTLSCertsConfigMapName, v1.GetOptions{})
errors.CheckError(err)
export(writer, *acdTLSCertsConfigMap)
export(writer, *acdTLSCertsConfigMap, namespace)
referencedSecrets := getReferencedSecrets(*acdConfigMap)
secrets, err := acdClients.secrets.List(ctx, v1.ListOptions{})
errors.CheckError(err)
for _, secret := range secrets.Items {
if isArgoCDSecret(referencedSecrets, secret) {
export(writer, secret)
export(writer, secret, namespace)
}
}
projects, err := acdClients.projects.List(ctx, v1.ListOptions{})
errors.CheckError(err)
for _, proj := range projects.Items {
export(writer, proj)
export(writer, proj, namespace)
}
additionalNamespaces := getAdditionalNamespaces(ctx, acdClients)
if len(applicationNamespaces) == 0 {
applicationNamespaces = additionalNamespaces.applicationNamespaces
}
if len(applicationsetNamespaces) == 0 {
applicationsetNamespaces = additionalNamespaces.applicationsetNamespaces
}
applications, err := acdClients.applications.List(ctx, v1.ListOptions{})
errors.CheckError(err)
for _, app := range applications.Items {
export(writer, app)
// Export application only if it is in one of the enabled namespaces
if secutil.IsNamespaceEnabled(app.GetNamespace(), namespace, applicationNamespaces) {
export(writer, app, namespace)
}
}
applicationSets, err := acdClients.applicationSets.List(ctx, v1.ListOptions{})
if err != nil && !apierr.IsNotFound(err) {
@@ -97,7 +113,9 @@ func NewExportCommand() *cobra.Command {
}
if applicationSets != nil {
for _, appSet := range applicationSets.Items {
export(writer, appSet)
if secutil.IsNamespaceEnabled(appSet.GetNamespace(), namespace, applicationsetNamespaces) {
export(writer, appSet, namespace)
}
}
}
},
@@ -105,18 +123,21 @@ func NewExportCommand() *cobra.Command {
clientConfig = cli.AddKubectlFlagsToCmd(&command)
command.Flags().StringVarP(&out, "out", "o", "-", "Output to the specified file instead of stdout")
command.Flags().StringSliceVarP(&applicationNamespaces, "application-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to export applications from. If not provided value from '%s' in %s will be used,if it's not defined only applications from Argo CD namespace will be exported", applicationNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName))
command.Flags().StringSliceVarP(&applicationsetNamespaces, "applicationset-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to export applicationsets from. If not provided value from '%s' in %s will be used,if it's not defined only applicationsets from Argo CD namespace will be exported", applicationsetNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName))
return &command
}
// NewImportCommand defines a new command for exporting Kubernetes and Argo CD resources.
func NewImportCommand() *cobra.Command {
var (
clientConfig clientcmd.ClientConfig
prune bool
dryRun bool
verbose bool
stopOperation bool
clientConfig clientcmd.ClientConfig
prune bool
dryRun bool
verbose bool
stopOperation bool
applicationNamespaces []string
applicationsetNamespaces []string
)
command := cobra.Command{
Use: "import SOURCE",
@@ -135,6 +156,8 @@ func NewImportCommand() *cobra.Command {
namespace, _, err := clientConfig.Namespace()
errors.CheckError(err)
acdClients := newArgoCDClientsets(config, namespace)
client, err := dynamic.NewForConfig(config)
errors.CheckError(err)
var input []byte
if in := args[0]; in == "-" {
@@ -148,6 +171,15 @@ func NewImportCommand() *cobra.Command {
dryRunMsg = " (dry run)"
}
additionalNamespaces := getAdditionalNamespaces(ctx, acdClients)
if len(applicationNamespaces) == 0 {
applicationNamespaces = additionalNamespaces.applicationNamespaces
}
if len(applicationsetNamespaces) == 0 {
applicationsetNamespaces = additionalNamespaces.applicationsetNamespaces
}
// pruneObjects tracks live objects and it's current resource version. any remaining
// items in this map indicates the resource should be pruned since it no longer appears
// in the backup
@@ -159,7 +191,7 @@ func NewImportCommand() *cobra.Command {
var referencedSecrets map[string]bool
for _, cm := range configMaps.Items {
if isArgoCDConfigMap(cm.GetName()) {
pruneObjects[kube.ResourceKey{Group: "", Kind: "ConfigMap", Name: cm.GetName()}] = cm
pruneObjects[kube.ResourceKey{Group: "", Kind: "ConfigMap", Name: cm.GetName(), Namespace: cm.GetNamespace()}] = cm
}
if cm.GetName() == common.ArgoCDConfigMapName {
referencedSecrets = getReferencedSecrets(cm)
@@ -170,18 +202,20 @@ func NewImportCommand() *cobra.Command {
errors.CheckError(err)
for _, secret := range secrets.Items {
if isArgoCDSecret(referencedSecrets, secret) {
pruneObjects[kube.ResourceKey{Group: "", Kind: "Secret", Name: secret.GetName()}] = secret
pruneObjects[kube.ResourceKey{Group: "", Kind: "Secret", Name: secret.GetName(), Namespace: secret.GetNamespace()}] = secret
}
}
applications, err := acdClients.applications.List(ctx, v1.ListOptions{})
errors.CheckError(err)
for _, app := range applications.Items {
pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationKind, Name: app.GetName()}] = app
if secutil.IsNamespaceEnabled(app.GetNamespace(), namespace, applicationNamespaces) {
pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationKind, Name: app.GetName(), Namespace: app.GetNamespace()}] = app
}
}
projects, err := acdClients.projects.List(ctx, v1.ListOptions{})
errors.CheckError(err)
for _, proj := range projects.Items {
pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.AppProjectKind, Name: proj.GetName()}] = proj
pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.AppProjectKind, Name: proj.GetName(), Namespace: proj.GetNamespace()}] = proj
}
applicationSets, err := acdClients.applicationSets.List(ctx, v1.ListOptions{})
if apierr.IsForbidden(err) || apierr.IsNotFound(err) {
@@ -191,7 +225,9 @@ func NewImportCommand() *cobra.Command {
}
if applicationSets != nil {
for _, appSet := range applicationSets.Items {
pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationSetKind, Name: appSet.GetName()}] = appSet
if secutil.IsNamespaceEnabled(appSet.GetNamespace(), namespace, applicationsetNamespaces) {
pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationSetKind, Name: appSet.GetName(), Namespace: appSet.GetNamespace()}] = appSet
}
}
}
@@ -200,21 +236,33 @@ func NewImportCommand() *cobra.Command {
errors.CheckError(err)
for _, bakObj := range backupObjects {
gvk := bakObj.GroupVersionKind()
key := kube.ResourceKey{Group: gvk.Group, Kind: gvk.Kind, Name: bakObj.GetName()}
// For objects without namespace, assume they belong in ArgoCD namespace
if bakObj.GetNamespace() == "" {
bakObj.SetNamespace(namespace)
}
key := kube.ResourceKey{Group: gvk.Group, Kind: gvk.Kind, Name: bakObj.GetName(), Namespace: bakObj.GetNamespace()}
liveObj, exists := pruneObjects[key]
delete(pruneObjects, key)
var dynClient dynamic.ResourceInterface
switch bakObj.GetKind() {
case "Secret":
dynClient = acdClients.secrets
dynClient = client.Resource(secretResource).Namespace(bakObj.GetNamespace())
case "ConfigMap":
dynClient = acdClients.configMaps
dynClient = client.Resource(configMapResource).Namespace(bakObj.GetNamespace())
case application.AppProjectKind:
dynClient = acdClients.projects
dynClient = client.Resource(appprojectsResource).Namespace(bakObj.GetNamespace())
case application.ApplicationKind:
dynClient = acdClients.applications
dynClient = client.Resource(applicationsResource).Namespace(bakObj.GetNamespace())
// If application is not in one of the allowed namespaces do not import it
if !secutil.IsNamespaceEnabled(bakObj.GetNamespace(), namespace, applicationNamespaces) {
continue
}
case application.ApplicationSetKind:
dynClient = acdClients.applicationSets
dynClient = client.Resource(appplicationSetResource).Namespace(bakObj.GetNamespace())
// If applicationset is not in one of the allowed namespaces do not import it
if !secutil.IsNamespaceEnabled(bakObj.GetNamespace(), namespace, applicationsetNamespaces) {
continue
}
}
if !exists {
isForbidden := false
@@ -228,7 +276,7 @@ func NewImportCommand() *cobra.Command {
}
}
if !isForbidden {
fmt.Printf("%s/%s %s created%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), dryRunMsg)
fmt.Printf("%s/%s %s in namespace %s created%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), bakObj.GetNamespace(), dryRunMsg)
}
} else if specsEqual(*bakObj, liveObj) && checkAppHasNoNeedToStopOperation(liveObj, stopOperation) {
if verbose {
@@ -247,7 +295,7 @@ func NewImportCommand() *cobra.Command {
}
}
if !isForbidden {
fmt.Printf("%s/%s %s updated%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), dryRunMsg)
fmt.Printf("%s/%s %s in namespace %s updated%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), bakObj.GetNamespace(), dryRunMsg)
}
}
}
@@ -258,11 +306,11 @@ func NewImportCommand() *cobra.Command {
var dynClient dynamic.ResourceInterface
switch key.Kind {
case "Secret":
dynClient = acdClients.secrets
dynClient = client.Resource(secretResource).Namespace(liveObj.GetNamespace())
case application.AppProjectKind:
dynClient = acdClients.projects
dynClient = client.Resource(appprojectsResource).Namespace(liveObj.GetNamespace())
case application.ApplicationKind:
dynClient = acdClients.applications
dynClient = client.Resource(applicationsResource).Namespace(liveObj.GetNamespace())
if !dryRun {
if finalizers := liveObj.GetFinalizers(); len(finalizers) > 0 {
newLive := liveObj.DeepCopy()
@@ -274,7 +322,7 @@ func NewImportCommand() *cobra.Command {
}
}
case application.ApplicationSetKind:
dynClient = acdClients.applicationSets
dynClient = client.Resource(appplicationSetResource).Namespace(liveObj.GetNamespace())
default:
log.Fatalf("Unexpected kind '%s' in prune list", key.Kind)
}
@@ -303,6 +351,8 @@ func NewImportCommand() *cobra.Command {
command.Flags().BoolVar(&prune, "prune", false, "Prune secrets, applications and projects which do not appear in the backup")
command.Flags().BoolVar(&verbose, "verbose", false, "Verbose output (versus only changed output)")
command.Flags().BoolVar(&stopOperation, "stop-operation", false, "Stop any existing operations")
command.Flags().StringSliceVarP(&applicationNamespaces, "application-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to which import of applications is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applications without an explicit namespace will be imported to the Argo CD namespace", applicationNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName))
command.Flags().StringSliceVarP(&applicationsetNamespaces, "applicationset-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs which import of applicationsets is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applicationsets without an explicit namespace will be imported to the Argo CD namespace", applicationsetNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName))
return &command
}
@@ -320,13 +370,14 @@ func checkAppHasNoNeedToStopOperation(liveObj unstructured.Unstructured, stopOpe
}
// export writes the unstructured object and removes extraneous cruft from output before writing
func export(w io.Writer, un unstructured.Unstructured) {
func export(w io.Writer, un unstructured.Unstructured, argocdNamespace string) {
name := un.GetName()
finalizers := un.GetFinalizers()
apiVersion := un.GetAPIVersion()
kind := un.GetKind()
labels := un.GetLabels()
annotations := un.GetAnnotations()
namespace := un.GetNamespace()
unstructured.RemoveNestedField(un.Object, "metadata")
un.SetName(name)
un.SetFinalizers(finalizers)
@@ -334,6 +385,9 @@ func export(w io.Writer, un unstructured.Unstructured) {
un.SetKind(kind)
un.SetLabels(labels)
un.SetAnnotations(annotations)
if namespace != argocdNamespace {
un.SetNamespace(namespace)
}
data, err := yaml.Marshal(un.Object)
errors.CheckError(err)
_, err = w.Write(data)

View File

@@ -35,7 +35,8 @@ func NewNotificationsCommand() *cobra.Command {
"notifications",
"argocd admin notifications",
applications,
settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), func(clientConfig clientcmd.ClientConfig) {
settings.GetFactorySettingsForCLI(&argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false),
func(clientConfig clientcmd.ClientConfig) {
k8sCfg, err := clientConfig.ClientConfig()
if err != nil {
log.Fatalf("Failed to parse k8s config: %v", err)

View File

@@ -36,7 +36,7 @@ func TestPrintTreeViewAppResources(t *testing.T) {
buf := &bytes.Buffer{}
w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0)
printTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, false, false, w)
printTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w)
if err := w.Flush(); err != nil {
t.Fatal(err)
}
@@ -77,7 +77,7 @@ func TestPrintTreeViewDetailedAppResources(t *testing.T) {
buf := &bytes.Buffer{}
w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0)
printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, false, false, w)
printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w)
if err := w.Flush(); err != nil {
t.Fatal(err)
}

View File

@@ -175,25 +175,25 @@ func parentChildInfo(nodes []v1alpha1.ResourceNode) (map[string]v1alpha1.Resourc
return mapUidToNode, mapParentToChild, parentNode
}
func printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) {
func printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) {
for uid := range parentNodes {
detailedTreeViewAppResourcesNotOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w)
}
}
func printDetailedTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) {
func printDetailedTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) {
for uid := range parentNodes {
detailedTreeViewAppResourcesOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w)
}
}
func printTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) {
func printTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) {
for uid := range parentNodes {
treeViewAppResourcesNotOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w)
}
}
func printTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) {
func printTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) {
for uid := range parentNodes {
treeViewAppResourcesOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w)
}
@@ -206,24 +206,24 @@ func printResources(listAll bool, orphaned bool, appResourceTree *v1alpha1.Appli
if !orphaned || listAll {
mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.Nodes)
printDetailedTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, orphaned, listAll, w)
printDetailedTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, w)
}
if orphaned || listAll {
mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes)
printDetailedTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, orphaned, listAll, w)
printDetailedTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, w)
}
} else if output == "tree" {
fmt.Fprintf(w, "GROUP\tKIND\tNAMESPACE\tNAME\tORPHANED\n")
if !orphaned || listAll {
mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.Nodes)
printTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, orphaned, listAll, w)
printTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, w)
}
if orphaned || listAll {
mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes)
printTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, orphaned, listAll, w)
printTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, w)
}
} else {
headers := []interface{}{"GROUP", "KIND", "NAMESPACE", "NAME", "ORPHANED"}

View File

@@ -34,6 +34,10 @@ const (
clusterFieldName = "name"
// cluster field is 'namespaces'
clusterFieldNamespaces = "namespaces"
// cluster field is 'labels'
clusterFieldLabel = "labels"
// cluster field is 'annotations'
clusterFieldAnnotation = "annotations"
// indicates managing all namespaces
allNamespaces = "*"
)
@@ -220,6 +224,8 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
var (
clusterOptions cmdutil.ClusterOptions
clusterName string
labels []string
annotations []string
)
command := &cobra.Command{
Use: "set NAME",
@@ -238,17 +244,25 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie()
defer io.Close(conn)
// checks the fields that needs to be updated
updatedFields := checkFieldsToUpdate(clusterOptions)
updatedFields := checkFieldsToUpdate(clusterOptions, labels, annotations)
namespaces := clusterOptions.Namespaces
// check if all namespaces have to be considered
if len(namespaces) == 1 && strings.EqualFold(namespaces[0], allNamespaces) {
namespaces[0] = ""
}
// parse the labels you're receiving from the label flag
labelsMap, err := label.Parse(labels)
errors.CheckError(err)
// parse the annotations you're receiving from the annotation flag
annotationsMap, err := label.Parse(annotations)
errors.CheckError(err)
if updatedFields != nil {
clusterUpdateRequest := clusterpkg.ClusterUpdateRequest{
Cluster: &argoappv1.Cluster{
Name: clusterOptions.Name,
Namespaces: namespaces,
Name: clusterOptions.Name,
Namespaces: namespaces,
Labels: labelsMap,
Annotations: annotationsMap,
},
UpdatedFields: updatedFields,
Id: &clusterpkg.ClusterID{
@@ -266,11 +280,13 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
}
command.Flags().StringVar(&clusterOptions.Name, "name", "", "Overwrite the cluster name")
command.Flags().StringArrayVar(&clusterOptions.Namespaces, "namespace", nil, "List of namespaces which are allowed to manage. Specify '*' to manage all namespaces")
command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)")
command.Flags().StringArrayVar(&annotations, "annotation", nil, "Set metadata annotations (e.g. --annotation key=value)")
return command
}
// checkFieldsToUpdate returns the fields that needs to be updated
func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions) []string {
func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions, labels []string, annotations []string) []string {
var updatedFields []string
if clusterOptions.Name != "" {
updatedFields = append(updatedFields, clusterFieldName)
@@ -278,6 +294,12 @@ func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions) []string {
if clusterOptions.Namespaces != nil {
updatedFields = append(updatedFields, clusterFieldNamespaces)
}
if labels != nil {
updatedFields = append(updatedFields, clusterFieldLabel)
}
if annotations != nil {
updatedFields = append(updatedFields, clusterFieldAnnotation)
}
return updatedFields
}

View File

@@ -80,6 +80,7 @@ func NewCommand() *cobra.Command {
command.PersistentFlags().StringVar(&clientOpts.PortForwardNamespace, "port-forward-namespace", config.GetFlag("port-forward-namespace", ""), "Namespace name which should be used for port forwarding")
command.PersistentFlags().IntVar(&clientOpts.HttpRetryMax, "http-retry-max", config.GetIntFlag("http-retry-max", 0), "Maximum number of retries to establish http connection to Argo CD server")
command.PersistentFlags().BoolVar(&clientOpts.Core, "core", config.GetBoolFlag("core"), "If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server")
command.PersistentFlags().StringVar(&clientOpts.Context, "argocd-context", "", "The name of the Argo-CD server context to use")
command.PersistentFlags().StringVar(&clientOpts.ServerName, "server-name", env.StringFromEnv(common.EnvServerName, common.DefaultServerName), fmt.Sprintf("Name of the Argo CD API server; set this or the %s environment variable when the server's name label differs from the default, for example when installing via the Helm chart", common.EnvServerName))
command.PersistentFlags().StringVar(&clientOpts.AppControllerName, "controller-name", env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName), fmt.Sprintf("Name of the Argo CD Application controller; set this or the %s environment variable when the controller's name label differs from the default, for example when installing via the Helm chart", common.EnvAppControllerName))
command.PersistentFlags().StringVar(&clientOpts.RedisHaProxyName, "redis-haproxy-name", env.StringFromEnv(common.EnvRedisHaProxyName, common.DefaultRedisHaProxyName), fmt.Sprintf("Name of the Redis HA Proxy; set this or the %s environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart", common.EnvRedisHaProxyName))

View File

@@ -46,6 +46,7 @@ const (
ArgoCDGPGKeysConfigMapName = "argocd-gpg-keys-cm"
// ArgoCDAppControllerShardConfigMapName contains the application controller to shard mapping
ArgoCDAppControllerShardConfigMapName = "argocd-app-controller-shard-cm"
ArgoCDCmdParamsConfigMapName = "argocd-cmd-params-cm"
)
// Some default configurables

View File

@@ -1957,11 +1957,18 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *
}
}
selfHeal := app.Spec.SyncPolicy.Automated.SelfHeal
// Multi-Source Apps with selfHeal disabled should not trigger an autosync if
// the last sync revision and the new sync revision is the same.
if app.Spec.HasMultipleSources() && !selfHeal && reflect.DeepEqual(app.Status.Sync.Revisions, syncStatus.Revisions) {
logCtx.Infof("Skipping auto-sync: selfHeal disabled and sync caused by object update")
return nil, 0
}
desiredCommitSHA := syncStatus.Revision
desiredCommitSHAsMS := syncStatus.Revisions
alreadyAttempted, attemptPhase := alreadyAttemptedSync(app, desiredCommitSHA, desiredCommitSHAsMS, app.Spec.HasMultipleSources())
ts.AddCheckpoint("already_attempted_sync_ms")
selfHeal := app.Spec.SyncPolicy.Automated.SelfHeal
op := appv1.Operation{
Sync: &appv1.SyncOperation{
Revision: desiredCommitSHA,
@@ -2109,7 +2116,7 @@ func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application) (bool,
// isAppNamespaceAllowed returns whether the application is allowed in the
// namespace it's residing in.
func (ctrl *ApplicationController) isAppNamespaceAllowed(app *appv1.Application) bool {
return app.Namespace == ctrl.namespace || glob.MatchStringInList(ctrl.applicationNamespaces, app.Namespace, false)
return app.Namespace == ctrl.namespace || glob.MatchStringInList(ctrl.applicationNamespaces, app.Namespace, glob.REGEXP)
}
func (ctrl *ApplicationController) canProcessApp(obj interface{}) bool {

View File

@@ -563,6 +563,42 @@ func TestAutoSync(t *testing.T) {
assert.False(t, app.Operation.Sync.Prune)
}
func TestMultiSourceSelfHeal(t *testing.T) {
// Simulate OutOfSync caused by object change in cluster
// So our Sync Revisions and SyncStatus Revisions should deep equal
t.Run("ClusterObjectChangeShouldNotTriggerAutoSync", func(t *testing.T) {
app := newFakeMultiSourceApp()
app.Spec.SyncPolicy.Automated.SelfHeal = false
app.Status.Sync.Revisions = []string{"z", "x", "v"}
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil)
syncStatus := v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeOutOfSync,
Revisions: []string{"z", "x", "v"},
}
cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook-1", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}})
assert.Nil(t, cond)
app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{})
require.NoError(t, err)
assert.Nil(t, app.Operation)
})
t.Run("NewRevisionChangeShouldTriggerAutoSync", func(t *testing.T) {
app := newFakeMultiSourceApp()
app.Spec.SyncPolicy.Automated.SelfHeal = false
app.Status.Sync.Revisions = []string{"a", "b", "c"}
ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil)
syncStatus := v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeOutOfSync,
Revisions: []string{"z", "x", "v"},
}
cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook-1", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}})
assert.Nil(t, cond)
app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{})
require.NoError(t, err)
assert.NotNil(t, app.Operation)
})
}
func TestAutoSyncNotAllowEmpty(t *testing.T) {
app := newFakeApp()
app.Spec.SyncPolicy.Automated.Prune = true

View File

@@ -591,7 +591,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
}
// No need to care about the return value here, we just want the modified managedNs
_, err = syncNamespace(m.resourceTracking, appLabelKey, trackingMethod, app.Name, app.Spec.SyncPolicy)(managedNs, liveObj)
_, err = syncNamespace(app.Spec.SyncPolicy)(managedNs, liveObj)
if err != nil {
conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
failedToLoadObjs = true

View File

@@ -324,7 +324,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
}
if syncOp.SyncOptions.HasOption("CreateNamespace=true") {
opts = append(opts, sync.WithNamespaceModifier(syncNamespace(m.resourceTracking, appLabelKey, trackingMethod, app.Name, app.Spec.SyncPolicy)))
opts = append(opts, sync.WithNamespaceModifier(syncNamespace(app.Spec.SyncPolicy)))
}
syncCtx, cleanup, err := sync.NewSyncContext(

View File

@@ -5,12 +5,11 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo"
)
// syncNamespace determine if Argo CD should create and/or manage the namespace
// where the application will be deployed.
func syncNamespace(resourceTracking argo.ResourceTracking, appLabelKey string, trackingMethod v1alpha1.TrackingMethod, appName string, syncPolicy *v1alpha1.SyncPolicy) func(m, l *unstructured.Unstructured) (bool, error) {
func syncNamespace(syncPolicy *v1alpha1.SyncPolicy) func(m *unstructured.Unstructured, l *unstructured.Unstructured) (bool, error) {
// This function must return true for the managed namespace to be synced.
return func(managedNs, liveNs *unstructured.Unstructured) (bool, error) {
if managedNs == nil {

View File

@@ -8,9 +8,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo"
)
func createFakeNamespace(uid string, resourceVersion string, labels map[string]string, annotations map[string]string) *unstructured.Unstructured {
@@ -250,7 +248,7 @@ func Test_shouldNamespaceSync(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual, err := syncNamespace(argo.NewResourceTracking(), common.LabelKeyAppInstance, argo.TrackingMethodAnnotation, "some-app", tt.syncPolicy)(tt.managedNs, tt.liveNs)
actual, err := syncNamespace(tt.syncPolicy)(tt.managedNs, tt.liveNs)
require.NoError(t, err)
if tt.managedNs != nil {

View File

@@ -15,7 +15,7 @@ These are the upcoming releases dates:
| v2.10 | Monday, Dec. 18, 2023 | Monday, Feb. 5, 2024 | [Katie Lamkin](https://github.com/kmlamkin9) | | [checklist](https://github.com/argoproj/argo-cd/issues/16339) |
| v2.11 | Friday, Apr. 5, 2024 | Monday, May 6, 2024 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/17726) |
| v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | [Ishita Sequeira](https://github.com/ishitasequeira) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19063) |
| v2.13 | Monday, Sep. 16, 2024 | Monday, Nov. 4, 2024 | | | |
| v2.13 | Monday, Sep. 16, 2024 | Monday, Nov. 4, 2024 | [Regina Voloshin](https://github.com/reggie-k) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19513) |
| v2.14 | Monday, Dec. 16, 2024 | Monday, Feb. 3, 2025 | | | |
| v2.15 | Monday, Mar. 17, 2025 | Monday, May 5, 2025 | | | |

View File

@@ -42,8 +42,11 @@ In order for an application to be managed and reconciled outside the Argo CD's c
In order to enable this feature, the Argo CD administrator must reconfigure the `argocd-server` and `argocd-application-controller` workloads to add the `--application-namespaces` parameter to the container's startup command.
The `--application-namespaces` parameter takes a comma-separated list of namespaces where `Applications` are to be allowed in. Each entry of the list supports shell-style wildcards such as `*`, so for example the entry `app-team-*` would match `app-team-one` and `app-team-two`. To enable all namespaces on the cluster where Argo CD is running on, you can just specify `*`, i.e. `--application-namespaces=*`.
The `--application-namespaces` parameter takes a comma-separated list of namespaces where `Applications` are to be allowed in. Each entry of the list supports:
- shell-style wildcards such as `*`, so for example the entry `app-team-*` would match `app-team-one` and `app-team-two`. To enable all namespaces on the cluster where Argo CD is running on, you can just specify `*`, i.e. `--application-namespaces=*`.
- regex, requires wrapping the string in ```/```, example to allow all namespaces except a particular one: ```/^((?!not-allowed).)*$/```.
The startup parameters for both, the `argocd-server` and the `argocd-application-controller` can also be conveniently set up and kept in sync by specifying the `application.namespaces` settings in the `argocd-cmd-params-cm` ConfigMap _instead_ of changing the manifests for the respective workloads. For example:
```yaml

View File

@@ -7,6 +7,8 @@ The Git generator contains two subtypes: the Git directory generator, and Git fi
If the `project` field in your ApplicationSet is templated, developers may be able to create Applications under Projects with excessive permissions.
For ApplicationSets with a templated `project` field, [the source of truth _must_ be controlled by admins](./Security.md#templated-project-field)
- in the case of git generators, PRs must require admin approval.
- Git generator does not support Signature Verification For ApplicationSets with a templated `project` field.
## Git Generator: Directories

View File

@@ -100,6 +100,17 @@ possible with Go text templates:
- name: throw-away
value: "{{end}}"
- Signature verification is not supported for the templated `project` field when using the Git generator.
::yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
spec:
goTemplate: true
template:
spec:
project: {{.project}}
## Migration guide

View File

@@ -43,6 +43,7 @@ Note:
- Referenced clusters must already be defined in Argo CD, for the ApplicationSet controller to use them
- Only **one** of `name` or `server` may be specified: if both are specified, an error is returned.
- Signature Verification does not work with the templated `project` field when using git generator.
The `metadata` field of template may also be used to set an Application `name`, or to add labels or annotations to the Application.

View File

@@ -11,6 +11,7 @@ argocd [flags]
### Options
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -52,6 +52,7 @@ argocd account [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -25,6 +25,7 @@ argocd account bcrypt --password YOUR_PASSWORD
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -35,6 +35,7 @@ Resources: [clusters projects applications applicationsets repositories certific
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -28,6 +28,7 @@ argocd account delete-token --account <account-name> ID
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -30,6 +30,7 @@ argocd account generate-token --account <account-name>
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -28,6 +28,7 @@ argocd account get-user-info [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -29,6 +29,7 @@ argocd account get --account <account-name>
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -24,6 +24,7 @@ argocd account list
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -40,6 +40,7 @@ argocd account update-password [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -30,6 +30,7 @@ $ argocd admin initial-password reset
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -32,6 +32,7 @@ argocd admin app get-reconcile-results APPNAME
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -17,6 +17,7 @@ argocd admin app diff-reconcile-results PATH1 PATH2 [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -106,6 +106,7 @@ argocd admin app generate-spec APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -43,6 +43,7 @@ argocd admin app get-reconcile-results PATH [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -31,6 +31,7 @@ argocd admin cluster namespaces my-cluster
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -40,6 +40,7 @@ argocd admin cluster generate-spec CONTEXT [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -54,6 +54,7 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -37,6 +37,7 @@ argocd admin cluster namespaces [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -38,6 +38,7 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -40,6 +40,7 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -53,6 +53,7 @@ argocd admin cluster shards [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -67,6 +67,7 @@ argocd admin cluster stats target-cluster
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -54,6 +54,7 @@ $ argocd admin dashboard --redis-compress gzip
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -11,33 +11,36 @@ argocd admin export [flags]
### Options
```
--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
--disable-compression If true, opt-out of response compression for all requests to the server
-h, --help help for export
--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
-o, --out string Output to the specified file instead of stdout (default "-")
--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
--application-namespaces strings Comma separated list of namespace globs to export applications from. If not provided value from 'application.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applications from Argo CD namespace will be exported
--applicationset-namespaces strings Comma separated list of namespace globs to export applicationsets from. If not provided value from 'applicationsetcontroller.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applicationsets from Argo CD namespace will be exported
--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
--disable-compression If true, opt-out of response compression for all requests to the server
-h, --help help for export
--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
-o, --out string Output to the specified file instead of stdout (default "-")
--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
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -11,36 +11,39 @@ argocd admin import SOURCE [flags]
### Options
```
--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
--disable-compression If true, opt-out of response compression for all requests to the server
--dry-run Print what will be performed
-h, --help help for import
--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
--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
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--verbose Verbose output (versus only changed output)
--application-namespaces strings Comma separated list of namespace globs to which import of applications is allowed. If not provided value from 'application.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applications without an explicit namespace will be imported to the Argo CD namespace
--applicationset-namespaces strings Comma separated list of namespace globs which import of applicationsets is allowed. If not provided value from 'applicationsetcontroller.namespaces' in argocd-cmd-params-cm will be used,if it's not defined only applicationsets without an explicit namespace will be imported to the Argo CD namespace
--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
--disable-compression If true, opt-out of response compression for all requests to the server
--dry-run Print what will be performed
-h, --help help for import
--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
--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
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--verbose Verbose output (versus only changed output)
```
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -37,6 +37,7 @@ argocd admin initial-password [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -42,6 +42,7 @@ argocd admin notifications [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -17,6 +17,7 @@ argocd admin notifications template [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081")
--argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server
--argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server

View File

@@ -29,6 +29,7 @@ argocd admin notifications template get app-sync-succeeded -o=yaml
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081")
--argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server
--argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server

View File

@@ -30,6 +30,7 @@ argocd admin notifications template notify app-sync-succeeded guestbook
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081")
--argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server
--argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server

View File

@@ -17,6 +17,7 @@ argocd admin notifications trigger [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081")
--argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server
--argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server

View File

@@ -29,6 +29,7 @@ argocd admin notifications trigger get on-sync-failed -o=yaml
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081")
--argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server
--argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server

View File

@@ -29,6 +29,7 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081")
--argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server
--argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server

View File

@@ -17,6 +17,7 @@ argocd admin proj [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -45,6 +45,7 @@ argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -44,6 +44,7 @@ argocd admin proj generate-spec PROJECT [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -53,6 +53,7 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -37,6 +37,7 @@ argocd admin redis-initial-password [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -17,6 +17,7 @@ argocd admin repo [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -64,6 +64,7 @@ argocd admin repo generate-spec REPOURL [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -40,6 +40,7 @@ argocd admin settings [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -18,6 +18,7 @@ argocd admin settings rbac [flags]
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -73,6 +73,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--argocd-secret-path string Path to local argocd-secret.yaml file
--auth-token string Authentication token
--client-crt string Client certificate file

View File

@@ -65,6 +65,7 @@ argocd admin settings rbac validate --namespace argocd
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--argocd-secret-path string Path to local argocd-secret.yaml file
--auth-token string Authentication token
--client-crt string Client certificate file

View File

@@ -18,6 +18,7 @@ argocd admin settings resource-overrides [flags]
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -29,6 +29,7 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path .
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -29,6 +29,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -30,6 +30,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml -
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -29,6 +29,7 @@ argocd admin settings resource-overrides action list /tmp/deploy.yaml --argocd-c
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -29,6 +29,7 @@ argocd admin settings resource-overrides action run /tmp/deploy.yaml restart --a
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -34,6 +34,7 @@ argocd admin settings validate --group accounts --group plugins --load-cluster-s
```
--argocd-cm-path string Path to local argocd-cm.yaml file
--argocd-context string The name of the Argo-CD server context to use
--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.

View File

@@ -49,6 +49,7 @@ argocd app [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -27,6 +27,7 @@ argocd app actions [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -29,6 +29,7 @@ argocd app actions list APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -29,6 +29,7 @@ argocd app actions run APPNAME ACTION [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -83,6 +83,7 @@ argocd app add-source APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -107,6 +107,7 @@ argocd app create APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -25,6 +25,7 @@ argocd app delete-resource APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -40,6 +40,7 @@ argocd app delete APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -36,6 +36,7 @@ argocd app diff APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -18,6 +18,7 @@ argocd app edit APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -54,6 +54,7 @@ argocd app get APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -19,6 +19,7 @@ argocd app history APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -37,6 +37,7 @@ argocd app list [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -68,6 +68,7 @@ argocd app logs APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -36,6 +36,7 @@ argocd app manifests APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -25,6 +25,7 @@ argocd app patch-resource APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

View File

@@ -30,6 +30,7 @@ argocd app patch APPNAME [flags]
### Options inherited from parent commands
```
--argocd-context string The name of the Argo-CD server context to use
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file

Some files were not shown because too many files have changed in this diff Show More