Compare commits

...

97 Commits

Author SHA1 Message Date
github-actions[bot]
206a6eeca5 Bump version to 2.14.21 on release-2.14 branch (#25161)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-11-04 09:56:45 -05:00
Jakub Ciolek
8b31544069 fix: make webhook payload handlers recover from panics (cherry-pick #24862 for 2.14) (#24926)
Signed-off-by: Jakub Ciolek <jakub@ciolek.dev>
2025-10-14 14:14:22 -04:00
Carlos R.F.
9b7bf3e16d chore(deps): bump redis from 7.0.14 to 7.2.11 to address vuln (release-2.14) (#24892)
Signed-off-by: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
2025-10-09 17:08:18 -04:00
github-actions[bot]
879895af78 Bump version to 2.14.20 on release-2.14 branch (#24796)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 11:32:00 -04:00
Ville Vesilehto
1f98e3f989 Merge commit from fork
Fixed a race condition in repository credentials handling by
implementing deep copying of secrets before modification.
This prevents concurrent map read/write panics when multiple
goroutines access the same secret.

The fix ensures thread-safe operations by always operating on
copies rather than shared objects.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
2025-09-30 10:45:59 -04:00
Michael Crenshaw
741f00e2e3 Merge commit from fork
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 10:45:32 -04:00
Michael Crenshaw
e889f0a7ff Merge commit from fork
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 10:07:24 -04:00
Michael Crenshaw
7b219ee97f Merge commit from fork
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 09:45:21 -04:00
argo-cd-cherry-pick-bot[bot]
4ab9cd45bf fix: allow for backwards compatibility of durations defined in days (cherry-pick #24769 for 2.14) (#24772)
Signed-off-by: lplazas <felipe.plazas10@gmail.com>
Co-authored-by: lplazas <luis.plazas@workato.com>
2025-09-29 09:08:15 -04:00
github-actions[bot]
ba5b938858 Bump version to 2.14.19 on release-2.14 branch (#24700)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: alexmt <426437+alexmt@users.noreply.github.com>
2025-09-22 15:14:10 -07:00
Alexander Matyushentsev
4a133ce41b fix: limit number of resources in appset status (#24690) (#24694)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2025-09-22 14:57:44 -07:00
Alexandre Gaudreault
376525eea2 ci(release): only set latest release in github when latest (#24525) (#24688)
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2025-09-22 11:47:51 -04:00
github-actions[bot]
9fa9bb8c89 Bump version to 2.14.18 on release-2.14 branch (#24637)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: blakepettersson <1227954+blakepettersson@users.noreply.github.com>
2025-09-18 04:19:04 -10:00
Alexander Matyushentsev
4359b3c774 fix: use informer in webhook handler to reduce memory usage (#24622) (#24628)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2025-09-18 08:13:03 +02:00
argo-cd-cherry-pick-bot[bot]
4f6686fc3f fix: correct post-delete finalizer removal when cluster not found (cherry-pick #24415 for 2.14) (#24591)
Signed-off-by: Pavel Aborilov <aborilov@gmail.com>
Co-authored-by: Pavel <aborilov@gmail.com>
2025-09-16 16:14:18 -07:00
Anand Francis Joseph
caa4dc1bd2 fix(util): Fix default key exchange algorthims used for SSH connection to be FIPS compliant (#24499)
Signed-off-by: anandf <anjoseph@redhat.com>
2025-09-10 11:21:45 -04:00
Nitish Kumar
981e7f762a fix(2.14): change the appset namespace to server namespace when generating appset (#24481)
Signed-off-by: nitishfy <justnitish06@gmail.com>
2025-09-09 14:00:35 +03:00
Fox Piacenti
3d76aa5daa docs: Update URL for HA manifests to stable. (#24456)
Signed-off-by: Fox Danger Piacenti <fox@opencraft.com>
2025-09-09 12:35:30 +03:00
github-actions[bot]
fca3a7ed2a Bump version to 2.14.17 on release-2.14 branch (#24403)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-09-04 13:31:21 -04:00
github-actions[bot]
2bb617d02a Bump version to 2.14.16 on release-2.14 branch (#24397)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-09-04 11:53:37 -04:00
Michael Crenshaw
72e2387795 fix(security): repository.GetDetailedProject exposes repo secrets (#24389)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Signed-off-by: Dan Garfield <dan.garfield@octopus.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Co-authored-by: Dan Garfield <dan.garfield@octopus.com>
2025-09-04 11:33:04 -04:00
Adrian Berger
f8eba3e6e9 fix(cherry-pick-2.14): custom resource health for flux helm repository of type oci (#24339)
Signed-off-by: Adrian Berger <adrian.berger@bedag.ch>
2025-09-02 15:19:27 -04:00
Nitish Kumar
510b77546e chore(cherry-pick-2.14): replace bitnami images (#24289)
Signed-off-by: nitishfy <justnitish06@gmail.com>
2025-08-27 14:37:51 +02:00
gcp-cherry-pick-bot[bot]
d77ecdf113 chore: adds all components in goreman run script (cherry-pick #23777) (#23790)
Signed-off-by: Patroklos Papapetrou <ppapapetrou76@gmail.com>
Co-authored-by: Papapetrou Patroklos <1743100+ppapapetrou76@users.noreply.github.com>
2025-08-24 21:37:14 -04:00
Ville Vesilehto
f9bb3b608e chore: update Go to 1.24.6 (release-2.14) (#24091)
Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
2025-08-11 11:24:15 +02:00
rumstead
5d0a4f0dd3 fix(appset): When Appset is deleted, the controller should reconcile applicationset #23723 (cherry-pick ##23823) (#23832)
Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
Co-authored-by: sangeer <86688098+sangdammad@users.noreply.github.com>
2025-07-17 11:56:24 -04:00
Michael Crenshaw
8a3b2fdd2b fix(server): infer resource status health for apps-in-any-ns (#22944) (#23707)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-07-09 11:50:18 -04:00
gcp-cherry-pick-bot[bot]
ddb6073e52 fix: improves the ui message when an operation is terminated due to controller sync timeout (cherry-pick #23657) (#23673)
Signed-off-by: Patroklos Papapetrou <ppapapetrou76@gmail.com>
Co-authored-by: Papapetrou Patroklos <1743100+ppapapetrou76@users.noreply.github.com>
2025-07-07 10:49:51 +03:00
gcp-cherry-pick-bot[bot]
d95b710055 fix(controller): get commit server url from env (cherry-pick #23536) (#23543)
Signed-off-by: Alexej Disterhoft <alexej.disterhoft@redcare-pharmacy.com>
Co-authored-by: Alexej Disterhoft <alexej@disterhoft.de>
2025-06-24 14:41:11 -04:00
github-actions[bot]
6c7d6940cd Bump version to 2.14.15 on release-2.14 branch (#23427)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-06-16 13:59:54 -04:00
rumstead
ec5198949e fix(applicationset): requeue applicationste when application status changes (#23413)
Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
Co-authored-by: Dmitry Shmelev <avikez@gmail.com>
2025-06-16 11:46:59 -04:00
Alexandre Gaudreault
da2ef7db67 fix(sync): auto-sync loop when FailOnSharedResource (#23357)
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2025-06-12 11:58:04 -04:00
github-actions[bot]
c6166fd531 Bump version to 2.14.14 on release-2.14 branch (#23299)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: blakepettersson <1227954+blakepettersson@users.noreply.github.com>
2025-06-09 11:37:55 -04:00
Ville Vesilehto
3c68b26d7a chore: upgrade Go from 1.23.4 to 1.24.4 (release-2.14) (#23294)
Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-06-08 20:00:00 +02:00
Ville Vesilehto
5f890629a9 chore: upgrade mockery to v2.53.4 (release-2.14) (#23316)
Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
2025-06-08 07:58:46 -04:00
Ville Vesilehto
e24ee58f28 chore: upgrade golangci-lint to v2 (release-2.14) (#23305)
Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
2025-06-06 16:54:43 -04:00
gcp-cherry-pick-bot[bot]
14fa0e0d9f fix: parse project with applicationset resource (cherry-pick #23252) (#23268)
Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
Co-authored-by: Blake Pettersson <blake.pettersson@gmail.com>
2025-06-04 23:16:30 -10:00
Siddhesh Ghadi
2aceb1dc44 fix: update broken yarn.lock (#23212)
Signed-off-by: Siddhesh Ghadi <sghadi1203@gmail.com>
2025-05-30 10:41:41 -06:00
Soumya Ghosh Dastidar
a2361bf850 fix: add cooldown to prevent resetting autoheal exp backoff preemptively (cherry-pick #23057) (#23188)
Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>
2025-05-28 22:40:38 +02:00
github-actions[bot]
5ad281ef56 Bump version to 2.14.13 on release-2.14 branch (#23183)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-05-28 08:45:02 -06:00
Michael Crenshaw
24d57220ca Merge commit from fork
Fix shadowed variable name

Signed-off-by: Ry0taK <49341894+Ry0taK@users.noreply.github.com>
Co-authored-by: Ry0taK <49341894+Ry0taK@users.noreply.github.com>
2025-05-28 08:20:48 -06:00
Peter Jiang
d213c305e4 chore: bump gitops-engine ssd fix (#23072)
Signed-off-by: Peter Jiang <peterjiang823@gmail.com>
2025-05-20 21:10:33 -04:00
github-actions[bot]
25e327bb9a Bump version to 2.14.12 on release-2.14 branch (#23064)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-05-20 11:29:01 -04:00
nathanlaceyraft
efe5d2956e chore(deps): resolve CVE GO-2025-3540, GO-2025-3503, GO-2025-3487 within 2.14.10 (#22709)
Signed-off-by: Nathan Lacey <nlacey@teamraft.com>
2025-05-20 10:57:12 -04:00
Alexandre Gaudreault
5bc6f4722b fix: infinite reconciliation loop when app is in error (#23047)
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-05-20 10:48:47 -04:00
gcp-cherry-pick-bot[bot]
25235fbc2d fix(test): broken e2e test (cherry-pick #22975) (#23052)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-05-20 09:49:13 -04:00
gcp-cherry-pick-bot[bot]
3a9ab77537 fix(commit-server): apply image override (cherry-pick #22916) (#22918) 2025-05-09 21:54:33 -04:00
gcp-cherry-pick-bot[bot]
ced6a7822e fix(health): handle nil lastTransitionTime (#22897) (cherry-pick #22900) (#22909)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-05-09 10:46:25 -04:00
Blake Pettersson
fe93963970 fix: do not normalize resource tracking on live crds (#22722) - cherrypick 2.14 (#22746)
Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
Co-authored-by: Dan Garfield <dan@codefresh.io>
2025-05-07 16:35:29 -07:00
Mike Bryant
78e61ba71c fix: Only port-forward to ready pods (#10610) (cherry-pick #22794) (#22826)
Signed-off-by: Mike Bryant <mike.bryant@mettle.co.uk>
Co-authored-by: Dan Garfield <dan@codefresh.io>
2025-05-07 15:24:52 -07:00
gcp-cherry-pick-bot[bot]
f7ad2adf50 fix(ApplicationSet): Check strategy type to verify it's a progressive sync (cherry-pick #22563) (#22833)
Signed-off-by: Fernando Crespo Gravalos <fcrespo@fastly.com>
Signed-off-by: Fernando Crespo Grávalos <59588094+fcrespofastly@users.noreply.github.com>
Co-authored-by: Fernando Crespo Grávalos <59588094+fcrespofastly@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-04-30 12:37:32 -07:00
Peter Jiang
b163de0784 fix: remove project from cache key for project scoped credentials (#22816)
Signed-off-by: Peter Jiang <peterjiang823@gmail.com>
2025-04-28 16:41:57 -04:00
github-actions[bot]
82831155c2 Bump version to 2.14.11 on release-2.14 branch (#22755)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-04-22 08:25:09 -07:00
gcp-cherry-pick-bot[bot]
91f54459d4 feat(hydrator): handle sourceHydrator fields from webhook (#19397) (cherry-pick #22485) (#22754)
Signed-off-by: daengdaengLee <gunho1020@gmail.com>
Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Co-authored-by: Alexy Mantha <alexy.mantha@goto.com>
Co-authored-by: Kunho Lee <gunho1020@gmail.com>
2025-04-22 08:20:58 -07:00
gcp-cherry-pick-bot[bot]
0451723be1 fix(appset): generated app errors should use the default requeue (#21887) (cherry-pick #21936) (#22672)
Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com>
Co-authored-by: Blake Pettersson <blake.pettersson@gmail.com>
2025-04-18 11:48:08 -07:00
gcp-cherry-pick-bot[bot]
f6f7d29c11 fix(ui): avoid spurious error on hydration (#22506) (cherry-pick #22711) (#22714)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-04-17 16:40:39 -07:00
github-actions[bot]
5feb8c21f2 Bump version to 2.14.10 on release-2.14 branch (#22670)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: alexmt <426437+alexmt@users.noreply.github.com>
2025-04-14 17:38:21 -07:00
Hesham Sherif
4826fb0ab8 chore(deps): Update github.com/expr-lang/expr to v1.17.0 fixing CVE-2025-29786 (#22651)
Signed-off-by: heshamelsherif97 <heshamelsherif97@gmail.com>
2025-04-14 15:05:10 -07:00
gcp-cherry-pick-bot[bot]
3b308d66e2 fix: respect delete confirmation for argocd app deletion (cherry-pick #22657) (#22664)
Signed-off-by: nitishfy <justnitish06@gmail.com>
Co-authored-by: Nitish Kumar <justnitish06@gmail.com>
2025-04-14 08:36:01 -07:00
gcp-cherry-pick-bot[bot]
b31d700188 fix(cli): wrong variable to store --no-proxy value (cherry-pick #21226) (#22590)
Signed-off-by: Nathanael Liechti <technat@technat.ch>
Co-authored-by: Nathanael Liechti <technat@technat.ch>
2025-04-10 07:08:55 -07:00
gcp-cherry-pick-bot[bot]
be81419f27 fix: login return_url doesn't work with custom server paths (cherry-pick #21588) (#22594)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2025-04-07 13:14:27 -07:00
Aaron Hoffman
6b15a04509 fix: [cherry-pick] selfhealattemptscount needs to be reset at times (#22095, #20978) (#22583)
Signed-off-by: Michal Ryšavý <michal.rysavy@ext.csas.cz>
Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
Co-authored-by: Michal Ryšavý <mrysavy@users.noreply.github.com>
Co-authored-by: Michal Ryšavý <michal.rysavy@ext.csas.cz>
Co-authored-by: Blake Pettersson <blake.pettersson@gmail.com>
2025-04-07 06:32:03 -07:00
github-actions[bot]
38985bdcd6 Bump version to 2.14.9 on release-2.14 branch (#22549)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-04-02 12:29:11 -07:00
Peter Jiang
c868711d03 chore(dep): bump gitops-engine 2.14 (#22520)
Signed-off-by: Peter Jiang <peterjiang823@gmail.com>
2025-03-29 10:44:07 -04:00
gcp-cherry-pick-bot[bot]
31a554568a fix: Check for semver constraint matching in application webhook handler (cherry-pick #21648) (#22508)
Signed-off-by: eadred <eadred77@googlemail.com>
Co-authored-by: Eadred <eadred77@googlemail.com>
2025-03-27 11:27:09 -04:00
github-actions[bot]
a7178be1c1 Bump version to 2.14.8 on release-2.14 branch (#22469)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-03-24 15:38:39 -04:00
Michael Crenshaw
9a9e62d392 fix(server): fully populate app destination before project checks (#22408) (#22426)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-03-24 11:20:07 -07:00
Michael Crenshaw
9f832cd099 chore(deps): bump github.com/golang-jwt/jwt to 4.5.2/5.2.2 (#22465)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-03-24 14:06:41 -04:00
Blake Pettersson
ec45e33800 fix(ui, rbac): project-roles (#21829) (2.14 backport) (#22461)
Signed-off-by: wyttime04 <vanessa80332@gmail.com>
Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
Co-authored-by: wyttime04 <vanessa80332@gmail.com>
2025-03-24 10:47:26 -07:00
Atif Ali
872319e8e7 fix: handle annotated git tags correctly in repo server cache (#21771) (#22424)
Signed-off-by: Atif Ali <atali@redhat.com>
2025-03-21 09:49:35 -04:00
nmirasch
7acdaa96e0 fix: CVE-2025-26791 upgrading redoc dep to 2.4.0 to avoid DOMPurify b… (#21997)
Signed-off-by: nmirasch <neus.miras@gmail.com>
2025-03-21 07:33:19 -04:00
github-actions[bot]
d107d4e41a Bump version to 2.14.7 on release-2.14 branch (#22412)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-03-19 13:04:41 -04:00
Michael Crenshaw
39407827d3 chore(deps): bump gitops engine (#22405)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-03-19 10:51:18 -04:00
github-actions[bot]
fe2a6e91b6 Bump version to 2.14.6 on release-2.14 branch (#22393)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-03-18 06:23:50 -07:00
rumstead
38c03769af feat(server): make deep copies of objects returned by informers (#22173) (#22179) (#22340)
Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-03-13 11:56:50 -07:00
Anand Francis Joseph
defd4be943 chore(deps): Update go-git from 5.12.0 to 5.13.2 to include several CVE fixes (#22313)
Signed-off-by: anandf <anjoseph@redhat.com>
2025-03-13 09:49:44 -04:00
github-actions[bot]
f463a945d5 Bump version to 2.14.5 on release-2.14 branch (#22292)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ishitasequeira <46771830+ishitasequeira@users.noreply.github.com>
2025-03-10 23:11:20 -04:00
Anand Francis Joseph
ed242b9eee chore(deps): bump github.com/redis/go-redis/v9 from 9.7.0 to 9.7.1 (#21957) (#22255)
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: anandf <anjoseph@redhat.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-09 19:39:46 +02:00
github-actions[bot]
3d901f2037 Bump version to 2.14.4 on release-2.14 branch (#22176)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-03-04 15:31:29 -05:00
Michael Crenshaw
2b1e829986 chore(deps): switch gitops-engine back to release-2.14 branch (#22163)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-03-04 15:23:48 -05:00
gcp-cherry-pick-bot[bot]
52231dbc09 fix(actions): don't run empty Lua scripts (#22084) (cherry-pick #22161) (#22172)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-03-04 15:23:32 -05:00
Michael Crenshaw
2eab10a3cb chore(deps): revert accidental upgrade of go.mod packages (#22162)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-03-04 14:08:08 -05:00
gcp-cherry-pick-bot[bot]
962d7a9ad9 fix(ci): use pinned Helm version for init-release (#22164) (cherry-pick #22165) (#22171)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-03-04 13:51:52 -05:00
gcp-cherry-pick-bot[bot]
54170a4fd8 fix: make codegen permissions (cherry-pick #21667) (#22145)
Signed-off-by: Brett C. Dudo <brett@dudo.io>
Signed-off-by: Brett Dudo <brett@dudo.io>
Co-authored-by: Brett Dudo <brett@dudo.io>
Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com>
2025-03-04 09:57:17 +05:30
gcp-cherry-pick-bot[bot]
71fd4e501d fix: Check placement exists before length check (#22060) (cherry-pick #22057) (#22089)
Signed-off-by: Dale Haiducek <19750917+dhaiducek@users.noreply.github.com>
Co-authored-by: Dale Haiducek <19750917+dhaiducek@users.noreply.github.com>
2025-02-28 11:41:20 -05:00
Nitish Kumar
cb1df5d35f fix: correct lookup for the kustomization file when applying patches (cherry-pick #22024) (#22086)
Signed-off-by: nitishfy <justnitish06@gmail.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-02-28 21:36:55 +05:30
github-actions[bot]
66db4b6876 Bump version to 2.14.3 on release-2.14 branch (#22070)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-02-27 15:53:50 -05:00
Michael Crenshaw
3adb83c1df fix(hydrator): refresh by annotation instead of work queue (#22016) (#22067)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-02-27 15:30:14 -05:00
Michael Crenshaw
63edc3eb9c fix: accidental v3 imports (#22068)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-02-27 15:29:47 -05:00
gcp-cherry-pick-bot[bot]
2dd70dede8 fix(hydrator): don't use manifest-generate-paths (#22039) (cherry-pick #22015) (#22061)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-02-27 13:01:13 -05:00
Michael Crenshaw
d79185a4fe fix(hydrator): don't get cluster or API versions for hydrator (#21985) (#22038)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-02-26 15:33:09 -05:00
gcp-cherry-pick-bot[bot]
8f925c6754 fix: fetch syncedRevision in UpdateRevisionForPaths (#21014) (cherry-pick #21015) (#22011)
Signed-off-by: toyamagu2021 <toyamagu2021@gmail.com>
Signed-off-by: toyamagu-2021 <toyamagu2021@gmail.com>
Co-authored-by: gussan <83329336+toyamagu-2021@users.noreply.github.com>
2025-02-26 20:12:02 +05:30
gcp-cherry-pick-bot[bot]
b5be1df890 docs: document source hydrator maturity (cherry-pick #21969) (#21970)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-02-24 10:41:39 -05:00
gcp-cherry-pick-bot[bot]
92a3c3d727 fix: correctly set compareWith when requesting app refresh with delay (fixes #18998) (cherry-pick #21298) (#21952)
Signed-off-by: Xiaonan Shen <s@sxn.dev>
Co-authored-by: Xiaonan Shen <s@sxn.dev>
Co-authored-by: 沈啸楠 <sxn@shenxiaonandeMacBook-Pro.local>
2025-02-23 22:51:30 +05:30
gcp-cherry-pick-bot[bot]
aaed35c6d4 fix(applicationset): ApplicationSets with rolling sync stuck in Pending (cherry-pick #20230) (#21948)
Signed-off-by: Fabián Sellés <fabian.selles@adevinta.com>
Co-authored-by: Fabián Sellés Rosa <1088313+Fsero@users.noreply.github.com>
Co-authored-by: Thibault Jamet <tjamet@users.noreply.github.com>
Co-authored-by: Carlos Rejano <carlosrejanoromeu@gmail.com>
2025-02-22 15:07:42 -05:00
Nitish Kumar
2b422d2c70 chore: add cherry pick for v2.14 (#21901)
Signed-off-by: nitishfy <justnitish06@gmail.com>
2025-02-18 11:34:01 -08:00
Andrii Korotkov
896a461ae6 fix: New kube applier for server side diff dry run with refactoring (#21488) (#21819)
Signed-off-by: Andrii Korotkov <andrii.korotkov@verkada.com>
2025-02-07 17:57:27 -05:00
354 changed files with 5833 additions and 2732 deletions

View File

@@ -14,7 +14,7 @@ on:
env:
# Golang version to use across CI steps
# renovate: datasource=golang-version packageName=golang
GOLANG_VERSION: '1.23.3'
GOLANG_VERSION: '1.24.6'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -109,10 +109,10 @@ jobs:
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Run golangci-lint
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
with:
# renovate: datasource=go packageName=github.com/golangci/golangci-lint versioning=regex:^v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?$
version: v1.62.2
version: v2.1.6
args: --verbose
test-go:
@@ -393,7 +393,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
uses: SonarSource/sonarqube-scan-action@1b442ee39ac3fa7c2acdd410208dcb2bcfaae6c4 # v4.1.0
uses: SonarSource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
if: env.sonar_secret != ''
test-e2e:
name: Run end-to-end tests
@@ -486,7 +486,7 @@ jobs:
run: |
docker pull ghcr.io/dexidp/dex:v2.41.1
docker pull argoproj/argo-cd-ci-builder:v1.0.0
docker pull redis:7.0.15-alpine
docker pull redis:7.2.11-alpine
- name: Create target directory for binaries in the build-process
run: |
mkdir -p dist
@@ -549,4 +549,4 @@ jobs:
exit 0
else
exit 1
fi
fi

View File

@@ -53,7 +53,7 @@ jobs:
with:
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.23.3
go-version: 1.24.6
platforms: ${{ needs.set-vars.outputs.platforms }}
push: false
@@ -70,7 +70,7 @@ jobs:
ghcr_image_name: ghcr.io/argoproj/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }}
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.23.3
go-version: 1.24.6
platforms: ${{ needs.set-vars.outputs.platforms }}
push: true
secrets:

View File

@@ -11,7 +11,7 @@ permissions: {}
env:
# renovate: datasource=golang-version packageName=golang
GOLANG_VERSION: '1.23.3' # Note: go-version must also be set in job argocd-image.with.go-version
GOLANG_VERSION: '1.24.6' # Note: go-version must also be set in job argocd-image.with.go-version
jobs:
argocd-image:
@@ -25,13 +25,49 @@ jobs:
quay_image_name: quay.io/argoproj/argocd:${{ github.ref_name }}
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
# renovate: datasource=golang-version packageName=golang
go-version: 1.23.3
go-version: 1.24.6
platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
push: true
secrets:
quay_username: ${{ secrets.RELEASE_QUAY_USERNAME }}
quay_password: ${{ secrets.RELEASE_QUAY_TOKEN }}
setup-variables:
name: Setup Release Variables
if: github.repository == 'argoproj/argo-cd'
runs-on: ubuntu-22.04
outputs:
is_pre_release: ${{ steps.var.outputs.is_pre_release }}
is_latest_release: ${{ steps.var.outputs.is_latest_release }}
steps:
- name: Checkout code
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup variables
id: var
run: |
set -xue
# Fetch all tag information
git fetch --prune --tags --force
LATEST_RELEASE_TAG=$(git -c 'versionsort.suffix=-rc' tag --list --sort=version:refname | grep -v '-' | tail -n1)
PRE_RELEASE=false
# Check if latest tag is a pre-release
if echo ${{ github.ref_name }} | grep -E -- '-rc[0-9]+$';then
PRE_RELEASE=true
fi
IS_LATEST=false
# Ensure latest release tag matches github.ref_name
if [[ $LATEST_RELEASE_TAG == ${{ github.ref_name }} ]];then
IS_LATEST=true
fi
echo "is_pre_release=$PRE_RELEASE" >> $GITHUB_OUTPUT
echo "is_latest_release=$IS_LATEST" >> $GITHUB_OUTPUT
argocd-image-provenance:
needs: [argocd-image]
permissions:
@@ -50,15 +86,17 @@ jobs:
goreleaser:
needs:
- setup-variables
- argocd-image
- argocd-image-provenance
permissions:
contents: write # used for uploading assets
if: github.repository == 'argoproj/argo-cd'
runs-on: ubuntu-22.04
env:
GORELEASER_MAKE_LATEST: ${{ needs.setup-variables.outputs.is_latest_release }}
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
steps:
- name: Checkout code
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
@@ -140,7 +178,7 @@ jobs:
permissions:
contents: write # Needed for release uploads
outputs:
hashes: ${{ steps.sbom-hash.outputs.hashes}}
hashes: ${{ steps.sbom-hash.outputs.hashes }}
if: github.repository == 'argoproj/argo-cd'
runs-on: ubuntu-22.04
steps:
@@ -218,6 +256,7 @@ jobs:
post-release:
needs:
- setup-variables
- argocd-image
- goreleaser
- generate-sbom
@@ -226,6 +265,8 @@ jobs:
pull-requests: write # Needed to create PR for VERSION update.
if: github.repository == 'argoproj/argo-cd'
runs-on: ubuntu-22.04
env:
TAG_STABLE: ${{ needs.setup-variables.outputs.is_latest_release }}
steps:
- name: Checkout code
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
@@ -239,27 +280,6 @@ jobs:
git config --global user.email 'ci@argoproj.com'
git config --global user.name 'CI'
- name: Check if tag is the latest version and not a pre-release
run: |
set -xue
# Fetch all tag information
git fetch --prune --tags --force
LATEST_TAG=$(git -c 'versionsort.suffix=-rc' tag --list --sort=version:refname | tail -n1)
PRE_RELEASE=false
# Check if latest tag is a pre-release
if echo $LATEST_TAG | grep -E -- '-rc[0-9]+$';then
PRE_RELEASE=true
fi
# Ensure latest tag matches github.ref_name & not a pre-release
if [[ $LATEST_TAG == ${{ github.ref_name }} ]] && [[ $PRE_RELEASE != 'true' ]];then
echo "TAG_STABLE=true" >> $GITHUB_ENV
else
echo "TAG_STABLE=false" >> $GITHUB_ENV
fi
- name: Update stable tag to latest version
run: |
git tag -f stable ${{ github.ref_name }}

View File

@@ -1,20 +1,12 @@
issues:
exclude:
- SA5011
max-issues-per-linter: 0
max-same-issues: 0
exclude-rules:
- path: '(.+)_test\.go'
linters:
- unparam
version: "2"
run:
timeout: 50m
linters:
default: none
enable:
- errcheck
- errorlint
- gocritic
- gofumpt
- goimports
- gosimple
- govet
- ineffassign
- misspell
@@ -25,35 +17,85 @@ linters:
- unparam
- unused
- usestdlibvars
- whitespace
linters-settings:
gocritic:
disabled-checks:
- appendAssign
- assignOp # Keep it disabled for readability
- badCond
- commentFormatting
- exitAfterDefer
- ifElseChain
- mapKey
- singleCaseSwitch
- typeSwitchVar
goimports:
local-prefixes: github.com/argoproj/argo-cd/v2
perfsprint:
# Optimizes even if it requires an int or uint type cast.
int-conversion: true
# Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.
err-error: false
# Optimizes `fmt.Errorf`.
errorf: false
# Optimizes `fmt.Sprintf` with only one argument.
sprintf1: true
# Optimizes into strings concatenation.
strconcat: false
testifylint:
enable-all: true
disable:
- go-require
run:
timeout: 50m
- whitespace
settings:
gocritic:
disabled-checks:
- appendAssign
- assignOp
- badCond
- commentFormatting
- exitAfterDefer
- ifElseChain
- mapKey
- singleCaseSwitch
- typeSwitchVar
perfsprint:
int-conversion: true
err-error: false
errorf: false
sprintf1: true
strconcat: false
staticcheck:
checks:
- "all"
- "-ST1001" # dot imports are discouraged
- "-ST1003" # poorly chosen identifier
- "-ST1005" # incorrectly formatted error string
- "-ST1011" # poorly chosen name for variable of type time.Duration
- "-ST1012" # poorly chosen name for an error variable
- "-ST1016" # use consistent method receiver names
- "-ST1017" # don't use Yoda conditions
- "-ST1019" # importing the same package multiple times
- "-ST1023" # redundant type in variable declaration
- "-QF1001" # apply De Morgans law
- "-QF1003" # convert if/else-if chain to tagged switch
- "-QF1006" # lift if+break into loop condition
- "-QF1007" # merge conditional assignment into variable declaration
- "-QF1008" # omit embedded fields from selector expression
- "-QF1009" # use time.Time.Equal instead of == operator
- "-QF1011" # omit redundant type from variable declaration
- "-QF1012" # use fmt.Fprintf(x, ...) instead of x.Write(fmt.Sprintf(...))
testifylint:
enable-all: true
disable:
- go-require
- equal-values
- empty
- len
- expected-actual
- formatter
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- unparam
path: (.+)_test\.go
- path: (.+)\.go$
text: SA5011
paths:
- third_party$
- builtin$
- examples$
issues:
max-issues-per-linter: 0
max-same-issues: 0
formatters:
enable:
- gofumpt
- goimports
settings:
goimports:
local-prefixes:
- github.com/argoproj/argo-cd/v2
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$

View File

@@ -46,16 +46,17 @@ builds:
archives:
- id: argocd-archive
builds:
- argocd-cli
- argocd-cli
name_template: |-
{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}
format: binary
formats: [binary]
checksum:
name_template: 'cli_checksums.txt'
algorithm: sha256
release:
make_latest: '{{ .Env.GORELEASER_MAKE_LATEST }}'
prerelease: auto
draft: false
header: |
@@ -85,16 +86,14 @@ release:
If upgrading from a different minor version, be sure to read the [upgrading](https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/overview/) documentation.
footer: |
**Full Changelog**: https://github.com/argoproj/argo-cd/compare/{{ .PreviousTag }}...{{ .Tag }}
<a href="https://argoproj.github.io/cd/"><img src="https://raw.githubusercontent.com/argoproj/argo-site/master/content/pages/cd/gitops-cd.png" width="25%" ></a>
snapshot: #### To be removed for PR
name_template: "2.6.0"
name_template: '2.6.0'
changelog:
use:
github
use: github
sort: asc
abbrev: 0
groups: # Regex use RE2 syntax as defined here: https://github.com/google/re2/wiki/Syntax.
@@ -117,7 +116,4 @@ changelog:
- '^test:'
- '^.*?Bump(\([[:word:]]+\))?.+$'
- '^.*?\[Bot\](\([[:word:]]+\))?.+$'
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json

View File

@@ -74,3 +74,6 @@ packages:
github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster:
interfaces:
ClusterServiceServer:
github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1:
interfaces:
AppProjectInterface:

View File

@@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8
# Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image
# Also used as the image in CI jobs so needs all dependencies
####################################################################################################
FROM docker.io/library/golang:1.23.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS builder
FROM docker.io/library/golang:1.24.6@sha256:2c89c41fb9efc3807029b59af69645867cfe978d2b877d475be0d72f6c6ce6f6 AS builder
RUN echo 'deb http://archive.debian.org/debian buster-backports main' >> /etc/apt/sources.list
@@ -101,7 +101,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP
####################################################################################################
# Argo CD Build stage which performs the actual build of Argo CD binaries
####################################################################################################
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.23.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS argocd-build
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24.6@sha256:2c89c41fb9efc3807029b59af69645867cfe978d2b877d475be0d72f6c6ce6f6 AS argocd-build
WORKDIR /go/src/github.com/argoproj/argo-cd

View File

@@ -1 +1 @@
2.14.2
2.14.21

View File

@@ -91,6 +91,7 @@ type ApplicationSetReconciler struct {
GlobalPreservedAnnotations []string
GlobalPreservedLabels []string
Metrics *metrics.ApplicationsetMetrics
MaxResourcesStatusCount int
}
// +kubebuilder:rbac:groups=argoproj.io,resources=applicationsets,verbs=get;list;watch;create;update;patch;delete
@@ -127,8 +128,8 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
}()
// Do not attempt to further reconcile the ApplicationSet if it is being deleted.
if applicationSetInfo.ObjectMeta.DeletionTimestamp != nil {
appsetName := applicationSetInfo.ObjectMeta.Name
if applicationSetInfo.DeletionTimestamp != nil {
appsetName := applicationSetInfo.Name
logCtx.Debugf("DeletionTimestamp is set on %s", appsetName)
deleteAllowed := utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowDelete()
if !deleteAllowed {
@@ -155,6 +156,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// desiredApplications is the main list of all expected Applications from all generators in this appset.
desiredApplications, applicationSetReason, err := template.GenerateApplications(logCtx, applicationSetInfo, r.Generators, r.Renderer, r.Client)
if err != nil {
logCtx.Errorf("unable to generate applications: %v", err)
_ = r.setApplicationSetStatusCondition(ctx,
&applicationSetInfo,
argov1alpha1.ApplicationSetCondition{
@@ -164,7 +166,8 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
Status: argov1alpha1.ApplicationSetConditionStatusTrue,
}, parametersGenerated,
)
return ctrl.Result{RequeueAfter: ReconcileRequeueOnValidationError}, err
// In order for the controller SDK to respect RequeueAfter, the error must be nil
return ctrl.Result{RequeueAfter: ReconcileRequeueOnValidationError}, nil
}
parametersGenerated = true
@@ -208,16 +211,16 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
appSyncMap := map[string]bool{}
if r.EnableProgressiveSyncs {
if applicationSetInfo.Spec.Strategy == nil && len(applicationSetInfo.Status.ApplicationStatus) > 0 {
// If appset used progressive sync but stopped, clean up the progressive sync application statuses
if !isRollingSyncStrategy(&applicationSetInfo) && len(applicationSetInfo.Status.ApplicationStatus) > 0 {
// If an appset was previously syncing with a `RollingSync` strategy but it has switched to the default strategy, clean up the progressive sync application statuses
logCtx.Infof("Removing %v unnecessary AppStatus entries from ApplicationSet %v", len(applicationSetInfo.Status.ApplicationStatus), applicationSetInfo.Name)
err := r.setAppSetApplicationStatus(ctx, logCtx, &applicationSetInfo, []argov1alpha1.ApplicationSetApplicationStatus{})
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to clear previous AppSet application statuses for %v: %w", applicationSetInfo.Name, err)
}
} else if applicationSetInfo.Spec.Strategy != nil {
// appset uses progressive sync
} else if isRollingSyncStrategy(&applicationSetInfo) {
// The appset uses progressive sync with `RollingSync` strategy
for _, app := range currentApplications {
appMap[app.Name] = app
}
@@ -312,7 +315,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
if applicationSetInfo.RefreshRequired() {
delete(applicationSetInfo.Annotations, common.AnnotationApplicationSetRefresh)
err := r.Client.Update(ctx, &applicationSetInfo)
err := r.Update(ctx, &applicationSetInfo)
if err != nil {
logCtx.Warnf("error occurred while updating ApplicationSet: %v", err)
_ = r.setApplicationSetStatusCondition(ctx,
@@ -487,7 +490,7 @@ func (r *ApplicationSetReconciler) validateGeneratedApplications(ctx context.Con
}
appProject := &argov1alpha1.AppProject{}
err := r.Client.Get(ctx, types.NamespacedName{Name: app.Spec.Project, Namespace: r.ArgoCDNamespace}, appProject)
err := r.Get(ctx, types.NamespacedName{Name: app.Spec.Project, Namespace: r.ArgoCDNamespace}, appProject)
if err != nil {
if apierr.IsNotFound(err) {
errorsByIndex[i] = fmt.Errorf("application references project %s which does not exist", app.Spec.Project)
@@ -551,12 +554,13 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProg
return fmt.Errorf("error setting up with manager: %w", err)
}
ownsHandler := getOwnsHandlerPredicates(enableProgressiveSyncs)
appOwnsHandler := getApplicationOwnsHandler(enableProgressiveSyncs)
appSetOwnsHandler := getApplicationSetOwnsHandler(enableProgressiveSyncs)
return ctrl.NewControllerManagedBy(mgr).WithOptions(controller.Options{
MaxConcurrentReconciles: maxConcurrentReconciliations,
}).For(&argov1alpha1.ApplicationSet{}).
Owns(&argov1alpha1.Application{}, builder.WithPredicates(ownsHandler)).
}).For(&argov1alpha1.ApplicationSet{}, builder.WithPredicates(appSetOwnsHandler)).
Owns(&argov1alpha1.Application{}, builder.WithPredicates(appOwnsHandler)).
WithEventFilter(ignoreNotAllowedNamespaces(r.ApplicationSetNamespaces)).
Watches(
&corev1.Secret{},
@@ -564,7 +568,6 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProg
Client: mgr.GetClient(),
Log: log.WithField("type", "createSecretEventHandler"),
}).
// TODO: also watch Applications and respond on changes if we own them.
Complete(r)
}
@@ -623,7 +626,7 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
preservedAnnotations = append(preservedAnnotations, defaultPreservedAnnotations...)
for _, key := range preservedAnnotations {
if state, exists := found.ObjectMeta.Annotations[key]; exists {
if state, exists := found.Annotations[key]; exists {
if generatedApp.Annotations == nil {
generatedApp.Annotations = map[string]string{}
}
@@ -632,7 +635,7 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
}
for _, key := range preservedLabels {
if state, exists := found.ObjectMeta.Labels[key]; exists {
if state, exists := found.Labels[key]; exists {
if generatedApp.Labels == nil {
generatedApp.Labels = map[string]string{}
}
@@ -642,7 +645,7 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
// Preserve post-delete finalizers:
// https://github.com/argoproj/argo-cd/issues/17181
for _, finalizer := range found.ObjectMeta.Finalizers {
for _, finalizer := range found.Finalizers {
if strings.HasPrefix(finalizer, argov1alpha1.PostDeleteFinalizerName) {
if generatedApp.Finalizers == nil {
generatedApp.Finalizers = []string{}
@@ -651,10 +654,10 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
}
}
found.ObjectMeta.Annotations = generatedApp.Annotations
found.Annotations = generatedApp.Annotations
found.ObjectMeta.Finalizers = generatedApp.Finalizers
found.ObjectMeta.Labels = generatedApp.Labels
found.Finalizers = generatedApp.Finalizers
found.Labels = generatedApp.Labels
return controllerutil.SetControllerReference(&applicationSet, found, r.Scheme)
})
@@ -708,7 +711,7 @@ func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, logCtx *
func (r *ApplicationSetReconciler) getCurrentApplications(ctx context.Context, applicationSet argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, error) {
var current argov1alpha1.ApplicationList
err := r.Client.List(ctx, &current, client.MatchingFields{".metadata.controller": applicationSet.Name}, client.InNamespace(applicationSet.Namespace))
err := r.List(ctx, &current, client.MatchingFields{".metadata.controller": applicationSet.Name}, client.InNamespace(applicationSet.Namespace))
if err != nil {
return nil, fmt.Errorf("error retrieving applications: %w", err)
}
@@ -719,9 +722,6 @@ func (r *ApplicationSetReconciler) getCurrentApplications(ctx context.Context, a
// deleteInCluster will delete Applications that are currently on the cluster, but not in appList.
// The function must be called after all generators had been called and generated applications
func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error {
// settingsMgr := settings.NewSettingsManager(context.TODO(), r.KubeClientset, applicationSet.Namespace)
// argoDB := db.NewDB(applicationSet.Namespace, settingsMgr, r.KubeClientset)
// clusterList, err := argoDB.ListClusters(ctx)
clusterList, err := utils.ListClusters(ctx, r.KubeClientset, r.ArgoCDNamespace)
if err != nil {
return fmt.Errorf("error listing clusters: %w", err)
@@ -756,7 +756,7 @@ func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, logCtx *
continue
}
err = r.Client.Delete(ctx, &app)
err = r.Delete(ctx, &app)
if err != nil {
logCtx.WithError(err).Error("failed to delete Application")
if firstError != nil {
@@ -828,7 +828,7 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte
if log.IsLevelEnabled(log.DebugLevel) {
utils.LogPatch(appLog, patch, updated)
}
if err := r.Client.Patch(ctx, updated, patch); err != nil {
if err := r.Patch(ctx, updated, patch); err != nil {
return fmt.Errorf("error updating finalizers: %w", err)
}
// Application must have updated list of finalizers
@@ -850,7 +850,7 @@ func (r *ApplicationSetReconciler) removeOwnerReferencesOnDeleteAppSet(ctx conte
for _, app := range applications {
app.SetOwnerReferences([]metav1.OwnerReference{})
err := r.Client.Update(ctx, &app)
err := r.Update(ctx, &app)
if err != nil {
return fmt.Errorf("error updating application: %w", err)
}
@@ -1006,8 +1006,14 @@ func appSyncEnabledForNextStep(appset *argov1alpha1.ApplicationSet, app argov1al
return true
}
func isRollingSyncStrategy(appset *argov1alpha1.ApplicationSet) bool {
// It's only RollingSync if the type specifically sets it
return appset.Spec.Strategy != nil && appset.Spec.Strategy.Type == "RollingSync" && appset.Spec.Strategy.RollingSync != nil
}
func progressiveSyncsRollingSyncStrategyEnabled(appset *argov1alpha1.ApplicationSet) bool {
return appset.Spec.Strategy != nil && appset.Spec.Strategy.RollingSync != nil && appset.Spec.Strategy.Type == "RollingSync" && len(appset.Spec.Strategy.RollingSync.Steps) > 0
// ProgressiveSync is enabled if the strategy is set to `RollingSync` + steps slice is not empty
return isRollingSyncStrategy(appset) && len(appset.Spec.Strategy.RollingSync.Steps) > 0
}
func isApplicationHealthy(app argov1alpha1.Application) bool {
@@ -1060,19 +1066,20 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con
Message: "No Application status found, defaulting status to Waiting.",
Status: "Waiting",
Step: strconv.Itoa(getAppStep(app.Name, appStepMap)),
TargetRevisions: app.Status.GetRevisions(),
}
} else {
// we have an existing AppStatus
currentAppStatus = applicationSet.Status.ApplicationStatus[idx]
// upgrade any existing AppStatus that might have been set by an older argo-cd version
// note: currentAppStatus.TargetRevisions may be set to empty list earlier during migrations,
// to prevent other usage of r.Client.Status().Update to fail before reaching here.
if len(currentAppStatus.TargetRevisions) == 0 {
currentAppStatus.TargetRevisions = app.Status.GetRevisions()
if !reflect.DeepEqual(currentAppStatus.TargetRevisions, app.Status.GetRevisions()) {
currentAppStatus.Message = "Application has pending changes, setting status to Waiting."
}
}
if !reflect.DeepEqual(currentAppStatus.TargetRevisions, app.Status.GetRevisions()) {
currentAppStatus.TargetRevisions = app.Status.GetRevisions()
currentAppStatus.Status = "Waiting"
currentAppStatus.LastTransitionTime = &now
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
}
appOutdated := false
if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) {
@@ -1085,25 +1092,15 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con
currentAppStatus.Status = "Waiting"
currentAppStatus.Message = "Application has pending changes, setting status to Waiting."
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
currentAppStatus.TargetRevisions = app.Status.GetRevisions()
}
if currentAppStatus.Status == "Pending" {
if operationPhaseString == "Succeeded" {
revisions := []string{}
if len(app.Status.OperationState.SyncResult.Revisions) > 0 {
revisions = app.Status.OperationState.SyncResult.Revisions
} else if app.Status.OperationState.SyncResult.Revision != "" {
revisions = append(revisions, app.Status.OperationState.SyncResult.Revision)
}
if reflect.DeepEqual(currentAppStatus.TargetRevisions, revisions) {
logCtx.Infof("Application %v has completed a sync successfully, updating its ApplicationSet status to Progressing", app.Name)
currentAppStatus.LastTransitionTime = &now
currentAppStatus.Status = "Progressing"
currentAppStatus.Message = "Application resource completed a sync successfully, updating status from Pending to Progressing."
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
}
if !appOutdated && operationPhaseString == "Succeeded" {
logCtx.Infof("Application %v has completed a sync successfully, updating its ApplicationSet status to Progressing", app.Name)
currentAppStatus.LastTransitionTime = &now
currentAppStatus.Status = "Progressing"
currentAppStatus.Message = "Application resource completed a sync successfully, updating status from Pending to Progressing."
currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap))
} else if operationPhaseString == "Running" || healthStatusString == "Progressing" {
logCtx.Infof("Application %v has entered Progressing status, updating its ApplicationSet status to Progressing", app.Name)
currentAppStatus.LastTransitionTime = &now
@@ -1318,6 +1315,11 @@ func (r *ApplicationSetReconciler) updateResourcesStatus(ctx context.Context, lo
sort.Slice(statuses, func(i, j int) bool {
return statuses[i].Name < statuses[j].Name
})
if r.MaxResourcesStatusCount > 0 && len(statuses) > r.MaxResourcesStatusCount {
logCtx.Warnf("Truncating ApplicationSet %s resource status from %d to max allowed %d entries", appset.Name, len(statuses), r.MaxResourcesStatusCount)
statuses = statuses[:r.MaxResourcesStatusCount]
}
appset.Status.Resources = statuses
// DefaultRetry will retry 5 times with a backoff factor of 1, jitter of 0.1 and a duration of 10ms
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
@@ -1465,7 +1467,7 @@ func syncApplication(application argov1alpha1.Application, prune bool) argov1alp
return application
}
func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs {
func getApplicationOwnsHandler(enableProgressiveSyncs bool) predicate.Funcs {
return predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
// if we are the owner and there is a create event, we most likely created it and do not need to
@@ -1502,8 +1504,8 @@ func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs {
if !isApp {
return false
}
requeue := shouldRequeueApplicationSet(appOld, appNew, enableProgressiveSyncs)
logCtx.WithField("requeue", requeue).Debugf("requeue: %t caused by application %s", requeue, appNew.Name)
requeue := shouldRequeueForApplication(appOld, appNew, enableProgressiveSyncs)
logCtx.WithField("requeue", requeue).Debugf("requeue caused by application %s", appNew.Name)
return requeue
},
GenericFunc: func(e event.GenericEvent) bool {
@@ -1520,13 +1522,13 @@ func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs {
}
}
// shouldRequeueApplicationSet determines when we want to requeue an ApplicationSet for reconciling based on an owned
// shouldRequeueForApplication determines when we want to requeue an ApplicationSet for reconciling based on an owned
// application change
// The applicationset controller owns a subset of the Application CR.
// We do not need to re-reconcile if parts of the application change outside the applicationset's control.
// An example being, Application.ApplicationStatus.ReconciledAt which gets updated by the application controller.
// Additionally, Application.ObjectMeta.ResourceVersion and Application.ObjectMeta.Generation which are set by K8s.
func shouldRequeueApplicationSet(appOld *argov1alpha1.Application, appNew *argov1alpha1.Application, enableProgressiveSyncs bool) bool {
func shouldRequeueForApplication(appOld *argov1alpha1.Application, appNew *argov1alpha1.Application, enableProgressiveSyncs bool) bool {
if appOld == nil || appNew == nil {
return false
}
@@ -1536,9 +1538,9 @@ func shouldRequeueApplicationSet(appOld *argov1alpha1.Application, appNew *argov
// https://pkg.go.dev/reflect#DeepEqual
// ApplicationDestination has an unexported field so we can just use the == for comparison
if !cmp.Equal(appOld.Spec, appNew.Spec, cmpopts.EquateEmpty(), cmpopts.EquateComparable(argov1alpha1.ApplicationDestination{})) ||
!cmp.Equal(appOld.ObjectMeta.GetAnnotations(), appNew.ObjectMeta.GetAnnotations(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appOld.ObjectMeta.GetLabels(), appNew.ObjectMeta.GetLabels(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appOld.ObjectMeta.GetFinalizers(), appNew.ObjectMeta.GetFinalizers(), cmpopts.EquateEmpty()) {
!cmp.Equal(appOld.GetAnnotations(), appNew.GetAnnotations(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appOld.GetLabels(), appNew.GetLabels(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appOld.GetFinalizers(), appNew.GetFinalizers(), cmpopts.EquateEmpty()) {
return true
}
@@ -1559,4 +1561,90 @@ func shouldRequeueApplicationSet(appOld *argov1alpha1.Application, appNew *argov
return false
}
func getApplicationSetOwnsHandler(enableProgressiveSyncs bool) predicate.Funcs {
return predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
appSet, isApp := e.Object.(*argov1alpha1.ApplicationSet)
if !isApp {
return false
}
log.WithField("applicationset", appSet.QualifiedName()).Debugln("received create event")
// Always queue a new applicationset
return true
},
DeleteFunc: func(e event.DeleteEvent) bool {
appSet, isApp := e.Object.(*argov1alpha1.ApplicationSet)
if !isApp {
return false
}
log.WithField("applicationset", appSet.QualifiedName()).Debugln("received delete event")
// Always queue for the deletion of an applicationset
return true
},
UpdateFunc: func(e event.UpdateEvent) bool {
appSetOld, isAppSet := e.ObjectOld.(*argov1alpha1.ApplicationSet)
if !isAppSet {
return false
}
appSetNew, isAppSet := e.ObjectNew.(*argov1alpha1.ApplicationSet)
if !isAppSet {
return false
}
requeue := shouldRequeueForApplicationSet(appSetOld, appSetNew, enableProgressiveSyncs)
log.WithField("applicationset", appSetNew.QualifiedName()).
WithField("requeue", requeue).Debugln("received update event")
return requeue
},
GenericFunc: func(e event.GenericEvent) bool {
appSet, isApp := e.Object.(*argov1alpha1.ApplicationSet)
if !isApp {
return false
}
log.WithField("applicationset", appSet.QualifiedName()).Debugln("received generic event")
// Always queue for the generic of an applicationset
return true
},
}
}
// shouldRequeueForApplicationSet determines when we need to requeue an applicationset
func shouldRequeueForApplicationSet(appSetOld, appSetNew *argov1alpha1.ApplicationSet, enableProgressiveSyncs bool) bool {
if appSetOld == nil || appSetNew == nil {
return false
}
// Requeue if any ApplicationStatus.Status changed for Progressive sync strategy
if enableProgressiveSyncs {
if !cmp.Equal(appSetOld.Status.ApplicationStatus, appSetNew.Status.ApplicationStatus, cmpopts.EquateEmpty()) {
return true
}
}
// only compare the applicationset spec, annotations, labels and finalizers, deletionTimestamp, specifically avoiding
// the status field. status is owned by the applicationset controller,
// and we do not need to requeue when it does bookkeeping
// NB: the ApplicationDestination comes from the ApplicationSpec being embedded
// in the ApplicationSetTemplate from the generators
if !cmp.Equal(appSetOld.Spec, appSetNew.Spec, cmpopts.EquateEmpty(), cmpopts.EquateComparable(argov1alpha1.ApplicationDestination{})) ||
!cmp.Equal(appSetOld.GetLabels(), appSetNew.GetLabels(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appSetOld.GetFinalizers(), appSetNew.GetFinalizers(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appSetOld.DeletionTimestamp, appSetNew.DeletionTimestamp, cmpopts.EquateEmpty()) {
return true
}
// Requeue only when the refresh annotation is newly added to the ApplicationSet.
// Changes to other annotations made simultaneously might be missed, but such cases are rare.
if !cmp.Equal(appSetOld.GetAnnotations(), appSetNew.GetAnnotations(), cmpopts.EquateEmpty()) {
_, oldHasRefreshAnnotation := appSetOld.Annotations[common.AnnotationApplicationSetRefresh]
_, newHasRefreshAnnotation := appSetNew.Annotations[common.AnnotationApplicationSetRefresh]
if oldHasRefreshAnnotation && !newHasRefreshAnnotation {
return false
}
return true
}
return false
}
var _ handler.EventHandler = &clusterSecretEventHandler{}

View File

@@ -1885,7 +1885,7 @@ func TestRequeueGeneratorFails(t *testing.T) {
}
res, err := r.Reconcile(context.Background(), req)
require.Error(t, err)
require.NoError(t, err)
assert.Equal(t, ReconcileRequeueOnValidationError, res.RequeueAfter)
}
@@ -4733,6 +4733,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
Health: v1alpha1.HealthStatus{
Status: health.HealthStatusProgressing,
},
Sync: v1alpha1.SyncStatus{
Revision: "Next",
},
},
},
},
@@ -4796,7 +4799,8 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
Phase: common.OperationRunning,
},
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
Status: v1alpha1.SyncStatusCodeSynced,
Revision: "Current",
},
},
},
@@ -4861,7 +4865,8 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
Phase: common.OperationSucceeded,
},
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
Status: v1alpha1.SyncStatusCodeSynced,
Revision: "Next",
},
},
},
@@ -4926,7 +4931,8 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
Phase: common.OperationSucceeded,
},
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
Revision: "Current",
Status: v1alpha1.SyncStatusCodeSynced,
},
},
},
@@ -5165,86 +5171,6 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
},
},
},
{
name: "does not progresses a pending application with a successful sync triggered by controller with invalid revision to progressing",
appSet: v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "argocd",
},
Spec: v1alpha1.ApplicationSetSpec{
Strategy: &v1alpha1.ApplicationSetStrategy{
Type: "RollingSync",
RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{
Steps: []v1alpha1.ApplicationSetRolloutStep{
{
MatchExpressions: []v1alpha1.ApplicationMatchExpression{},
},
{
MatchExpressions: []v1alpha1.ApplicationMatchExpression{},
},
},
},
},
},
Status: v1alpha1.ApplicationSetStatus{
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
LastTransitionTime: &metav1.Time{
Time: time.Now().Add(time.Duration(-1) * time.Minute),
},
Message: "",
Status: "Pending",
Step: "1",
TargetRevisions: []string{"Next"},
},
},
},
},
apps: []v1alpha1.Application{
{
ObjectMeta: metav1.ObjectMeta{
Name: "app1",
},
Status: v1alpha1.ApplicationStatus{
Health: v1alpha1.HealthStatus{
Status: health.HealthStatusDegraded,
},
OperationState: &v1alpha1.OperationState{
Phase: common.OperationSucceeded,
StartedAt: metav1.Time{
Time: time.Now(),
},
Operation: v1alpha1.Operation{
InitiatedBy: v1alpha1.OperationInitiator{
Username: "applicationset-controller",
Automated: true,
},
},
SyncResult: &v1alpha1.SyncOperationResult{
Revision: "Previous",
},
},
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
},
},
},
},
appStepMap: map[string]int{
"app1": 0,
},
expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
Message: "",
Status: "Pending",
Step: "1",
TargetRevisions: []string{"Next"},
},
},
},
{
name: "removes the appStatus for applications that no longer exist",
appSet: v1alpha1.ApplicationSet{
@@ -5299,7 +5225,77 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
Phase: common.OperationSucceeded,
},
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
Status: v1alpha1.SyncStatusCodeSynced,
Revision: "Current",
},
},
},
},
appStepMap: map[string]int{
"app1": 0,
},
expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
Message: "Application resource is already Healthy, updating status from Waiting to Healthy.",
Status: "Healthy",
Step: "1",
TargetRevisions: []string{"Current"},
},
},
},
{
name: "progresses a pending synced application with an old revision to progressing with the Current one",
appSet: v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "argocd",
},
Spec: v1alpha1.ApplicationSetSpec{
Strategy: &v1alpha1.ApplicationSetStrategy{
Type: "RollingSync",
RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{
Steps: []v1alpha1.ApplicationSetRolloutStep{
{
MatchExpressions: []v1alpha1.ApplicationMatchExpression{},
},
{
MatchExpressions: []v1alpha1.ApplicationMatchExpression{},
},
},
},
},
},
Status: v1alpha1.ApplicationSetStatus{
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
Message: "",
Status: "Pending",
Step: "1",
TargetRevisions: []string{"Old"},
},
},
},
},
apps: []v1alpha1.Application{
{
ObjectMeta: metav1.ObjectMeta{
Name: "app1",
},
Status: v1alpha1.ApplicationStatus{
Health: v1alpha1.HealthStatus{
Status: health.HealthStatusHealthy,
},
OperationState: &v1alpha1.OperationState{
Phase: common.OperationSucceeded,
SyncResult: &v1alpha1.SyncOperationResult{
Revision: "Current",
},
},
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
Revisions: []string{"Current"},
},
},
},
@@ -6101,10 +6097,11 @@ func TestUpdateResourceStatus(t *testing.T) {
require.NoError(t, err)
for _, cc := range []struct {
name string
appSet v1alpha1.ApplicationSet
apps []v1alpha1.Application
expectedResources []v1alpha1.ResourceStatus
name string
appSet v1alpha1.ApplicationSet
apps []v1alpha1.Application
expectedResources []v1alpha1.ResourceStatus
maxResourcesStatusCount int
}{
{
name: "handles an empty application list",
@@ -6275,6 +6272,73 @@ func TestUpdateResourceStatus(t *testing.T) {
apps: []v1alpha1.Application{},
expectedResources: nil,
},
{
name: "truncates resources status list to",
appSet: v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "argocd",
},
Status: v1alpha1.ApplicationSetStatus{
Resources: []v1alpha1.ResourceStatus{
{
Name: "app1",
Status: v1alpha1.SyncStatusCodeOutOfSync,
Health: &v1alpha1.HealthStatus{
Status: health.HealthStatusProgressing,
Message: "this is progressing",
},
},
{
Name: "app2",
Status: v1alpha1.SyncStatusCodeOutOfSync,
Health: &v1alpha1.HealthStatus{
Status: health.HealthStatusProgressing,
Message: "this is progressing",
},
},
},
},
},
apps: []v1alpha1.Application{
{
ObjectMeta: metav1.ObjectMeta{
Name: "app1",
},
Status: v1alpha1.ApplicationStatus{
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
},
Health: v1alpha1.HealthStatus{
Status: health.HealthStatusHealthy,
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "app2",
},
Status: v1alpha1.ApplicationStatus{
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
},
Health: v1alpha1.HealthStatus{
Status: health.HealthStatusHealthy,
},
},
},
},
expectedResources: []v1alpha1.ResourceStatus{
{
Name: "app1",
Status: v1alpha1.SyncStatusCodeSynced,
Health: &v1alpha1.HealthStatus{
Status: health.HealthStatusHealthy,
},
},
},
maxResourcesStatusCount: 1,
},
} {
t.Run(cc.name, func(t *testing.T) {
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
@@ -6283,13 +6347,14 @@ func TestUpdateResourceStatus(t *testing.T) {
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
r := ApplicationSetReconciler{
Client: client,
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &dbmocks.ArgoDB{},
KubeClientset: kubeclientset,
Metrics: metrics,
Client: client,
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &dbmocks.ArgoDB{},
KubeClientset: kubeclientset,
Metrics: metrics,
MaxResourcesStatusCount: cc.maxResourcesStatusCount,
}
err := r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps)
@@ -6397,11 +6462,11 @@ func TestResourceStatusAreOrdered(t *testing.T) {
func TestOwnsHandler(t *testing.T) {
// progressive syncs do not affect create, delete, or generic
ownsHandler := getOwnsHandlerPredicates(true)
ownsHandler := getApplicationOwnsHandler(true)
assert.False(t, ownsHandler.CreateFunc(event.CreateEvent{}))
assert.True(t, ownsHandler.DeleteFunc(event.DeleteEvent{}))
assert.True(t, ownsHandler.GenericFunc(event.GenericEvent{}))
ownsHandler = getOwnsHandlerPredicates(false)
ownsHandler = getApplicationOwnsHandler(false)
assert.False(t, ownsHandler.CreateFunc(event.CreateEvent{}))
assert.True(t, ownsHandler.DeleteFunc(event.DeleteEvent{}))
assert.True(t, ownsHandler.GenericFunc(event.GenericEvent{}))
@@ -6581,7 +6646,7 @@ func TestOwnsHandler(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ownsHandler = getOwnsHandlerPredicates(tt.args.enableProgressiveSyncs)
ownsHandler = getApplicationOwnsHandler(tt.args.enableProgressiveSyncs)
assert.Equalf(t, tt.want, ownsHandler.UpdateFunc(tt.args.e), "UpdateFunc(%v)", tt.args.e)
})
}
@@ -6658,6 +6723,358 @@ func TestMigrateStatus(t *testing.T) {
}
}
func TestApplicationSetOwnsHandlerUpdate(t *testing.T) {
buildAppSet := func(annotations map[string]string) *v1alpha1.ApplicationSet {
return &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Annotations: annotations,
},
}
}
tests := []struct {
name string
appSetOld crtclient.Object
appSetNew crtclient.Object
enableProgressiveSyncs bool
want bool
}{
{
name: "Different Spec",
appSetOld: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Generators: []v1alpha1.ApplicationSetGenerator{
{List: &v1alpha1.ListGenerator{}},
},
},
},
appSetNew: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Generators: []v1alpha1.ApplicationSetGenerator{
{Git: &v1alpha1.GitGenerator{}},
},
},
},
enableProgressiveSyncs: false,
want: true,
},
{
name: "Different Annotations",
appSetOld: buildAppSet(map[string]string{"key1": "value1"}),
appSetNew: buildAppSet(map[string]string{"key1": "value2"}),
enableProgressiveSyncs: false,
want: true,
},
{
name: "Different Labels",
appSetOld: &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"key1": "value1"},
},
},
appSetNew: &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"key1": "value2"},
},
},
enableProgressiveSyncs: false,
want: true,
},
{
name: "Different Finalizers",
appSetOld: &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Finalizers: []string{"finalizer1"},
},
},
appSetNew: &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Finalizers: []string{"finalizer2"},
},
},
enableProgressiveSyncs: false,
want: true,
},
{
name: "No Changes",
appSetOld: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Generators: []v1alpha1.ApplicationSetGenerator{
{List: &v1alpha1.ListGenerator{}},
},
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{"key1": "value1"},
Labels: map[string]string{"key1": "value1"},
Finalizers: []string{"finalizer1"},
},
},
appSetNew: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Generators: []v1alpha1.ApplicationSetGenerator{
{List: &v1alpha1.ListGenerator{}},
},
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{"key1": "value1"},
Labels: map[string]string{"key1": "value1"},
Finalizers: []string{"finalizer1"},
},
},
enableProgressiveSyncs: false,
want: false,
},
{
name: "annotation removed",
appSetOld: buildAppSet(map[string]string{
argocommon.AnnotationApplicationSetRefresh: "true",
}),
appSetNew: buildAppSet(map[string]string{}),
enableProgressiveSyncs: false,
want: false,
},
{
name: "annotation not removed",
appSetOld: buildAppSet(map[string]string{
argocommon.AnnotationApplicationSetRefresh: "true",
}),
appSetNew: buildAppSet(map[string]string{
argocommon.AnnotationApplicationSetRefresh: "true",
}),
enableProgressiveSyncs: false,
want: false,
},
{
name: "annotation added",
appSetOld: buildAppSet(map[string]string{}),
appSetNew: buildAppSet(map[string]string{
argocommon.AnnotationApplicationSetRefresh: "true",
}),
enableProgressiveSyncs: false,
want: true,
},
{
name: "old object is not an appset",
appSetOld: &v1alpha1.Application{},
appSetNew: buildAppSet(map[string]string{}),
enableProgressiveSyncs: false,
want: false,
},
{
name: "new object is not an appset",
appSetOld: buildAppSet(map[string]string{}),
appSetNew: &v1alpha1.Application{},
enableProgressiveSyncs: false,
want: false,
},
{
name: "deletionTimestamp present when progressive sync enabled",
appSetOld: buildAppSet(map[string]string{}),
appSetNew: &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
DeletionTimestamp: &metav1.Time{Time: time.Now()},
},
},
enableProgressiveSyncs: true,
want: true,
},
{
name: "deletionTimestamp present when progressive sync disabled",
appSetOld: buildAppSet(map[string]string{}),
appSetNew: &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
DeletionTimestamp: &metav1.Time{Time: time.Now()},
},
},
enableProgressiveSyncs: false,
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ownsHandler := getApplicationSetOwnsHandler(tt.enableProgressiveSyncs)
requeue := ownsHandler.UpdateFunc(event.UpdateEvent{
ObjectOld: tt.appSetOld,
ObjectNew: tt.appSetNew,
})
assert.Equalf(t, tt.want, requeue, "ownsHandler.UpdateFunc(%v, %v, %t)", tt.appSetOld, tt.appSetNew, tt.enableProgressiveSyncs)
})
}
}
func TestApplicationSetOwnsHandlerGeneric(t *testing.T) {
ownsHandler := getApplicationSetOwnsHandler(false)
tests := []struct {
name string
obj crtclient.Object
want bool
}{
{
name: "Object is ApplicationSet",
obj: &v1alpha1.ApplicationSet{},
want: true,
},
{
name: "Object is not ApplicationSet",
obj: &v1alpha1.Application{},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
requeue := ownsHandler.GenericFunc(event.GenericEvent{
Object: tt.obj,
})
assert.Equalf(t, tt.want, requeue, "ownsHandler.GenericFunc(%v)", tt.obj)
})
}
}
func TestApplicationSetOwnsHandlerCreate(t *testing.T) {
ownsHandler := getApplicationSetOwnsHandler(false)
tests := []struct {
name string
obj crtclient.Object
want bool
}{
{
name: "Object is ApplicationSet",
obj: &v1alpha1.ApplicationSet{},
want: true,
},
{
name: "Object is not ApplicationSet",
obj: &v1alpha1.Application{},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
requeue := ownsHandler.CreateFunc(event.CreateEvent{
Object: tt.obj,
})
assert.Equalf(t, tt.want, requeue, "ownsHandler.CreateFunc(%v)", tt.obj)
})
}
}
func TestApplicationSetOwnsHandlerDelete(t *testing.T) {
ownsHandler := getApplicationSetOwnsHandler(false)
tests := []struct {
name string
obj crtclient.Object
want bool
}{
{
name: "Object is ApplicationSet",
obj: &v1alpha1.ApplicationSet{},
want: true,
},
{
name: "Object is not ApplicationSet",
obj: &v1alpha1.Application{},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
requeue := ownsHandler.DeleteFunc(event.DeleteEvent{
Object: tt.obj,
})
assert.Equalf(t, tt.want, requeue, "ownsHandler.DeleteFunc(%v)", tt.obj)
})
}
}
func TestShouldRequeueForApplicationSet(t *testing.T) {
type args struct {
appSetOld *v1alpha1.ApplicationSet
appSetNew *v1alpha1.ApplicationSet
enableProgressiveSyncs bool
}
tests := []struct {
name string
args args
want bool
}{
{
name: "NilAppSet",
args: args{
appSetNew: &v1alpha1.ApplicationSet{},
appSetOld: nil,
enableProgressiveSyncs: false,
},
want: false,
},
{
name: "ApplicationSetApplicationStatusChanged",
args: args{
appSetOld: &v1alpha1.ApplicationSet{
Status: v1alpha1.ApplicationSetStatus{
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
Status: "Healthy",
},
},
},
},
appSetNew: &v1alpha1.ApplicationSet{
Status: v1alpha1.ApplicationSetStatus{
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
Status: "Waiting",
},
},
},
},
enableProgressiveSyncs: true,
},
want: true,
},
{
name: "ApplicationSetWithDeletionTimestamp",
args: args{
appSetOld: &v1alpha1.ApplicationSet{
Status: v1alpha1.ApplicationSetStatus{
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
Status: "Healthy",
},
},
},
},
appSetNew: &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
DeletionTimestamp: &metav1.Time{Time: time.Now()},
},
Status: v1alpha1.ApplicationSetStatus{
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
{
Application: "app1",
Status: "Waiting",
},
},
},
},
enableProgressiveSyncs: false,
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, shouldRequeueForApplicationSet(tt.args.appSetOld, tt.args.appSetNew, tt.args.enableProgressiveSyncs), "shouldRequeueForApplicationSet(%v, %v)", tt.args.appSetOld, tt.args.appSetNew)
})
}
}
func TestIgnoreNotAllowedNamespaces(t *testing.T) {
tests := []struct {
name string
@@ -6740,3 +7157,62 @@ func TestIgnoreNotAllowedNamespaces(t *testing.T) {
})
}
}
func TestIsRollingSyncStrategy(t *testing.T) {
tests := []struct {
name string
appset *v1alpha1.ApplicationSet
expected bool
}{
{
name: "RollingSync strategy is explicitly set",
appset: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Strategy: &v1alpha1.ApplicationSetStrategy{
Type: "RollingSync",
RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{
Steps: []v1alpha1.ApplicationSetRolloutStep{},
},
},
},
},
expected: true,
},
{
name: "AllAtOnce strategy is explicitly set",
appset: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Strategy: &v1alpha1.ApplicationSetStrategy{
Type: "AllAtOnce",
},
},
},
expected: false,
},
{
name: "Strategy is empty",
appset: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Strategy: &v1alpha1.ApplicationSetStrategy{},
},
},
expected: false,
},
{
name: "Strategy is nil",
appset: &v1alpha1.ApplicationSet{
Spec: v1alpha1.ApplicationSetSpec{
Strategy: nil,
},
},
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := isRollingSyncStrategy(tt.appset)
assert.Equal(t, tt.expected, result)
})
}
}

View File

@@ -28,10 +28,11 @@ type GitGenerator struct {
namespace string
}
func NewGitGenerator(repos services.Repos, namespace string) Generator {
// NewGitGenerator creates a new instance of Git Generator
func NewGitGenerator(repos services.Repos, controllerNamespace string) Generator {
g := &GitGenerator{
repos: repos,
namespace: namespace,
namespace: controllerNamespace,
}
return g
@@ -70,11 +71,11 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic
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
controllerNamespace := g.namespace
if controllerNamespace == "" {
controllerNamespace = appSet.Namespace
}
if err := client.Get(context.TODO(), types.NamespacedName{Name: project, Namespace: namespace}, appProject); err != nil {
if err := client.Get(context.TODO(), types.NamespacedName{Name: project, Namespace: controllerNamespace}, 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

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -10,15 +10,15 @@ import (
"github.com/argoproj/argo-cd/v2/applicationset/services"
)
func GetGenerators(ctx context.Context, c client.Client, k8sClient kubernetes.Interface, namespace string, argoCDService services.Repos, dynamicClient dynamic.Interface, scmConfig SCMConfig) map[string]Generator {
func GetGenerators(ctx context.Context, c client.Client, k8sClient kubernetes.Interface, controllerNamespace string, argoCDService services.Repos, dynamicClient dynamic.Interface, scmConfig SCMConfig) map[string]Generator {
terminalGenerators := map[string]Generator{
"List": NewListGenerator(),
"Clusters": NewClusterGenerator(c, ctx, k8sClient, namespace),
"Git": NewGitGenerator(argoCDService, namespace),
"Clusters": NewClusterGenerator(c, ctx, k8sClient, controllerNamespace),
"Git": NewGitGenerator(argoCDService, controllerNamespace),
"SCMProvider": NewSCMProviderGenerator(c, scmConfig),
"ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, namespace),
"ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, controllerNamespace),
"PullRequest": NewPullRequestGenerator(c, scmConfig),
"Plugin": NewPluginGenerator(c, ctx, k8sClient, namespace),
"Plugin": NewPluginGenerator(c, ctx, k8sClient, controllerNamespace),
}
nestedGenerators := map[string]Generator{

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -25,10 +25,14 @@ import (
"github.com/go-playground/webhooks/v6/github"
"github.com/go-playground/webhooks/v6/gitlab"
log "github.com/sirupsen/logrus"
"github.com/argoproj/argo-cd/v2/util/guard"
)
const payloadQueueSize = 50000
const panicMsgAppSet = "panic while processing applicationset-controller webhook event"
type WebhookHandler struct {
sync.WaitGroup // for testing
namespace string
@@ -103,6 +107,7 @@ func NewWebhookHandler(namespace string, webhookParallelism int, argocdSettingsM
}
func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
compLog := log.WithField("component", "applicationset-webhook")
for i := 0; i < webhookParallelism; i++ {
h.Add(1)
go func() {
@@ -112,7 +117,7 @@ func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
if !ok {
return
}
h.HandleEvent(payload)
guard.RecoverAndLog(func() { h.HandleEvent(payload) }, compLog, panicMsgAppSet)
}
}()
}

View File

@@ -64,6 +64,7 @@ func NewCommand() *cobra.Command {
selfHealBackoffTimeoutSeconds int
selfHealBackoffFactor int
selfHealBackoffCapSeconds int
selfHealBackoffCooldownSeconds int
syncTimeout int
statusProcessors int
operationProcessors int
@@ -196,6 +197,7 @@ func NewCommand() *cobra.Command {
time.Duration(appResyncJitter)*time.Second,
time.Duration(selfHealTimeoutSeconds)*time.Second,
selfHealBackoff,
time.Duration(selfHealBackoffCooldownSeconds)*time.Second,
time.Duration(syncTimeout)*time.Second,
time.Duration(repoErrorGracePeriod)*time.Second,
metricsPort,
@@ -266,6 +268,7 @@ func NewCommand() *cobra.Command {
command.Flags().IntVar(&selfHealBackoffTimeoutSeconds, "self-heal-backoff-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS", 2, 0, math.MaxInt32), "Specifies initial timeout of exponential backoff between self heal attempts")
command.Flags().IntVar(&selfHealBackoffFactor, "self-heal-backoff-factor", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR", 3, 0, math.MaxInt32), "Specifies factor of exponential timeout between application self heal attempts")
command.Flags().IntVar(&selfHealBackoffCapSeconds, "self-heal-backoff-cap-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS", 300, 0, math.MaxInt32), "Specifies max timeout of exponential backoff between application self heal attempts")
command.Flags().IntVar(&selfHealBackoffCooldownSeconds, "self-heal-backoff-cooldown-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS", 330, 0, math.MaxInt32), "Specifies period of time the app needs to stay synced before the self heal backoff can reset")
command.Flags().IntVar(&syncTimeout, "sync-timeout", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT", 0, 0, math.MaxInt32), "Specifies the timeout after which a sync would be terminated. 0 means no timeout (default 0).")
command.Flags().Int64Var(&kubectlParallelismLimit, "kubectl-parallelism-limit", env.ParseInt64FromEnv("ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT", 20, 0, math.MaxInt64), "Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit.")
command.Flags().BoolVar(&repoServerPlaintext, "repo-server-plaintext", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT", false), "Disable TLS on connections to repo server")

View File

@@ -74,6 +74,7 @@ func NewCommand() *cobra.Command {
enableScmProviders bool
webhookParallelism int
tokenRefStrictMode bool
maxResourcesStatusCount int
)
scheme := runtime.NewScheme()
_ = clientgoscheme.AddToScheme(scheme)
@@ -227,6 +228,7 @@ func NewCommand() *cobra.Command {
GlobalPreservedAnnotations: globalPreservedAnnotations,
GlobalPreservedLabels: globalPreservedLabels,
Metrics: &metrics,
MaxResourcesStatusCount: maxResourcesStatusCount,
}).SetupWithManager(mgr, enableProgressiveSyncs, maxConcurrentReconciliations); err != nil {
log.Error(err, "unable to create controller", "controller", "ApplicationSet")
os.Exit(1)
@@ -270,6 +272,7 @@ func NewCommand() *cobra.Command {
command.Flags().StringSliceVar(&globalPreservedLabels, "preserved-labels", env.StringsFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS", []string{}, ","), "Sets global preserved field values for labels")
command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently")
command.Flags().StringSliceVar(&metricsAplicationsetLabels, "metrics-applicationset-labels", []string{}, "List of Application labels that will be added to the argocd_applicationset_labels metric")
command.Flags().IntVar(&maxResourcesStatusCount, "max-resources-status-count", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT", 0, 0, math.MaxInt), "Max number of resources stored in appset status.")
return &command
}

View File

@@ -16,12 +16,13 @@ import (
"golang.org/x/term"
"sigs.k8s.io/yaml"
"github.com/argoproj/argo-cd/v2/util/rbac"
"github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless"
"github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils"
argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient"
accountpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/account"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/session"
"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/errors"
"github.com/argoproj/argo-cd/v2/util/io"
@@ -218,7 +219,7 @@ argocd account can-i create clusters '*'
Actions: %v
Resources: %v
`, rbacpolicy.Actions, rbacpolicy.Resources),
`, rbac.Actions, rbac.Resources),
Run: func(c *cobra.Command, args []string) {
ctx := c.Context()
@@ -262,7 +263,7 @@ func NewAccountListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman
Use: "list",
Short: "List accounts",
Example: "argocd account list",
Run: func(c *cobra.Command, args []string) {
Run: func(c *cobra.Command, _ []string) {
ctx := c.Context()
conn, client := headless.NewClientOrDie(clientOpts, c).NewAccountClientOrDie()
@@ -309,7 +310,7 @@ argocd account get
# Get details for an account by name
argocd account get --account <account-name>`,
Run: func(c *cobra.Command, args []string) {
Run: func(c *cobra.Command, _ []string) {
ctx := c.Context()
clientset := headless.NewClientOrDie(clientOpts, c)
@@ -358,7 +359,7 @@ func printAccountDetails(acc *accountpkg.Account) {
expiresAt := time.Unix(t.ExpiresAt, 0)
expiresAtFormatted = expiresAt.Format(time.RFC3339)
if expiresAt.Before(time.Now()) {
expiresAtFormatted = fmt.Sprintf("%s (expired)", expiresAtFormatted)
expiresAtFormatted = expiresAtFormatted + " (expired)"
}
}
@@ -382,7 +383,7 @@ argocd account generate-token
# Generate token for the account with the specified name
argocd account generate-token --account <account-name>`,
Run: func(c *cobra.Command, args []string) {
Run: func(c *cobra.Command, _ []string) {
ctx := c.Context()
clientset := headless.NewClientOrDie(clientOpts, c)

View File

@@ -9,6 +9,7 @@ import (
"sort"
"time"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/spf13/cobra"
apiv1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -402,7 +403,26 @@ func reconcileApplications(
)
appStateManager := controller.NewAppStateManager(
argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking(), false, 0, serverSideDiff, ignoreNormalizerOpts)
argoDB,
appClientset,
repoServerClient,
namespace,
kubeutil.NewKubectl(),
func(_ string) (kube.CleanupFunc, error) {
return func() {}, nil
},
settingsMgr,
stateCache,
projInformer,
server,
cache,
time.Second,
argo.NewResourceTracking(),
false,
0,
serverSideDiff,
ignoreNormalizerOpts,
)
appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector})
if err != nil {

View File

@@ -183,13 +183,12 @@ func getControllerReplicas(ctx context.Context, kubeClient *kubernetes.Clientset
func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
shard int
replicas int
shardingAlgorithm string
clientConfig clientcmd.ClientConfig
cacheSrc func() (*appstatecache.Cache, error)
portForwardRedis bool
redisCompressionStr string
shard int
replicas int
shardingAlgorithm string
clientConfig clientcmd.ClientConfig
cacheSrc func() (*appstatecache.Cache, error)
portForwardRedis bool
)
command := cobra.Command{
Use: "shards",
@@ -213,7 +212,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm
if replicas == 0 {
return
}
clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, shardingAlgorithm, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr)
clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, shardingAlgorithm, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, clientOpts.RedisCompression)
errors.CheckError(err)
if len(clusters) == 0 {
return
@@ -234,7 +233,6 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm
// we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later
// nolint:errcheck
command.ParseFlags(os.Args[1:])
redisCompressionStr, _ = command.Flags().GetString(cacheutil.CLIFlagRedisCompress)
return &command
}
@@ -466,13 +464,12 @@ func NewClusterDisableNamespacedMode() *cobra.Command {
func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
shard int
replicas int
shardingAlgorithm string
clientConfig clientcmd.ClientConfig
cacheSrc func() (*appstatecache.Cache, error)
portForwardRedis bool
redisCompressionStr string
shard int
replicas int
shardingAlgorithm string
clientConfig clientcmd.ClientConfig
cacheSrc func() (*appstatecache.Cache, error)
portForwardRedis bool
)
command := cobra.Command{
Use: "stats",
@@ -502,7 +499,7 @@ argocd admin cluster stats target-cluster`,
replicas, err = getControllerReplicas(ctx, kubeClient, namespace, clientOpts.AppControllerName)
errors.CheckError(err)
}
clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, shardingAlgorithm, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr)
clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, shardingAlgorithm, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, clientOpts.RedisCompression)
errors.CheckError(err)
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
@@ -524,7 +521,6 @@ argocd admin cluster stats target-cluster`,
// we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later
// nolint:errcheck
command.ParseFlags(os.Args[1:])
redisCompressionStr, _ = command.Flags().GetString(cacheutil.CLIFlagRedisCompress)
return &command
}

View File

@@ -12,17 +12,14 @@ import (
"github.com/argoproj/argo-cd/v2/cmd/argocd/commands/initialize"
"github.com/argoproj/argo-cd/v2/common"
argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient"
"github.com/argoproj/argo-cd/v2/util/cache"
"github.com/argoproj/argo-cd/v2/util/env"
"github.com/argoproj/argo-cd/v2/util/errors"
)
func NewDashboardCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
port int
address string
compressionStr string
clientConfig clientcmd.ClientConfig
port int
address string
clientConfig clientcmd.ClientConfig
)
cmd := &cobra.Command{
Use: "dashboard",
@@ -30,10 +27,8 @@ func NewDashboardCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
Run: func(cmd *cobra.Command, args []string) {
ctx := cmd.Context()
compression, err := cache.CompressionTypeFromString(compressionStr)
errors.CheckError(err)
clientOpts.Core = true
errors.CheckError(headless.MaybeStartLocalServer(ctx, clientOpts, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address, compression, clientConfig))
errors.CheckError(headless.MaybeStartLocalServer(ctx, clientOpts, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address, clientConfig))
println(fmt.Sprintf("Argo CD UI is available at http://%s:%d", address, port))
<-ctx.Done()
},
@@ -50,6 +45,5 @@ $ argocd admin dashboard --redis-compress gzip
clientConfig = cli.AddKubectlFlagsToSet(cmd.Flags())
cmd.Flags().IntVar(&port, "port", common.DefaultPortAPIServer, "Listen on given port")
cmd.Flags().StringVar(&address, "address", common.DefaultAddressAdminDashboard, "Listen on given address")
cmd.Flags().StringVar(&compressionStr, "redis-compress", env.StringFromEnv("REDIS_COMPRESSION", string(cache.RedisCompressionGZip)), "Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none)")
return cmd
}

View File

@@ -9,13 +9,12 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/yaml"
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
"github.com/argoproj/argo-cd/v2/util/assets"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/errors"
@@ -28,94 +27,85 @@ type rbacTrait struct {
allowPath bool
}
// Provide a mapping of short-hand resource names to their RBAC counterparts
// Provide a mapping of shorthand resource names to their RBAC counterparts
var resourceMap = map[string]string{
"account": rbacpolicy.ResourceAccounts,
"app": rbacpolicy.ResourceApplications,
"apps": rbacpolicy.ResourceApplications,
"application": rbacpolicy.ResourceApplications,
"applicationsets": rbacpolicy.ResourceApplicationSets,
"cert": rbacpolicy.ResourceCertificates,
"certs": rbacpolicy.ResourceCertificates,
"certificate": rbacpolicy.ResourceCertificates,
"cluster": rbacpolicy.ResourceClusters,
"extension": rbacpolicy.ResourceExtensions,
"gpgkey": rbacpolicy.ResourceGPGKeys,
"key": rbacpolicy.ResourceGPGKeys,
"log": rbacpolicy.ResourceLogs,
"logs": rbacpolicy.ResourceLogs,
"exec": rbacpolicy.ResourceExec,
"proj": rbacpolicy.ResourceProjects,
"projs": rbacpolicy.ResourceProjects,
"project": rbacpolicy.ResourceProjects,
"repo": rbacpolicy.ResourceRepositories,
"repos": rbacpolicy.ResourceRepositories,
"repository": rbacpolicy.ResourceRepositories,
}
var projectScoped = map[string]bool{
rbacpolicy.ResourceApplications: true,
rbacpolicy.ResourceApplicationSets: true,
rbacpolicy.ResourceLogs: true,
rbacpolicy.ResourceExec: true,
rbacpolicy.ResourceClusters: true,
rbacpolicy.ResourceRepositories: true,
"account": rbac.ResourceAccounts,
"app": rbac.ResourceApplications,
"apps": rbac.ResourceApplications,
"application": rbac.ResourceApplications,
"applicationsets": rbac.ResourceApplicationSets,
"cert": rbac.ResourceCertificates,
"certs": rbac.ResourceCertificates,
"certificate": rbac.ResourceCertificates,
"cluster": rbac.ResourceClusters,
"extension": rbac.ResourceExtensions,
"gpgkey": rbac.ResourceGPGKeys,
"key": rbac.ResourceGPGKeys,
"log": rbac.ResourceLogs,
"logs": rbac.ResourceLogs,
"exec": rbac.ResourceExec,
"proj": rbac.ResourceProjects,
"projs": rbac.ResourceProjects,
"project": rbac.ResourceProjects,
"repo": rbac.ResourceRepositories,
"repos": rbac.ResourceRepositories,
"repository": rbac.ResourceRepositories,
}
// List of allowed RBAC resources
var validRBACResourcesActions = map[string]actionTraitMap{
rbacpolicy.ResourceAccounts: accountsActions,
rbacpolicy.ResourceApplications: applicationsActions,
rbacpolicy.ResourceApplicationSets: defaultCRUDActions,
rbacpolicy.ResourceCertificates: defaultCRDActions,
rbacpolicy.ResourceClusters: defaultCRUDActions,
rbacpolicy.ResourceExtensions: extensionActions,
rbacpolicy.ResourceGPGKeys: defaultCRDActions,
rbacpolicy.ResourceLogs: logsActions,
rbacpolicy.ResourceExec: execActions,
rbacpolicy.ResourceProjects: defaultCRUDActions,
rbacpolicy.ResourceRepositories: defaultCRUDActions,
rbac.ResourceAccounts: accountsActions,
rbac.ResourceApplications: applicationsActions,
rbac.ResourceApplicationSets: defaultCRUDActions,
rbac.ResourceCertificates: defaultCRDActions,
rbac.ResourceClusters: defaultCRUDActions,
rbac.ResourceExtensions: extensionActions,
rbac.ResourceGPGKeys: defaultCRDActions,
rbac.ResourceLogs: logsActions,
rbac.ResourceExec: execActions,
rbac.ResourceProjects: defaultCRUDActions,
rbac.ResourceRepositories: defaultCRUDActions,
}
// List of allowed RBAC actions
var defaultCRUDActions = actionTraitMap{
rbacpolicy.ActionCreate: rbacTrait{},
rbacpolicy.ActionGet: rbacTrait{},
rbacpolicy.ActionUpdate: rbacTrait{},
rbacpolicy.ActionDelete: rbacTrait{},
rbac.ActionCreate: rbacTrait{},
rbac.ActionGet: rbacTrait{},
rbac.ActionUpdate: rbacTrait{},
rbac.ActionDelete: rbacTrait{},
}
var defaultCRDActions = actionTraitMap{
rbacpolicy.ActionCreate: rbacTrait{},
rbacpolicy.ActionGet: rbacTrait{},
rbacpolicy.ActionDelete: rbacTrait{},
rbac.ActionCreate: rbacTrait{},
rbac.ActionGet: rbacTrait{},
rbac.ActionDelete: rbacTrait{},
}
var applicationsActions = actionTraitMap{
rbacpolicy.ActionCreate: rbacTrait{},
rbacpolicy.ActionGet: rbacTrait{},
rbacpolicy.ActionUpdate: rbacTrait{allowPath: true},
rbacpolicy.ActionDelete: rbacTrait{allowPath: true},
rbacpolicy.ActionAction: rbacTrait{allowPath: true},
rbacpolicy.ActionOverride: rbacTrait{},
rbacpolicy.ActionSync: rbacTrait{},
rbac.ActionCreate: rbacTrait{},
rbac.ActionGet: rbacTrait{},
rbac.ActionUpdate: rbacTrait{allowPath: true},
rbac.ActionDelete: rbacTrait{allowPath: true},
rbac.ActionAction: rbacTrait{allowPath: true},
rbac.ActionOverride: rbacTrait{},
rbac.ActionSync: rbacTrait{},
}
var accountsActions = actionTraitMap{
rbacpolicy.ActionCreate: rbacTrait{},
rbacpolicy.ActionUpdate: rbacTrait{},
rbac.ActionCreate: rbacTrait{},
rbac.ActionUpdate: rbacTrait{},
}
var execActions = actionTraitMap{
rbacpolicy.ActionCreate: rbacTrait{},
rbac.ActionCreate: rbacTrait{},
}
var logsActions = actionTraitMap{
rbacpolicy.ActionGet: rbacTrait{},
rbac.ActionGet: rbacTrait{},
}
var extensionActions = actionTraitMap{
rbacpolicy.ActionInvoke: rbacTrait{},
rbac.ActionInvoke: rbacTrait{},
}
// NewRBACCommand is the command for 'rbac'
@@ -226,7 +216,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau
// even if there is no explicit RBAC allow, or if there is an explicit RBAC deny)
var isLogRbacEnforced func() bool
if nsOverride && policyFile == "" {
if resolveRBACResourceName(resource) == rbacpolicy.ResourceLogs {
if resolveRBACResourceName(resource) == rbac.ResourceLogs {
isLogRbacEnforced = func() bool {
if opts, ok := cmdCtx.(*settingsOpts); ok {
opts.loadClusterSettings = true
@@ -248,12 +238,11 @@ argocd admin settings rbac can someuser create application 'default/app' --defau
fmt.Println("Yes")
}
os.Exit(0)
} else {
if !quiet {
fmt.Println("No")
}
os.Exit(1)
}
if !quiet {
fmt.Println("No")
}
os.Exit(1)
},
}
clientConfig = cli.AddKubectlFlagsToCmd(command)
@@ -321,13 +310,11 @@ argocd admin settings rbac validate --namespace argocd
if err := rbac.ValidatePolicy(userPolicy); err == nil {
fmt.Printf("Policy is valid.\n")
os.Exit(0)
} else {
fmt.Printf("Policy is invalid: %v\n", err)
os.Exit(1)
}
} else {
log.Fatalf("Policy is empty or could not be loaded.")
fmt.Printf("Policy is invalid: %v\n", err)
os.Exit(1)
}
log.Fatalf("Policy is empty or could not be loaded.")
},
}
clientConfig = cli.AddKubectlFlagsToCmd(command)
@@ -402,7 +389,7 @@ func getPolicyFromConfigMap(cm *corev1.ConfigMap) (string, string, string) {
// getPolicyConfigMap fetches the RBAC config map from K8s cluster
func getPolicyConfigMap(ctx context.Context, client kubernetes.Interface, namespace string) (*corev1.ConfigMap, error) {
cm, err := client.CoreV1().ConfigMaps(namespace).Get(ctx, common.ArgoCDRBACConfigMapName, v1.GetOptions{})
cm, err := client.CoreV1().ConfigMaps(namespace).Get(ctx, common.ArgoCDRBACConfigMapName, metav1.GetOptions{})
if err != nil {
return nil, err
}
@@ -448,12 +435,12 @@ func checkPolicy(subject, action, resource, subResource, builtinPolicy, userPoli
// Some project scoped resources have a special notation - for simplicity's sake,
// if user gives no sub-resource (or specifies simple '*'), we construct
// the required notation by setting subresource to '*/*'.
if projectScoped[realResource] {
if rbac.ProjectScoped[realResource] {
if subResource == "*" || subResource == "" {
subResource = "*/*"
}
}
if realResource == rbacpolicy.ResourceLogs {
if realResource == rbac.ResourceLogs {
if isLogRbacEnforced != nil && !isLogRbacEnforced() {
return true
}
@@ -466,9 +453,8 @@ func checkPolicy(subject, action, resource, subResource, builtinPolicy, userPoli
func resolveRBACResourceName(name string) string {
if res, ok := resourceMap[name]; ok {
return res
} else {
return name
}
return name
}
// validateRBACResourceAction checks whether a given resource is a valid RBAC resource.

View File

@@ -7,14 +7,15 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
"github.com/argoproj/argo-cd/v2/util/rbac"
"github.com/argoproj/argo-cd/v2/util/assets"
)
@@ -56,8 +57,8 @@ func Test_validateRBACResourceAction(t *testing.T) {
{
name: "Test valid resource and action",
args: args{
resource: rbacpolicy.ResourceApplications,
action: rbacpolicy.ActionCreate,
resource: rbac.ResourceApplications,
action: rbac.ActionCreate,
},
valid: true,
},
@@ -71,7 +72,7 @@ func Test_validateRBACResourceAction(t *testing.T) {
{
name: "Test invalid action",
args: args{
resource: rbacpolicy.ResourceApplications,
resource: rbac.ResourceApplications,
action: "invalid",
},
valid: false,
@@ -79,24 +80,24 @@ func Test_validateRBACResourceAction(t *testing.T) {
{
name: "Test invalid action for resource",
args: args{
resource: rbacpolicy.ResourceLogs,
action: rbacpolicy.ActionCreate,
resource: rbac.ResourceLogs,
action: rbac.ActionCreate,
},
valid: false,
},
{
name: "Test valid action with path",
args: args{
resource: rbacpolicy.ResourceApplications,
action: rbacpolicy.ActionAction + "/apps/Deployment/restart",
resource: rbac.ResourceApplications,
action: rbac.ActionAction + "/apps/Deployment/restart",
},
valid: true,
},
{
name: "Test invalid action with path",
args: args{
resource: rbacpolicy.ResourceApplications,
action: rbacpolicy.ActionGet + "/apps/Deployment/restart",
resource: rbac.ResourceApplications,
action: rbac.ActionGet + "/apps/Deployment/restart",
},
valid: false,
},
@@ -147,7 +148,7 @@ func Test_PolicyFromK8s(t *testing.T) {
ctx := context.Background()
require.NoError(t, err)
kubeclientset := fake.NewClientset(&v1.ConfigMap{
kubeclientset := fake.NewClientset(&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "argocd-rbac-cm",
Namespace: "argocd",
@@ -280,7 +281,7 @@ p, role:user, logs, get, .*/.*, allow
p, role:user, exec, create, .*/.*, allow
`
kubeclientset := fake.NewClientset(&v1.ConfigMap{
kubeclientset := fake.NewClientset(&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "argocd-rbac-cm",
Namespace: "argocd",

View File

@@ -69,7 +69,7 @@ func newSettingsManager(data map[string]string) *settings.SettingsManager {
type fakeCmdContext struct {
mgr *settings.SettingsManager
// nolint:unused,structcheck
// nolint:unused
out bytes.Buffer
}

View File

@@ -177,7 +177,7 @@ func testAPI(ctx context.Context, clientOpts *apiclient.ClientOptions) error {
//
// If the clientOpts enables core mode, but the local config does not have core mode enabled, this function will
// not start the local server.
func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string, compression cache.RedisCompressionType, clientConfig clientcmd.ClientConfig) error {
func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string, clientConfig clientcmd.ClientConfig) error {
if clientConfig == nil {
flags := pflag.NewFlagSet("tmp", pflag.ContinueOnError)
clientConfig = cli.AddKubectlFlagsToSet(flags)
@@ -270,7 +270,7 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti
log.Warnf("Failed to fetch & set redis password for namespace %s: %v", namespace, err)
}
appstateCache := appstatecache.NewCache(cache.NewCache(&forwardCacheClient{namespace: namespace, context: ctxStr, compression: compression, redisHaProxyName: clientOpts.RedisHaProxyName, redisName: clientOpts.RedisName, redisPassword: redisOptions.Password}), time.Hour)
appstateCache := appstatecache.NewCache(cache.NewCache(&forwardCacheClient{namespace: namespace, context: ctxStr, compression: cache.RedisCompressionType(clientOpts.RedisCompression), redisHaProxyName: clientOpts.RedisHaProxyName, redisName: clientOpts.RedisName, redisPassword: redisOptions.Password}), time.Hour)
srv := server.NewServer(ctx, server.ArgoCDServerOpts{
EnableGZip: false,
Namespace: namespace,
@@ -321,7 +321,7 @@ func NewClientOrDie(opts *apiclient.ClientOptions, c *cobra.Command) apiclient.C
ctxStr := initialize.RetrieveContextIfChanged(c.Flag("context"))
// If we're in core mode, start the API server on the fly and configure the client `opts` to use it.
// If we're not in core mode, this function call will do nothing.
err := MaybeStartLocalServer(ctx, opts, ctxStr, nil, nil, cache.RedisCompressionNone, nil)
err := MaybeStartLocalServer(ctx, opts, ctxStr, nil, nil, nil)
if err != nil {
log.Fatal(err)
}

View File

@@ -11,6 +11,7 @@ import (
cmdutil "github.com/argoproj/argo-cd/v2/cmd/util"
"github.com/argoproj/argo-cd/v2/common"
argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient"
"github.com/argoproj/argo-cd/v2/util/cache"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/config"
"github.com/argoproj/argo-cd/v2/util/env"
@@ -87,6 +88,7 @@ func NewCommand() *cobra.Command {
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))
command.PersistentFlags().StringVar(&clientOpts.RedisName, "redis-name", env.StringFromEnv(common.EnvRedisName, common.DefaultRedisName), fmt.Sprintf("Name of the Redis deployment; set this or the %s environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart", common.EnvRedisName))
command.PersistentFlags().StringVar(&clientOpts.RepoServerName, "repo-server-name", env.StringFromEnv(common.EnvRepoServerName, common.DefaultRepoServerName), fmt.Sprintf("Name of the Argo CD Repo 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.EnvRepoServerName))
command.PersistentFlags().StringVar(&clientOpts.RedisCompression, "redis-compress", env.StringFromEnv("REDIS_COMPRESSION", string(cache.RedisCompressionGZip)), "Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none)")
command.PersistentFlags().BoolVar(&clientOpts.PromptsEnabled, "prompts-enabled", localconfig.GetPromptsEnabled(true), "Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.")
clientOpts.KubeOverrides = &clientcmd.ConfigOverrides{}

View File

@@ -53,7 +53,7 @@ func (p *Prompt) ConfirmBaseOnCount(messageForSingle string, messageForArray str
}
if count == 1 {
return p.Confirm(messageForSingle), true
return p.Confirm(messageForSingle), false
}
return p.ConfirmAll(messageForArray)

View File

@@ -38,11 +38,47 @@ func TestConfirmBaseOnCountPromptDisabled(t *testing.T) {
assert.True(t, result2)
}
func TestConfirmBaseOnCountZeroApps(t *testing.T) {
p := &Prompt{enabled: true}
result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Process all?", 0)
assert.True(t, result1)
assert.True(t, result2)
func TestConfirmBaseOnCount(t *testing.T) {
tests := []struct {
input string
output bool
count int
}{
{
input: "y\n",
output: true,
count: 0,
},
{
input: "y\n",
output: true,
count: 1,
},
{
input: "n\n",
output: false,
count: 1,
},
}
origStdin := os.Stdin
for _, tt := range tests {
tmpFile, err := writeToStdin(tt.input)
require.NoError(t, err)
p := &Prompt{enabled: true}
result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Proceed all?", tt.count)
assert.Equal(t, tt.output, result1)
if tt.count == 1 {
assert.False(t, result2)
} else {
assert.Equal(t, tt.output, result2)
}
_ = tmpFile.Close()
os.Remove(tmpFile.Name())
}
os.Stdin = origStdin
}
func TestConfirmPrompt(t *testing.T) {
@@ -62,8 +98,8 @@ func TestConfirmPrompt(t *testing.T) {
p := &Prompt{enabled: true}
result := p.Confirm("Are you sure you want to run this command? (y/n) \n")
assert.Equal(t, c.output, result)
os.Remove(tmpFile.Name())
_ = tmpFile.Close()
os.Remove(tmpFile.Name())
}
os.Stdin = origStdin
@@ -89,8 +125,8 @@ func TestConfirmAllPrompt(t *testing.T) {
confirm, confirmAll := p.ConfirmAll("Are you sure you want to run this command? (y/n) \n")
assert.Equal(t, c.confirm, confirm)
assert.Equal(t, c.confirmAll, confirmAll)
os.Remove(tmpFile.Name())
_ = tmpFile.Close()
os.Remove(tmpFile.Name())
}
os.Stdin = origStdin

View File

@@ -18,11 +18,13 @@ func TestProjectOpts_ResourceLists(t *testing.T) {
}
assert.ElementsMatch(t,
[]v1.GroupKind{{Kind: "ConfigMap"}}, opts.GetAllowedNamespacedResources(),
[]v1.GroupKind{{Group: "apps", Kind: "DaemonSet"}}, opts.GetDeniedNamespacedResources(),
[]v1.GroupKind{{Group: "apiextensions.k8s.io", Kind: "CustomResourceDefinition"}}, opts.GetAllowedClusterResources(),
[]v1.GroupKind{{Group: "rbac.authorization.k8s.io", Kind: "ClusterRole"}}, opts.GetDeniedClusterResources(),
)
[]v1.GroupKind{{Kind: "ConfigMap"}}, opts.GetAllowedNamespacedResources())
assert.ElementsMatch(t,
[]v1.GroupKind{{Group: "apps", Kind: "DaemonSet"}}, opts.GetDeniedNamespacedResources())
assert.ElementsMatch(t,
[]v1.GroupKind{{Group: "apiextensions.k8s.io", Kind: "CustomResourceDefinition"}}, opts.GetAllowedClusterResources())
assert.ElementsMatch(t,
[]v1.GroupKind{{Group: "rbac.authorization.k8s.io", Kind: "ClusterRole"}}, opts.GetDeniedClusterResources())
}
func TestProjectOpts_GetDestinationServiceAccounts(t *testing.T) {

View File

@@ -45,7 +45,7 @@ func AddRepoFlags(command *cobra.Command, opts *RepoOptions) {
command.Flags().StringVar(&opts.GithubAppPrivateKeyPath, "github-app-private-key-path", "", "private key of the GitHub Application")
command.Flags().StringVar(&opts.GitHubAppEnterpriseBaseURL, "github-app-enterprise-base-url", "", "base url to use when using GitHub Enterprise (e.g. https://ghe.example.com/api/v3")
command.Flags().StringVar(&opts.Proxy, "proxy", "", "use proxy to access repository")
command.Flags().StringVar(&opts.Proxy, "no-proxy", "", "don't access these targets via proxy")
command.Flags().StringVar(&opts.NoProxy, "no-proxy", "", "don't access these targets via proxy")
command.Flags().StringVar(&opts.GCPServiceAccountKeyPath, "gcp-service-account-key-path", "", "service account key for the Google Cloud Platform")
command.Flags().BoolVar(&opts.ForceHttpBasicAuth, "force-http-basic-auth", false, "whether to force use of basic auth when connecting repository via HTTP")
}

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks
@@ -14,7 +14,7 @@ type Clientset struct {
mock.Mock
}
// NewCommitServerClient provides a mock function with given fields:
// NewCommitServerClient provides a mock function with no fields
func (_m *Clientset) NewCommitServerClient() (io.Closer, apiclient.CommitServiceClient, error) {
ret := _m.Called()

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks

View File

@@ -41,6 +41,7 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
"k8s.io/utils/ptr"
commitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient"
"github.com/argoproj/argo-cd/v2/common"
@@ -135,6 +136,7 @@ type ApplicationController struct {
statusRefreshJitter time.Duration
selfHealTimeout time.Duration
selfHealBackOff *wait.Backoff
selfHealBackoffCooldown time.Duration
syncTimeout time.Duration
db db.ArgoDB
settingsMgr *settings_util.SettingsManager
@@ -169,6 +171,7 @@ func NewApplicationController(
appResyncJitter time.Duration,
selfHealTimeout time.Duration,
selfHealBackoff *wait.Backoff,
selfHealBackoffCooldown time.Duration,
syncTimeout time.Duration,
repoErrorGracePeriod time.Duration,
metricsPort int,
@@ -214,6 +217,7 @@ func NewApplicationController(
settingsMgr: settingsMgr,
selfHealTimeout: selfHealTimeout,
selfHealBackOff: selfHealBackoff,
selfHealBackoffCooldown: selfHealBackoffCooldown,
syncTimeout: syncTimeout,
clusterSharding: clusterSharding,
projByNameCache: sync.Map{},
@@ -309,7 +313,7 @@ func NewApplicationController(
}
}
stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterSharding, argo.NewResourceTracking())
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod, serverSideDiff, ignoreNormalizerOpts)
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.onKubectlRun, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod, serverSideDiff, ignoreNormalizerOpts)
ctrl.appInformer = appInformer
ctrl.appLister = appLister
ctrl.projInformer = projInformer
@@ -940,7 +944,7 @@ func (ctrl *ApplicationController) requestAppRefresh(appName string, compareWith
key := ctrl.toAppKey(appName)
if compareWith != nil && after != nil {
ctrl.appComparisonTypeRefreshQueue.AddAfter(fmt.Sprintf("%s/%d", key, compareWith), *after)
ctrl.appComparisonTypeRefreshQueue.AddAfter(fmt.Sprintf("%s/%d", key, *compareWith), *after)
} else {
if compareWith != nil {
ctrl.refreshRequestedAppsMutex.Lock()
@@ -1193,7 +1197,7 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic
isValid, cluster := ctrl.isValidDestination(app)
if !isValid {
app.UnSetCascadedDeletion()
app.UnSetPostDeleteFinalizer()
app.UnSetPostDeleteFinalizerAll()
if err := ctrl.updateFinalizers(app); err != nil {
return err
}
@@ -1472,7 +1476,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
} else {
state.Phase = synccommon.OperationRunning
state.RetryCount++
state.Message = fmt.Sprintf("%s. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen))
state.Message = fmt.Sprintf("%s due to application controller sync timeout. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen))
}
} else if state.RetryCount > 0 {
state.Message = fmt.Sprintf("%s (retried %d times).", state.Message, state.RetryCount)
@@ -1674,11 +1678,9 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
project, hasErrors := ctrl.refreshAppConditions(app)
ts.AddCheckpoint("refresh_app_conditions_ms")
now := metav1.Now()
if hasErrors {
app.Status.Sync.Status = appv1.SyncStatusCodeUnknown
app.Status.Health.Status = health.HealthStatusUnknown
app.Status.Health.LastTransitionTime = &now
patchMs = ctrl.persistAppStatus(origApp, &app.Status)
if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), &appv1.ApplicationTree{}); err != nil {
@@ -1769,6 +1771,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
ts.AddCheckpoint("auto_sync_ms")
if app.Status.ReconciledAt == nil || comparisonLevel >= CompareWithLatest {
now := metav1.Now()
app.Status.ReconciledAt = &now
}
app.Status.Sync = *compareResult.syncStatus
@@ -1999,9 +2002,15 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new
ctrl.logAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, context.TODO())
}
if orig.Status.Health.Status != newStatus.Health.Status {
now := metav1.Now()
newStatus.Health.LastTransitionTime = &now
message := fmt.Sprintf("Updated health status: %s -> %s", orig.Status.Health.Status, newStatus.Health.Status)
ctrl.logAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, context.TODO())
} else {
// make sure the last transition time is the same and populated if the health is the same
newStatus.Health.LastTransitionTime = orig.Status.Health.LastTransitionTime
}
var newAnnotations map[string]string
if orig.GetAnnotations() != nil {
newAnnotations = make(map[string]string)
@@ -2103,9 +2112,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *
InitiatedBy: appv1.OperationInitiator{Automated: true},
Retry: appv1.RetryStrategy{Limit: 5},
}
if app.Status.OperationState != nil && app.Status.OperationState.Operation.Sync != nil {
op.Sync.SelfHealAttemptsCount = app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount
}
if app.Spec.SyncPolicy.Retry != nil {
op.Retry = *app.Spec.SyncPolicy.Retry
}
@@ -2121,8 +2128,18 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *
}
logCtx.Infof("Skipping auto-sync: most recent sync already to %s", desiredCommitSHA)
return nil, 0
} else if alreadyAttempted && selfHeal {
if shouldSelfHeal, retryAfter := ctrl.shouldSelfHeal(app); shouldSelfHeal {
} else if selfHeal {
shouldSelfHeal, retryAfter := ctrl.shouldSelfHeal(app, alreadyAttempted)
if app.Status.OperationState != nil && app.Status.OperationState.Operation.Sync != nil {
op.Sync.SelfHealAttemptsCount = app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount
}
if alreadyAttempted {
if !shouldSelfHeal {
logCtx.Infof("Skipping auto-sync: already attempted sync to %s with timeout %v (retrying in %v)", desiredCommitSHA, ctrl.selfHealTimeout, retryAfter)
ctrl.requestAppRefresh(app.QualifiedName(), CompareWithLatest.Pointer(), &retryAfter)
return nil, 0
}
op.Sync.SelfHealAttemptsCount++
for _, resource := range resources {
if resource.Status != appv1.SyncStatusCodeSynced {
@@ -2133,10 +2150,6 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *
})
}
}
} else {
logCtx.Infof("Skipping auto-sync: already attempted sync to %s with timeout %v (retrying in %v)", desiredCommitSHA, ctrl.selfHealTimeout, retryAfter)
ctrl.requestAppRefresh(app.QualifiedName(), CompareWithLatest.Pointer(), &retryAfter)
return nil, 0
}
}
ts.AddCheckpoint("already_attempted_check_ms")
@@ -2220,29 +2233,41 @@ func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS
}
}
func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application) (bool, time.Duration) {
func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application, alreadyAttempted bool) (bool, time.Duration) {
if app.Status.OperationState == nil {
return true, time.Duration(0)
}
var timeSinceOperation *time.Duration
if app.Status.OperationState.FinishedAt != nil {
timeSinceOperation = ptr.To(time.Since(app.Status.OperationState.FinishedAt.Time))
}
// Reset counter if the prior sync was successful and the cooldown period is over OR if the revision has changed
if !alreadyAttempted || (timeSinceOperation != nil && *timeSinceOperation >= ctrl.selfHealBackoffCooldown && app.Status.Sync.Status == appv1.SyncStatusCodeSynced) {
app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount = 0
}
var retryAfter time.Duration
if ctrl.selfHealBackOff == nil {
if app.Status.OperationState.FinishedAt == nil {
if timeSinceOperation == nil {
retryAfter = ctrl.selfHealTimeout
} else {
retryAfter = ctrl.selfHealTimeout - time.Since(app.Status.OperationState.FinishedAt.Time)
retryAfter = ctrl.selfHealTimeout - *timeSinceOperation
}
} else {
backOff := *ctrl.selfHealBackOff
backOff.Steps = int(app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount)
var delay time.Duration
for backOff.Steps > 0 {
steps := backOff.Steps
for i := 0; i < steps; i++ {
delay = backOff.Step()
}
if app.Status.OperationState.FinishedAt == nil {
if timeSinceOperation == nil {
retryAfter = delay
} else {
retryAfter = delay - time.Since(app.Status.OperationState.FinishedAt.Time)
retryAfter = delay - *timeSinceOperation
}
}
return retryAfter <= 0, retryAfter

View File

@@ -171,6 +171,7 @@ func newFakeControllerWithResync(data *fakeData, appResyncPeriod time.Duration,
time.Second,
time.Minute,
nil,
time.Minute,
0,
time.Second*10,
common.DefaultPortArgoCDMetrics,
@@ -1409,6 +1410,25 @@ func TestNeedRefreshAppStatus(t *testing.T) {
assert.Equal(t, CompareWithRecent, compareWith)
})
t.Run("requesting refresh with delay gives correct compression level", func(t *testing.T) {
needRefresh, _, _ := ctrl.needRefreshAppStatus(app, 1*time.Hour, 2*time.Hour)
assert.False(t, needRefresh)
// use a one-off controller so other tests don't have a manual refresh request
ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil)
// refresh app with a non-nil delay
// use zero-second delay to test the add later logic without waiting in the test
delay := time.Duration(0)
ctrl.requestAppRefresh(app.Name, CompareWithRecent.Pointer(), &delay)
ctrl.processAppComparisonTypeQueueItem()
needRefresh, refreshType, compareWith := ctrl.needRefreshAppStatus(app, 1*time.Hour, 2*time.Hour)
assert.True(t, needRefresh)
assert.Equal(t, v1alpha1.RefreshTypeNormal, refreshType)
assert.Equal(t, CompareWithRecent, compareWith)
})
t.Run("refresh application which status is not reconciled using latest commit", func(t *testing.T) {
app := app.DeepCopy()
needRefresh, _, _ := ctrl.needRefreshAppStatus(app, 1*time.Hour, 2*time.Hour)
@@ -1818,7 +1838,7 @@ apps/Deployment:
hs = {}
hs.status = ""
hs.message = ""
if obj.metadata ~= nil then
if obj.metadata.labels ~= nil then
current_status = obj.metadata.labels["status"]
@@ -2042,7 +2062,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) {
phase, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "phase")
assert.Equal(t, string(synccommon.OperationRunning), phase)
message, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "message")
assert.Contains(t, message, "Retrying attempt #1")
assert.Contains(t, message, "due to application controller sync timeout. Retrying attempt #1")
retryCount, _, _ := unstructured.NestedFloat64(receivedPatch, "status", "operationState", "retryCount")
assert.InEpsilon(t, float64(1), retryCount, 0.0001)
}
@@ -2514,7 +2534,7 @@ func TestSelfHealExponentialBackoff(t *testing.T) {
ctrl.selfHealBackOff = &wait.Backoff{
Factor: 3,
Duration: 2 * time.Second,
Cap: 5 * time.Minute,
Cap: 2 * time.Minute,
}
app := &v1alpha1.Application{
@@ -2529,29 +2549,92 @@ func TestSelfHealExponentialBackoff(t *testing.T) {
testCases := []struct {
attempts int64
expectedAttempts int64
finishedAt *metav1.Time
expectedDuration time.Duration
shouldSelfHeal bool
alreadyAttempted bool
syncStatus v1alpha1.SyncStatusCode
}{{
attempts: 0,
finishedAt: ptr.To(metav1.Now()),
expectedDuration: 0,
shouldSelfHeal: true,
alreadyAttempted: true,
expectedAttempts: 0,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, {
attempts: 1,
finishedAt: ptr.To(metav1.Now()),
expectedDuration: 2 * time.Second,
shouldSelfHeal: false,
alreadyAttempted: true,
expectedAttempts: 1,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, {
attempts: 2,
finishedAt: ptr.To(metav1.Now()),
expectedDuration: 6 * time.Second,
shouldSelfHeal: false,
alreadyAttempted: true,
expectedAttempts: 2,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, {
attempts: 3,
finishedAt: nil,
expectedDuration: 18 * time.Second,
shouldSelfHeal: false,
alreadyAttempted: true,
expectedAttempts: 3,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, {
attempts: 4,
finishedAt: nil,
expectedDuration: 54 * time.Second,
shouldSelfHeal: false,
alreadyAttempted: true,
expectedAttempts: 4,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, {
attempts: 5,
finishedAt: nil,
expectedDuration: 120 * time.Second,
shouldSelfHeal: false,
alreadyAttempted: true,
expectedAttempts: 5,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, {
attempts: 6,
finishedAt: nil,
expectedDuration: 120 * time.Second,
shouldSelfHeal: false,
alreadyAttempted: true,
expectedAttempts: 6,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, {
attempts: 6,
finishedAt: nil,
expectedDuration: 0,
shouldSelfHeal: true,
alreadyAttempted: false,
expectedAttempts: 0,
syncStatus: v1alpha1.SyncStatusCodeOutOfSync,
}, { // backoff will not reset as finished tme isn't >= cooldown
attempts: 6,
finishedAt: ptr.To(metav1.Now()),
expectedDuration: 120 * time.Second,
shouldSelfHeal: false,
alreadyAttempted: true,
expectedAttempts: 6,
syncStatus: v1alpha1.SyncStatusCodeSynced,
}, { // backoff will reset as finished time is >= cooldown
attempts: 40,
finishedAt: &metav1.Time{Time: time.Now().Add(-(1 * time.Minute))},
expectedDuration: -60 * time.Second,
shouldSelfHeal: true,
alreadyAttempted: true,
expectedAttempts: 0,
syncStatus: v1alpha1.SyncStatusCodeSynced,
}}
for i := range testCases {
@@ -2559,8 +2642,10 @@ func TestSelfHealExponentialBackoff(t *testing.T) {
t.Run(fmt.Sprintf("test case %d", i), func(t *testing.T) {
app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount = tc.attempts
app.Status.OperationState.FinishedAt = tc.finishedAt
ok, duration := ctrl.shouldSelfHeal(app)
app.Status.Sync.Status = tc.syncStatus
ok, duration := ctrl.shouldSelfHeal(app, tc.alreadyAttempted)
require.Equal(t, ok, tc.shouldSelfHeal)
require.Equal(t, tc.expectedAttempts, app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount)
assertDurationAround(t, tc.expectedDuration, duration)
})
}

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.43.2. DO NOT EDIT.
// Code generated by mockery v2.53.4. DO NOT EDIT.
package mocks
@@ -55,7 +55,7 @@ func (_m *LiveStateCache) GetClusterCache(server string) (cache.ClusterCache, er
return r0, r1
}
// GetClustersInfo provides a mock function with given fields:
// GetClustersInfo provides a mock function with no fields
func (_m *LiveStateCache) GetClustersInfo() []cache.ClusterInfo {
ret := _m.Called()
@@ -172,7 +172,7 @@ func (_m *LiveStateCache) GetVersionsInfo(serverURL string) (string, []kube.APIR
return r0, r1, r2
}
// Init provides a mock function with given fields:
// Init provides a mock function with no fields
func (_m *LiveStateCache) Init() error {
ret := _m.Called()

View File

@@ -8,7 +8,6 @@ import (
"github.com/argoproj/gitops-engine/pkg/sync/ignore"
kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/argoproj/argo-cd/v2/common"
@@ -22,7 +21,9 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
var savedErr error
var errCount uint
appHealth := appv1.HealthStatus{Status: health.HealthStatusHealthy}
appHealth := app.Status.Health.DeepCopy()
appHealth.Status = health.HealthStatusHealthy
for i, res := range resources {
if res.Target != nil && hookutil.Skip(res.Target) {
continue
@@ -82,18 +83,11 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
}
if persistResourceHealth {
app.Status.ResourceHealthSource = appv1.ResourceHealthLocationInline
// if the status didn't change, don't update the timestamp
if app.Status.Health.Status == appHealth.Status && app.Status.Health.LastTransitionTime != nil {
appHealth.LastTransitionTime = app.Status.Health.LastTransitionTime
} else {
now := metav1.Now()
appHealth.LastTransitionTime = &now
}
} else {
app.Status.ResourceHealthSource = appv1.ResourceHealthLocationAppTree
}
if savedErr != nil && errCount > 1 {
savedErr = fmt.Errorf("see application-controller logs for %d other errors; most recent error was: %w", errCount-1, savedErr)
}
return &appHealth, savedErr
return appHealth, savedErr
}

View File

@@ -73,7 +73,6 @@ func TestSetApplicationHealth(t *testing.T) {
assert.NotNil(t, healthStatus.LastTransitionTime)
assert.Nil(t, resourceStatuses[0].Health.LastTransitionTime)
assert.Nil(t, resourceStatuses[1].Health.LastTransitionTime)
previousLastTransitionTime := healthStatus.LastTransitionTime
app.Status.Health = *healthStatus
// now mark the job as a hook and retry. it should ignore the hook and consider the app healthy
@@ -81,9 +80,8 @@ func TestSetApplicationHealth(t *testing.T) {
healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
// change in health, timestamp should change
assert.NotEqual(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime)
previousLastTransitionTime = healthStatus.LastTransitionTime
// timestamp should be the same in case health did not change
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
app.Status.Health = *healthStatus
// now we set the `argocd.argoproj.io/ignore-healthcheck: "true"` annotation on the job's target.
@@ -94,8 +92,7 @@ func TestSetApplicationHealth(t *testing.T) {
healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
// no change in health, timestamp shouldn't change
assert.Equal(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime)
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
}
func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) {
@@ -124,7 +121,7 @@ func TestSetApplicationHealth_MissingResource(t *testing.T) {
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusMissing, healthStatus.Status)
assert.False(t, healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
}
func TestSetApplicationHealth_HealthImproves(t *testing.T) {
@@ -156,7 +153,7 @@ func TestSetApplicationHealth_HealthImproves(t *testing.T) {
healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true)
require.NoError(t, err)
assert.Equal(t, tc.newStatus, healthStatus.Status)
assert.NotEqual(t, testTimestamp, *healthStatus.LastTransitionTime)
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
})
}
}
@@ -173,6 +170,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) {
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
assert.Equal(t, health.HealthStatusMissing, resourceStatuses[0].Health.Status)
})
@@ -184,7 +182,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) {
}, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusMissing, healthStatus.Status)
assert.False(t, healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
})
}

View File

@@ -27,7 +27,7 @@ type Dependencies interface {
GetProcessableApps() (*appv1.ApplicationList, error)
GetRepoObjs(app *appv1.Application, source appv1.ApplicationSource, revision string, project *appv1.AppProject) ([]*unstructured.Unstructured, *apiclient.ManifestResponse, error)
GetWriteCredentials(ctx context.Context, repoURL string, project string) (*appv1.Repository, error)
RequestAppRefresh(appName string)
RequestAppRefresh(appName string, appNamespace string) error
// TODO: only allow access to the hydrator status
PersistAppHydratorStatus(orig *appv1.Application, newStatus *appv1.SourceHydratorStatus)
AddHydrationQueueItem(key HydrationQueueKey)
@@ -156,7 +156,10 @@ func (h *Hydrator) ProcessHydrationQueueItem(hydrationKey HydrationQueueKey) (pr
}
h.dependencies.PersistAppHydratorStatus(origApp, &app.Status.SourceHydrator)
// Request a refresh since we pushed a new commit.
h.dependencies.RequestAppRefresh(app.QualifiedName())
err := h.dependencies.RequestAppRefresh(app.Name, app.Namespace)
if err != nil {
logCtx.WithField("app", app.QualifiedName()).WithError(err).Error("Failed to request app refresh after hydration")
}
}
return
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/argoproj/argo-cd/v2/controller/hydrator"
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
argoutil "github.com/argoproj/argo-cd/v2/util/argo"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -30,17 +31,26 @@ func (ctrl *ApplicationController) GetProcessableApps() (*appv1.ApplicationList,
return ctrl.getAppList(metav1.ListOptions{})
}
func (ctrl *ApplicationController) GetRepoObjs(app *appv1.Application, source appv1.ApplicationSource, revision string, project *appv1.AppProject) ([]*unstructured.Unstructured, *apiclient.ManifestResponse, error) {
sources := []appv1.ApplicationSource{source}
revisions := []string{revision}
func (ctrl *ApplicationController) GetRepoObjs(origApp *appv1.Application, drySource appv1.ApplicationSource, revision string, project *appv1.AppProject) ([]*unstructured.Unstructured, *apiclient.ManifestResponse, error) {
drySources := []appv1.ApplicationSource{drySource}
dryRevisions := []string{revision}
appLabelKey, err := ctrl.settingsMgr.GetAppInstanceLabelKey()
if err != nil {
return nil, nil, fmt.Errorf("failed to get app instance label key: %w", err)
}
app := origApp.DeepCopy()
// Remove the manifest generate path annotation, because the feature will misbehave for apps using source hydrator.
// Setting this annotation causes GetRepoObjs to compare the dry source commit to the most recent synced commit. The
// problem is that the most recent synced commit is likely on the hydrated branch, not the dry branch. The
// comparison will throw an error and break hydration.
//
// The long-term solution will probably be to persist the synced _dry_ revision and use that for the comparison.
delete(app.Annotations, appv1.AnnotationKeyManifestGeneratePaths)
// FIXME: use cache and revision cache
objs, resp, _, err := ctrl.appStateManager.GetRepoObjs(app, sources, appLabelKey, revisions, true, true, false, project, false, false)
objs, resp, _, err := ctrl.appStateManager.GetRepoObjs(app, drySources, appLabelKey, dryRevisions, true, true, false, project, false, false)
if err != nil {
return nil, nil, fmt.Errorf("failed to get repo objects: %w", err)
}
@@ -56,8 +66,17 @@ func (ctrl *ApplicationController) GetWriteCredentials(ctx context.Context, repo
return ctrl.db.GetWriteRepository(ctx, repoURL, project)
}
func (ctrl *ApplicationController) RequestAppRefresh(appName string) {
ctrl.requestAppRefresh(appName, CompareWithLatest.Pointer(), nil)
func (ctrl *ApplicationController) RequestAppRefresh(appName string, appNamespace string) error {
// We request a refresh by setting the annotation instead of by adding it to the refresh queue, because there is no
// guarantee that the hydrator is running on the same controller shard as is processing the application.
// This function is called for each app after a hydrate operation is completed so that the app controller can pick
// up the newly-hydrated changes. So we set hydrate=false to avoid a hydrate loop.
_, err := argoutil.RefreshApp(ctrl.applicationClientset.ArgoprojV1alpha1().Applications(appNamespace), appName, appv1.RefreshTypeNormal, false)
if err != nil {
return fmt.Errorf("failed to request app refresh: %w", err)
}
return nil
}
func (ctrl *ApplicationController) PersistAppHydratorStatus(orig *appv1.Application, newStatus *appv1.SourceHydratorStatus) {

View File

@@ -108,6 +108,7 @@ type appStateManager struct {
appclientset appclientset.Interface
projInformer cache.SharedIndexInformer
kubectl kubeutil.Kubectl
onKubectlRun kubeutil.OnKubectlRunFunc
repoClientset apiclient.Clientset
liveStateCache statecache.LiveStateCache
cache *appstatecache.Cache
@@ -168,9 +169,13 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
}
ts.AddCheckpoint("build_options_ms")
serverVersion, apiResources, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server)
if err != nil {
return nil, nil, false, fmt.Errorf("failed to get cluster version for cluster %q: %w", app.Spec.Destination.Server, err)
var serverVersion string
var apiResources []kubeutil.APIResourceInfo
if sendRuntimeState {
serverVersion, apiResources, err = m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server)
if err != nil {
return nil, nil, false, fmt.Errorf("failed to get cluster version for cluster %q: %w", app.Spec.Destination.Server, err)
}
}
conn, repoClient, err := m.repoClientset.NewRepoServerClient()
if err != nil {
@@ -223,8 +228,6 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
apiVersions := argo.APIResourcesToStrings(apiResources, true)
if !sendRuntimeState {
appNamespace = ""
apiVersions = nil
serverVersion = ""
}
if !source.IsHelm() && syncedRevision != "" && keyManifestGenerateAnnotationExists && keyManifestGenerateAnnotationVal != "" {
@@ -478,7 +481,6 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
// return unknown comparison result if basic comparison settings cannot be loaded
if err != nil {
now := metav1.Now()
if hasMultipleSources {
return &comparisonResult{
syncStatus: &v1alpha1.SyncStatus{
@@ -486,7 +488,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
Status: v1alpha1.SyncStatusCodeUnknown,
Revisions: revisions,
},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
}, nil
} else {
return &comparisonResult{
@@ -495,7 +497,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
Status: v1alpha1.SyncStatusCodeUnknown,
Revision: revisions[0],
},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
}, nil
}
}
@@ -739,13 +741,13 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
diffConfigBuilder.WithServerSideDiff(serverSideDiff)
if serverSideDiff {
resourceOps, cleanup, err := m.getResourceOperations(app.Spec.Destination.Server)
applier, cleanup, err := m.getServerSideDiffDryRunApplier(app.Spec.Destination.Server)
if err != nil {
log.Errorf("CompareAppState error getting resource operations: %s", err)
log.Errorf("CompareAppState error getting server side diff dry run applier: %s", err)
conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionUnknownError, Message: err.Error(), LastTransitionTime: &now})
}
defer cleanup()
diffConfigBuilder.WithServerSideDryRunner(diff.NewK8sServerSideDryRunner(resourceOps))
diffConfigBuilder.WithServerSideDryRunner(diff.NewK8sServerSideDryRunner(applier))
}
// enable structured merge diff if application syncs with server-side apply
@@ -1070,6 +1072,7 @@ func NewAppStateManager(
repoClientset apiclient.Clientset,
namespace string,
kubectl kubeutil.Kubectl,
onKubectlRun kubeutil.OnKubectlRunFunc,
settingsMgr *settings.SettingsManager,
liveStateCache statecache.LiveStateCache,
projInformer cache.SharedIndexInformer,
@@ -1088,6 +1091,7 @@ func NewAppStateManager(
db: db,
appclientset: appclientset,
kubectl: kubectl,
onKubectlRun: onKubectlRun,
repoClientset: repoClientset,
namespace: namespace,
settingsMgr: settingsMgr,

View File

@@ -715,7 +715,7 @@ func TestSetHealth(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
}
func TestPreserveStatusTimestamp(t *testing.T) {
@@ -790,7 +790,7 @@ func TestSetHealthSelfReferencedApp(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
}
func TestSetManagedResourcesWithOrphanedResources(t *testing.T) {
@@ -866,7 +866,7 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status)
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status)
}

View File

@@ -14,6 +14,7 @@ import (
cdcommon "github.com/argoproj/argo-cd/v2/common"
gitopsDiff "github.com/argoproj/gitops-engine/pkg/diff"
"github.com/argoproj/gitops-engine/pkg/sync"
"github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
@@ -33,6 +34,7 @@ import (
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/glob"
kubeutil "github.com/argoproj/argo-cd/v2/util/kube"
logutils "github.com/argoproj/argo-cd/v2/util/log"
"github.com/argoproj/argo-cd/v2/util/lua"
"github.com/argoproj/argo-cd/v2/util/rand"
@@ -66,11 +68,11 @@ func (m *appStateManager) getGVKParser(server string) (*managedfields.GvkParser,
return cluster.GetGVKParser(), nil
}
// getResourceOperations will return the kubectl implementation of the ResourceOperations
// interface that provides functionality to manage kubernetes resources. Returns a
// getServerSideDiffDryRunApplier will return the kubectl implementation of the KubeApplier
// interface that provides functionality to dry run apply kubernetes resources. Returns a
// cleanup function that must be called to remove the generated kube config for this
// server.
func (m *appStateManager) getResourceOperations(server string) (kube.ResourceOperations, func(), error) {
func (m *appStateManager) getServerSideDiffDryRunApplier(server string) (gitopsDiff.KubeApplier, func(), error) {
clusterCache, err := m.liveStateCache.GetClusterCache(server)
if err != nil {
return nil, nil, fmt.Errorf("error getting cluster cache: %w", err)
@@ -85,7 +87,7 @@ func (m *appStateManager) getResourceOperations(server string) (kube.ResourceOpe
if err != nil {
return nil, nil, fmt.Errorf("error getting cluster REST config: %w", err)
}
ops, cleanup, err := m.kubectl.ManageResources(rawConfig, clusterCache.GetOpenAPISchema())
ops, cleanup, err := kubeutil.ManageServerSideDiffDryRuns(rawConfig, clusterCache.GetOpenAPISchema(), m.onKubectlRun)
if err != nil {
return nil, nil, fmt.Errorf("error creating kubectl ResourceOperations: %w", err)
}
@@ -112,15 +114,6 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
}
syncOp = *state.Operation.Sync
// validates if it should fail the sync if it finds shared resources
hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app)
if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") &&
hasSharedResource {
state.Phase = common.OperationFailed
state.Message = fmt.Sprintf("Shared resource found: %s", sharedResourceMessage)
return
}
isMultiSourceRevision := app.Spec.HasMultipleSources()
rollback := len(syncOp.Sources) > 0 || syncOp.Source != nil
if rollback {
@@ -211,6 +204,15 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
syncRes.Revision = compareResult.syncStatus.Revision
syncRes.Revisions = compareResult.syncStatus.Revisions
// validates if it should fail the sync if it finds shared resources
hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app)
if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") &&
hasSharedResource {
state.Phase = common.OperationFailed
state.Message = fmt.Sprintf("Shared resource found: %s", sharedResourceMessage)
return
}
// If there are any comparison or spec errors error conditions do not perform the operation
if errConditions := app.Status.GetConditions(map[v1alpha1.ApplicationConditionType]bool{
v1alpha1.ApplicationConditionComparisonError: true,

View File

@@ -15,6 +15,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
argocommon "github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/controller/testdata"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
@@ -190,17 +191,23 @@ func TestSyncComparisonError(t *testing.T) {
}
func TestAppStateManager_SyncAppState(t *testing.T) {
t.Parallel()
type fixture struct {
project *v1alpha1.AppProject
application *v1alpha1.Application
project *v1alpha1.AppProject
controller *ApplicationController
}
setup := func() *fixture {
setup := func(liveObjects map[kube.ResourceKey]*unstructured.Unstructured) *fixture {
app := newFakeApp()
app.Status.OperationState = nil
app.Status.History = nil
if liveObjects == nil {
liveObjects = make(map[kube.ResourceKey]*unstructured.Unstructured)
}
project := &v1alpha1.AppProject{
ObjectMeta: v1.ObjectMeta{
Namespace: test.FakeArgoCDNamespace,
@@ -208,6 +215,12 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
},
Spec: v1alpha1.AppProjectSpec{
SignatureKeys: []v1alpha1.SignatureKey{{KeyID: "test"}},
Destinations: []v1alpha1.ApplicationDestination{
{
Namespace: "*",
Server: "*",
},
},
},
}
data := fakeData{
@@ -218,13 +231,13 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
Server: test.FakeClusterURL,
Revision: "abc123",
},
managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured),
managedLiveObjs: liveObjects,
}
ctrl := newFakeController(&data, nil)
return &fixture{
project: project,
application: app,
project: project,
controller: ctrl,
}
}
@@ -232,13 +245,23 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
t.Run("will fail the sync if finds shared resources", func(t *testing.T) {
// given
t.Parallel()
f := setup()
syncErrorMsg := "deployment already applied by another application"
condition := v1alpha1.ApplicationCondition{
Type: v1alpha1.ApplicationConditionSharedResourceWarning,
Message: syncErrorMsg,
}
f.application.Status.Conditions = append(f.application.Status.Conditions, condition)
sharedObject := kube.MustToUnstructured(&corev1.ConfigMap{
TypeMeta: v1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: v1.ObjectMeta{
Name: "configmap1",
Namespace: "default",
Labels: map[string]string{
argocommon.LabelKeyAppInstance: "another-app",
},
},
})
liveObjects := make(map[kube.ResourceKey]*unstructured.Unstructured)
liveObjects[kube.GetResourceKey(sharedObject)] = sharedObject
f := setup(liveObjects)
// Sync with source unspecified
opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{
@@ -253,7 +276,7 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
// then
assert.Equal(t, common.OperationFailed, opState.Phase)
assert.Contains(t, opState.Message, syncErrorMsg)
assert.Contains(t, opState.Message, "ConfigMap/configmap1 is part of applications fake-argocd-ns/my-app and another-app")
})
}

View File

@@ -272,6 +272,8 @@ data:
applicationsetcontroller.requeue.after: "3m"
# Enable strict mode for tokenRef in ApplicationSet resources. When enabled, the referenced secret must have a label `argocd.argoproj.io/secret-type` with value `scm-creds`.
applicationsetcontroller.enable.tokenref.strict.mode: "false"
# The maximum number of resources stored in the status of an ApplicationSet. This is a safeguard to prevent the status from growing too large.
applicationsetcontroller.status.max.resources.count: "5000"
## Argo CD Notifications Controller Properties
# Set the logging level. One of: debug|info|warn|error (default "info")

View File

@@ -15,7 +15,7 @@ to indicate their stability and maturity. These are the statuses of non-stable f
## Overview
| Feature | Introduced | Status |
| ----------------------------------------- | ---------- | ------ |
|-------------------------------------------|------------|--------|
| [AppSet Progressive Syncs][2] | v2.6.0 | Alpha |
| [Proxy Extensions][3] | v2.7.0 | Alpha |
| [Skip Application Reconcile][4] | v2.7.0 | Alpha |
@@ -25,6 +25,7 @@ to indicate their stability and maturity. These are the statuses of non-stable f
| [Server Side Diff][8] | v2.10.0 | Beta |
| [Cluster Sharding: consistent-hashing][9] | v2.12.0 | Alpha |
| [Service Account Impersonation][10] | v2.13.0 | Alpha |
| [Source Hydrator][11] | v2.14.0 | Alpha |
## Unstable Configurations
@@ -83,3 +84,4 @@ to indicate their stability and maturity. These are the statuses of non-stable f
[8]: ../user-guide/diff-strategies.md#server-side-diff
[9]: ./high_availability.md#argocd-application-controller
[10]: app-sync-using-impersonation.md
[11]: ../user-guide/source-hydrator.md

View File

@@ -2,7 +2,7 @@
Argo CD is largely stateless. All data is persisted as Kubernetes objects, which in turn is stored in Kubernetes' etcd. Redis is only used as a throw-away cache and can be lost. When lost, it will be rebuilt without loss of service.
A set of [HA manifests](https://github.com/argoproj/argo-cd/tree/master/manifests/ha) are provided for users who wish to run Argo CD in a highly available manner. This runs more containers, and runs Redis in HA mode.
A set of [HA manifests](https://github.com/argoproj/argo-cd/tree/stable/manifests/ha) are provided for users who wish to run Argo CD in a highly available manner. This runs more containers, and runs Redis in HA mode.
> **NOTE:** The HA installation will require at least three different nodes due to pod anti-affinity roles in the
> specs. Additionally, IPv6 only clusters are not supported.

View File

@@ -70,6 +70,7 @@ argocd-application-controller [flags]
--repo-server-timeout-seconds int Repo server RPC call timeout seconds. (default 60)
--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")
--self-heal-backoff-cap-seconds int Specifies max timeout of exponential backoff between application self heal attempts (default 300)
--self-heal-backoff-cooldown-seconds int Specifies period of time the app needs to stay synced before the self heal backoff can reset (default 330)
--self-heal-backoff-factor int Specifies factor of exponential timeout between application self heal attempts (default 3)
--self-heal-backoff-timeout-seconds int Specifies initial timeout of exponential backoff between self heal attempts (default 2)
--self-heal-timeout-seconds int Specifies timeout between application self heal attempts

View File

@@ -3,4 +3,12 @@
## Upgraded Helm Version
Helm was upgraded to 3.16.2 and the skipSchemaValidation Flag was added to
the [CLI and Application CR](https://argo-cd.readthedocs.io/en/latest/user-guide/helm/#helm-skip-schema-validation).
the [CLI and Application CR](https://argo-cd.readthedocs.io/en/latest/user-guide/helm/#helm-skip-schema-validation).
## Breaking Changes
## Sanitized project API response
Due to security reasons ([GHSA-786q-9hcg-v9ff](https://github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff)),
the project API response was sanitized to remove sensitive information. This includes
credentials of project-scoped repositories and clusters.

View File

@@ -31,6 +31,7 @@ argocd [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -71,6 +71,7 @@ argocd account [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -44,6 +44,7 @@ argocd account bcrypt --password YOUR_PASSWORD
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -54,6 +54,7 @@ Resources: [clusters projects applications applicationsets repositories write-re
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -47,6 +47,7 @@ argocd account delete-token --account <account-name> ID
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -49,6 +49,7 @@ argocd account generate-token --account <account-name>
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -47,6 +47,7 @@ argocd account get-user-info [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -48,6 +48,7 @@ argocd account get --account <account-name>
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -43,6 +43,7 @@ argocd account list
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -59,6 +59,7 @@ argocd account update-password [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -47,6 +47,7 @@ $ argocd admin initial-password reset
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -51,6 +51,7 @@ argocd admin app get-reconcile-results APPNAME
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -36,6 +36,7 @@ argocd admin app diff-reconcile-results PATH1 PATH2 [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -134,6 +134,7 @@ argocd admin app generate-spec APPNAME [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -62,6 +62,7 @@ argocd admin app get-reconcile-results PATH [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -50,6 +50,7 @@ argocd admin cluster namespaces my-cluster
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -60,6 +60,7 @@ argocd admin cluster generate-spec CONTEXT [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -73,6 +73,7 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -56,6 +56,7 @@ argocd admin cluster namespaces [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -57,6 +57,7 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -59,6 +59,7 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -42,7 +42,6 @@ $ argocd admin dashboard --redis-compress gzip
--password string Password for basic authentication to the API server
--port int Listen on given port (default 8080)
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--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.
@@ -73,6 +72,7 @@ $ argocd admin dashboard --redis-compress gzip
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -59,6 +59,7 @@ argocd admin export [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -63,6 +63,7 @@ argocd admin import SOURCE [flags]
--plaintext Disable TLS
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -56,6 +56,7 @@ argocd admin initial-password [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -61,6 +61,7 @@ argocd admin notifications [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -54,6 +54,7 @@ argocd admin notifications template [flags]
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -66,6 +66,7 @@ argocd admin notifications template get app-sync-succeeded -o=yaml
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -67,6 +67,7 @@ argocd admin notifications template notify app-sync-succeeded guestbook
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -54,6 +54,7 @@ argocd admin notifications trigger [flags]
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -66,6 +66,7 @@ argocd admin notifications trigger get on-sync-failed -o=yaml
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -66,6 +66,7 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -36,6 +36,7 @@ argocd admin proj [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -64,6 +64,7 @@ argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -64,6 +64,7 @@ argocd admin proj generate-spec PROJECT [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -72,6 +72,7 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -56,6 +56,7 @@ argocd admin redis-initial-password [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -36,6 +36,7 @@ argocd admin repo [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -84,6 +84,7 @@ argocd admin repo generate-spec REPOURL [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -59,6 +59,7 @@ argocd admin settings [flags]
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -53,6 +53,7 @@ argocd admin settings rbac [flags]
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -94,6 +94,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -86,6 +86,7 @@ argocd admin settings rbac validate --namespace argocd
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -53,6 +53,7 @@ argocd admin settings resource-overrides [flags]
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -64,6 +64,7 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path .
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -64,6 +64,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

View File

@@ -65,6 +65,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml -
--port-forward-namespace string Namespace name which should be used for port forwarding
--prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.
--proxy-url string If provided, this URL will be used to connect via proxy
--redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip")
--redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy")
--redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis")
--repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server")

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