Compare commits

...

66 Commits

Author SHA1 Message Date
argo-bot
0554262ccb Bump version to 2.5.22 2023-08-25 14:28:40 +00:00
argo-bot
3397b935b2 Bump version to 2.5.22 2023-08-25 14:28:35 +00:00
Michael Crenshaw
1503fd9480 chore: free up less disk space
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-08-25 10:03:13 -04:00
Michael Crenshaw
003d224c80 chore(ci): free up disk space
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-08-25 10:03:07 -04:00
gcp-cherry-pick-bot[bot]
e19d6dfa1f docs: add ignoreDifferences name and namespace fields (#14741) (#14808)
* Update application.yaml



* Update docs/operator-manual/application.yaml



---------

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-08-03 10:28:12 -04:00
gcp-cherry-pick-bot[bot]
5bb14a8873 docs: Change Generator docs for List Generator to note any key/value pairs can be used (#14825) (#14835)
This is no longer limited to cluster/url value pairs.

Signed-off-by: JesseBot <jessebot@linux.com>
Co-authored-by: JesseBot <jessebot@linux.com>
2023-08-01 13:56:24 -04:00
Alexander Matyushentsev
3ab4b2b42c fix(controller): cache deadlock on delete and re-add cluster (cherry-pick #14780) (#14815)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2023-08-01 08:23:06 -07:00
gcp-cherry-pick-bot[bot]
d7c2dd58e4 fix(sso): Set redirectURI for gitea, google, oauth Dex connectors (#11237) (#14739)
Signed-off-by: ylxianzhe <ylxianzhe@outlook.com>
Co-authored-by: XianzheTM <ylxianzhe@outlook.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-07-27 10:16:51 -04:00
gcp-cherry-pick-bot[bot]
daaf88a2c6 fix(server): handle PATCH in http/s server (#2677) (#14530) (#14734)
Signed-off-by: mmerrill3 <jjpaacks@gmail.com>
Co-authored-by: Michael Merrill <jjpaacks@gmail.com>
2023-07-27 10:15:24 -04:00
Yuan Tang
74600fc7a1 chore: Print in-cluster svr addr disabled warning when server starts (#14683)
* chore: Update log level to warn when in-cluster svr addr is disabled but internal addr is used (#14520)

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

* chore: Print in-cluster svr addr disabled warning during ArgoDB initialization (#14539)

* chore: Print in-cluster svr addr disabled warning during ArgoDB initialization

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

* fix: undo a change

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

* chore: move to a function

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

* chore: rename

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

---------

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

* chore: Print in-cluster svr addr disabled warning when server starts (#14553)

* chore: Print in-cluster svr addr disabled warning when server starts

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

* fix: mock

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>

* no interface change

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

---------

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

---------

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-07-24 17:25:26 -04:00
gcp-cherry-pick-bot[bot]
df7e6df64c fix: ApplicationSet Controller crashes when tag is not closed; panic: Cannot find end tag="}}"(#14227) ( #14227) (#14689) (#14691)
* appSet fix



* Update applicationset/utils/utils_test.go



---------

Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: schakrad <58915923+schakrad@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-07-24 17:25:10 -04:00
gcp-cherry-pick-bot[bot]
2fa12c8c99 docs: Skip export keyword in notification docs (#14633) (#14645)
This change does three things:

1. It removes the `export` keyword. It's not required since the example
   executes a script where the variables are evaluated as an inline
   string. One could even argue that there is a slight security issue
   with using `export` here, since that will expose the credentials to
   all applications started in the current context.
2. It adds a space (` `) before the `PASSWORD` variable. This will keep
   it out of the user's Bash history by default. See [HISTIGNORE][bash].
3. Add a newline for clarity.

[bash]: https://www.gnu.org/software/bash/manual/bash.html#index-HISTIGNORE

Signed-off-by: Andreas Lindhé <andreas@lindhe.io>
Co-authored-by: Andreas Lindhé <lindhe@users.noreply.github.com>
2023-07-21 10:17:10 -04:00
argo-bot
f627b62f29 Bump version to 2.5.21 2023-07-19 15:10:14 +00:00
argo-bot
1680a41fa6 Bump version to 2.5.21 2023-07-19 15:10:08 +00:00
gcp-cherry-pick-bot[bot]
21988d857a fix(cli): argocd CLI RBAC validation doesn't work on actions (#13911) (#14578) (#14584)
* #11602 fix : Object options menu truncated when selected in ApplicationListView.



* #11602 fix : Object options menu truncated when selected in ApplicationListView.



* changes for argocd_rbac



---------

Signed-off-by: schakradari <saisindhu_chakradari@intuit.com>
Signed-off-by: schakrad <chakradari.sindhu@gmail.com>
Co-authored-by: schakrad <58915923+schakrad@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-07-18 16:22:32 -04:00
gcp-cherry-pick-bot[bot]
791231490c fix: 'argocd-server-tls' Secret should be loaded from informer (#14522) (#14549)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2023-07-17 12:02:35 -04:00
Haitao Li
f37a682fb1 fix: Update bitbucket.org rsa ssh key (cherry-pick #14392) (#14409)
The key change announcement at https://bitbucket.org/blog/ssh-host-key-changes

Signed-off-by: Haitao Li <hli@atlassian.com>
2023-07-11 10:48:42 -04:00
gcp-cherry-pick-bot[bot]
305fcb556b docs: managedFieldsManagers example in docs needs double-quotes (#14324) (#14374)
* is a Yaml special character and must be quoted, otherwise ArgoCD fails to parse and shows an error.

Signed-off-by: Paul Martin <paul.martin@gmail.com>
Co-authored-by: Paul Martin <paul.martin@gmail.com>
2023-07-06 13:50:11 -04:00
argo-bot
bea852b1ea Bump version to 2.5.20 2023-07-05 19:30:19 +00:00
argo-bot
fb9b608da1 Bump version to 2.5.20 2023-07-05 19:30:16 +00:00
Venkata Mutyala
18f5bfab92 feat: upgrade dexIDP from 2.36.0 -> 2.37.0 (#14305) (#14310) (#14320)
* feat: update dexidp image tag from v2.36.0 -> v2.37.0



* chore: adding GlueOps to USERS.md



---------

Signed-off-by: Venkata Mutyala <venkata@venkatamutyala.com>
2023-07-03 12:54:41 -07:00
gcp-cherry-pick-bot[bot]
ad335936e7 docs: Clarify "SSH known host public keys" text (#13537) (#14300)
Add `ssh_keyscan` example usage

Signed-off-by: Daniel Perevalov <daniel.perevalov@gmail.com>
Co-authored-by: Daniel Perevalov <daniel.perevalov@gmail.com>
2023-06-30 19:35:16 -04:00
gcp-cherry-pick-bot[bot]
b359505688 docs: explicit that ArgoCD hooks replaces the Helm ones (#14283) (#14290)
* docs: explicit that ArgoCD hooks replace the Helm ones

After digging a bit in the code, I've found this comment that confirms
that if we define some ArgoCD hooks the Helm ones are ignored.
425d65e076/pkg/sync/hook/hook.go (L36C2-L36C46)



* docs: add Back Market in the user list



* Update docs/user-guide/helm.md



---------

Signed-off-by: Benoît Sauvère <benoit.sauvere@backmarket.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Benoît Sauvère <benoit@sauve.re>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-06-30 11:39:23 -04:00
gcp-cherry-pick-bot[bot]
a5d6602385 docs: Add documentation on background cascading deletion (#12229) (#14151)
Signed-off-by: toyamagu2021@gmail.com <toyamagu2021@gmail.com>
Co-authored-by: toyamagu <83329336+toyamagu-2021@users.noreply.github.com>
2023-06-20 21:29:52 -04:00
argo-bot
9f09e08548 Bump version to 2.5.19 2023-06-16 14:18:53 +00:00
argo-bot
b43bb659cf Bump version to 2.5.19 2023-06-16 14:18:46 +00:00
gcp-cherry-pick-bot[bot]
d62b03781c fix(cli): support application in any namespace with argocd app diff (#13978) (#13980) (#14063)
Closes https://github.com/argoproj/argo-cd/issues/13978.

Signed-off-by: mugioka <okamugi0722@gmail.com>
Co-authored-by: mugi <62197019+mugioka@users.noreply.github.com>
2023-06-14 15:21:41 -04:00
gcp-cherry-pick-bot[bot]
a6d2438d13 docs: add golang upgrade note for 2.5 (#14048) (#14059)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-06-14 15:08:41 -04:00
gcp-cherry-pick-bot[bot]
0ffa7d4bde docs: add documentation for child elements of path (#14044) (#14056)
* docs: add documentation for child elements of path

When using go templating, the parent `{{ path }}` becomes `{{ .path.path }}, however, the other values are not at `{{ .path.path.* }}`, but at `{{ .path.* }}`.

This documentation update seeks to make this easier to understand since we just ran into this.



* Update docs/operator-manual/applicationset/GoTemplate.md




---------

Signed-off-by: Morre <mmeyer@anaconda.com>
Signed-off-by: Morre <morre@mor.re>
Co-authored-by: Morre <morre@mor.re>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-06-14 15:07:22 -04:00
gcp-cherry-pick-bot[bot]
5e5b72da05 chore(deps): upgrade haproxy to 2.6.14-alpine (#14018) (#14053)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-06-14 15:06:27 -04:00
Michael Crenshaw
d296b41517 fix(security): upgrade go to 1.19 (#14023)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-06-14 11:38:53 -04:00
gcp-cherry-pick-bot[bot]
6f83c61dab fix(ui): Fix Patch and Get Manifests (#13949) (#13954)
Signed-off-by: Geoffrey Muselli <geoffrey.muselli@gmail.com>
Co-authored-by: Geoffrey MUSELLI <geoffrey.muselli@gmail.com>
2023-06-08 08:12:40 -04:00
argo-bot
b56ef0584c Bump version to 2.5.18 2023-06-05 18:44:54 +00:00
argo-bot
8b0b947144 Bump version to 2.5.18 2023-06-05 18:44:51 +00:00
Lewis Marsden-Lambert
431dc6cb40 fix(appset): Post selector with Go templates in ApplicationSet (cherry-pick #13584) (#13824)
* fix(appset): Post selector with Go templates in ApplicationSet (#13584)

* fixes #12524

Signed-off-by: Lewis Marsden-Lambert <lewis.lambert@zserve.co.uk>

* refactor keepOnlyStringLabels function into more generic map flattening function

Signed-off-by: Lewis Marsden-Lambert <lewis.lambert@zserve.co.uk>

* updated USERS.md

Signed-off-by: Lewis Marsden-Lambert <lewis.marsden-lambert@smartpension.co.uk>

* use flatten library to replace custom flatten function

Signed-off-by: Lewis Marsden-Lambert <lewis.marsden-lambert@smartpension.co.uk>

---------

Signed-off-by: Lewis Marsden-Lambert <lewis.lambert@zserve.co.uk>
Signed-off-by: Lewis Marsden-Lambert <lewis.marsden-lambert@smartpension.co.uk>

* fixed tests

Signed-off-by: Lewis Marsden-Lambert <lewis.lambert@zserve.co.uk>

* fixed missing import

Signed-off-by: Lewis Marsden-Lambert <lewis.lambert@zserve.co.uk>

---------

Signed-off-by: Lewis Marsden-Lambert <lewis.lambert@zserve.co.uk>
Signed-off-by: Lewis Marsden-Lambert <lewis.marsden-lambert@smartpension.co.uk>
2023-06-01 09:57:10 -04:00
Brian Fox
801e19518e fix: ensure repositories are correctly marked with inherited creds in CLI output (#13428) (#13808)
* tests: ensure `InheritedCreds` is propagated via repo API endpoints



* fix: ensure `InheritedCreds` is propagated via repo API endpoints



* tests: add e2e test for `argocd repo get` with inherited credentials



* fix(cli): prioritise value of `InheritedCreds` over `HasCredentials()`

Since the API does not return sensitive information `HasCredentials()` will return false for all scenarios except when username/password is used as credentials. Given the current logic this means that the code will never even check `InheritedCreds` resulting in an output of `false` for `CREDS` column (in the case of inherited credentials).

Note: There remains a bug in this code in that any repo that has explicit (sensitive) credentials (e.g. SSH private key) will still be displayed as `CREDS = false`.


---------

Signed-off-by: OneMatchFox <878612+onematchfox@users.noreply.github.com>
2023-05-29 10:23:16 -04:00
Tete17
deaaf9aafd fix(ui): Stop using the deprecated url format for gitlab instances (#13687) (#13797)
* fix: Stop using the deprecated url format for gitlab instances

The legacy URLs format has been deprecated since february 2023 and
now gitlab is make these urls invalid.

Ref: https://docs.gitlab.com/ee/update/deprecations.html#legacy-urls-replaced-or-removed


* docs: Add Urbantz to the list of organizations using argo-cd



---------



(cherry picked from commit 5662367474)

Signed-off-by: Miguel Sacristán Izcue <miguel_tete17@hotmail.com>
2023-05-28 16:17:28 -04:00
gcp-cherry-pick-bot[bot]
5640b727a4 docs: update openunison authChainName (#13531) (#13795)
Signed-off-by: Samir-NT <133138781+Samir-NT@users.noreply.github.com>
Co-authored-by: Samir-NT <133138781+Samir-NT@users.noreply.github.com>
2023-05-28 15:51:10 -04:00
gcp-cherry-pick-bot[bot]
e166cfaf7e docs: Update disaster_recovery.md to reflect quay.io as docker container registry (#13520) (#13792)
ArgoCD docker images are being used from `quay.io` registry.
Updated document to reflect that in the `bash` commands.

Signed-off-by: Divyang Patel <divyang.jp@gmail.com>
Co-authored-by: Divyang Patel <divyang.jp@gmail.com>
2023-05-28 15:48:25 -04:00
Blake Pettersson
e1184b4f3d test: remove testmatchvaluesgotemplate (#13787)
This test came with the previous cherry-pick, but should not be present
for 2.5 - 2.7.

Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
2023-05-28 08:23:22 -04:00
gcp-cherry-pick-bot[bot]
7aea7281ca docs: Fixed titles in app deletion doc (#13469) (#13784)
Signed-off-by: michaelkot97 <michael.kot97@gmail.com>
Co-authored-by: Michael Kotelnikov <36506417+michaelkotelnikov@users.noreply.github.com>
2023-05-27 21:47:05 -04:00
gcp-cherry-pick-bot[bot]
389a36bff8 fix: Regression in signature verification for git tags (#12797) (#13111)
Signed-off-by: jannfis <jann@mistrust.net>
Co-authored-by: jannfis <jann@mistrust.net>
2023-05-27 21:24:53 -04:00
gcp-cherry-pick-bot[bot]
930b4c9f9a docs: add helm values declarative syntax (#13661) (#13780)
The Helm section of the user guide is missing an example of using `source.helm.values`.

Signed-off-by: Nicholas Morey <nicholas@morey.tech>
Co-authored-by: Nicholas Morey <nicholas@morey.tech>
2023-05-27 20:56:30 -04:00
gcp-cherry-pick-bot[bot]
9557dd6098 docs: fix incorrect instructions for site documentation (#13209) (#13775)
* fix: incorrect instructions for site documentation



* drop checking external links



---------

Signed-off-by: Regina Scott <rescott@redhat.com>
Co-authored-by: Regina Scott <50851526+reginapizza@users.noreply.github.com>
2023-05-27 16:46:15 -04:00
Blake Pettersson
62ab3a4a63 fix(appset): allow cluster urls to be matched (#13715) (#13772)
* fix: allow cluster urls to be matched

Related to #13646, and after discussion with @crenshaw-dev, it turns
out that matching on cluster urls is not possible. This is due to the
fact that the implementation of `LabelSelectorAsSelector` from
`k8s.io/apimachinery` validates that a label value is no longer than 63
characters, and validates that it's alphanumeric. In order to work
around that, we'll create our own implementation of
`LabelSelectorAsSelector`.

This implementation has been copied verbatim, with the difference that
in `isValidLabelValue`, we first check if the label value is a valid
url. If it is not, we proceed with the label checks as with the
original implementation.

Apart from that, the only other differences are making as much as
possible to be package-private; the intent is to only make `Matches`
and `LabelSelectorAsSelector` available from outside the package.



* chore: drop all label value restrictions

We want to be more flexible in what we accept in post-selectors, mainly
that we want to allow other values than only server urls. For this, we
will drop all restrictions that a typical "label value" would typically
have.



---------

Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
2023-05-27 16:08:56 -04:00
gcp-cherry-pick-bot[bot]
da001b2a95 docs: correct indentation for gke ingress (#13680) (#13763)
Signed-off-by: Carlos Sanchez <carlos@apache.org>
Co-authored-by: Carlos Sanchez <carlos@apache.org>
2023-05-27 12:31:29 -04:00
argo-bot
c06f954730 Bump version to 2.5.17 2023-05-25 15:43:33 +00:00
argo-bot
c5dfd754e4 Bump version to 2.5.17 2023-05-25 15:43:24 +00:00
Michael Crenshaw
f8e5340f7d Revert "Bump version to 2.5.17 (#13717)" (#13727)
This reverts commit 20a5873fd8.

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-05-24 11:18:09 -04:00
github-actions[bot]
20a5873fd8 Bump version to 2.5.17 (#13717)
Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: crenshaw-dev <crenshaw-dev@users.noreply.github.com>
2023-05-24 09:35:18 -04:00
gcp-cherry-pick-bot[bot]
e75cad1c37 fix: prevent concurrent processing if kustomize commonAnnotations exist (#13697) (#13704)
Signed-off-by: yilmazo <onuryilmaz93@yandex.com>
Co-authored-by: Onur Yilmaz <onuryilmaz93@yandex.com>
2023-05-23 11:36:55 -07:00
Justin Marquis
63b9319453 chore: upgrade redis to 7.0.11 to avoid CVE-2023-0464(release-2.5) (#13560)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2023-05-18 18:22:06 -04:00
gcp-cherry-pick-bot[bot]
e2d3a9ad68 fix: avoid acquiring lock on two mutexes at the same time to prevent deadlock (#13636) (#13650)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2023-05-18 13:06:16 -07:00
gcp-cherry-pick-bot[bot]
0882565801 Update kustomize resource to correct path (#13196) (#13630)
This commit updates the kustomize section to include the correct path.  Without the `\base` at the end of the path kustomize errors out trying to find a `kustomization.yaml` since there isn't one in the `ha` directory.

Signed-off-by: Chris Wiggins <5607419+cwiggs@users.noreply.github.com>
Co-authored-by: Chris Wiggins <5607419+cwiggs@users.noreply.github.com>
2023-05-18 09:12:28 -04:00
gcp-cherry-pick-bot[bot]
e6e4d584ed docs: fix typo (#12960) (#13438)
Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com>
Co-authored-by: Takumi Sue <23391543+mikutas@users.noreply.github.com>
2023-05-04 18:21:01 -04:00
gcp-cherry-pick-bot[bot]
89d4622ffa chore: upgrade haproxy to 2.6.12 to avoid CVE-2023-0464 (#13388) (#13399)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
Co-authored-by: Justin Marquis <34fathombelow@protonmail.com>
2023-05-01 16:43:13 -04:00
gcp-cherry-pick-bot[bot]
3b866db875 docs: Application Info field documentation (#10814) (#13351) (#13375)
* add Application info field documentation



* Extra Application info docs



* Added info field documentation



* Add space to comment




* docs: Add extra_info.md to table of contents



---------

Signed-off-by: Hapshanko <112761282+Hapshanko@users.noreply.github.com>
Co-authored-by: Hapshanko <112761282+Hapshanko@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-05-01 15:42:05 -04:00
gcp-cherry-pick-bot[bot]
75a65e97cf docs: s/No supported/Not supported (#13189) (#13255)
Signed-off-by: Vincent Verleye <124772102+smals-vinve@users.noreply.github.com>
Co-authored-by: Vincent Verleye <124772102+smals-vinve@users.noreply.github.com>
2023-04-16 01:34:40 -04:00
gcp-cherry-pick-bot[bot]
930017a3f1 docs: Fix wrong link to non existing page for applicationset reference (#13207) (#13249)
Signed-off-by: TheDatabaseMe <philip.haberkern@googlemail.com>
Co-authored-by: Philip Haberkern <59010269+thedatabaseme@users.noreply.github.com>
2023-04-15 14:33:58 -04:00
gcp-cherry-pick-bot[bot]
77fdcb7699 fix(cli): add redis-compress flag to argocd admin dashboard command (#13055) (#13056) (#13116)
* add `redis-compress` flag to `argocd admin dashboard` command

Previously, gzip compression was disabled and not configurable,
which made it impossible to work with gzipped Redis cache.
This commit adds support for gzip compression to the ArgoCD admin dashboard.



* update dashboard docs for --redis-compress flag



* add support for REDIS_COMRESSION env in cli admin dashboard



* update flag description




* update dashboard docs



---------

Signed-off-by: Pavel Aborilov <aborilov@gmail.com>
Signed-off-by: Pavel <aborilov@gmail.com>
Co-authored-by: Pavel <aborilov@gmail.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-04-06 16:08:06 -07:00
gcp-cherry-pick-bot[bot]
3edc147e74 chore: disable codeql workflow on cherry-pick branches (cherry-pick #12893) (#12899)
* fix codegen

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

* fix codegen

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

* chore: disable codeql workflow on cherry-pick branches (#12893)

Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>

---------

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Justin Marquis <34fathombelow@protonmail.com>
2023-04-04 16:44:52 -04:00
gcp-cherry-pick-bot[bot]
034e6cc92a docs: fix broken version selector (#13102) (#13107)
Signed-off-by: Harold Cheng <niuchangcun@gmail.com>
Co-authored-by: cjc7373 <niuchangcun@gmail.com>
2023-04-04 16:23:11 -04:00
Steve Ramage
ee174fa349 fix: make webhook handler work in all configured application namespaces (#11867) (#12386)
Signed-off-by: Steve Ramage <commits@sjrx.net>
Co-authored-by: Steve Ramage <commits@sjrx.net>
2023-03-24 11:42:01 -04:00
Nobuo Takizawa
36c987b3c2 chore: Bump dex from v2.35.3 to v2.36.0 (#12933)
Signed-off-by: nobuyo <longzechangsheng@gmail.com>
2023-03-24 09:55:14 -04:00
gcp-cherry-pick-bot[bot]
7d45aa99ba fix: trigger ApplicationSet reconciliation for clusters matching cluster generators in matrix or merge generators (#12543) (#12990)
Signed-off-by: alexandre.vilain <alexandre.vilain@corp.ovh.com>
Co-authored-by: Alexandre Vilain <alexandrevilain@users.noreply.github.com>
2023-03-24 09:51:19 -04:00
gcp-cherry-pick-bot[bot]
6e19199e10 chore: fix lint (#12972) (#12976)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2023-03-23 13:27:56 -04:00
88 changed files with 1786 additions and 274 deletions

View File

@@ -13,7 +13,7 @@ on:
env:
# Golang version to use across CI steps
GOLANG_VERSION: '1.18'
GOLANG_VERSION: '1.19'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -425,9 +425,9 @@ jobs:
git config --global user.email "john.doe@example.com"
- name: Pull Docker image required for tests
run: |
docker pull ghcr.io/dexidp/dex:v2.35.3
docker pull ghcr.io/dexidp/dex:v2.37.0
docker pull argoproj/argo-cd-ci-builder:v1.0.0
docker pull redis:7.0.8-alpine
docker pull redis:7.0.11-alpine
- name: Create target directory for binaries in the build-process
run: |
mkdir -p dist

View File

@@ -5,6 +5,7 @@ on:
# Secrets aren't available for dependabot on push. https://docs.github.com/en/enterprise-cloud@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/troubleshooting-the-codeql-workflow#error-403-resource-not-accessible-by-integration-when-using-dependabot
branches-ignore:
- 'dependabot/**'
- 'cherry-pick-*'
pull_request:
schedule:
- cron: '0 19 * * 0'

View File

@@ -10,7 +10,7 @@ on:
types: [ labeled, unlabeled, opened, synchronize, reopened ]
env:
GOLANG_VERSION: '1.18'
GOLANG_VERSION: '1.19'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}

View File

@@ -12,7 +12,7 @@ on:
- "!release-v0*"
env:
GOLANG_VERSION: '1.18'
GOLANG_VERSION: '1.19'
permissions:
contents: read
@@ -266,6 +266,14 @@ jobs:
body: ${{ steps.release-notes.outputs.content }}
if: ${{ env.DRY_RUN == 'true' }}
# Based on this suggestion: https://github.com/actions/runner-images/issues/2840#issuecomment-1284059930
- name: Free Up Disk Space
id: free-up-disk-space
run: |
df -h
sudo rm -rf /usr/share/dotnet
df -h
- name: Generate SBOM (spdx)
id: spdx-builder
env:

View File

@@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:22.04
# 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.18 AS builder
FROM docker.io/library/golang:1.19 AS builder
RUN echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list
@@ -99,7 +99,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.18 AS argocd-build
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.19 AS argocd-build
WORKDIR /go/src/github.com/argoproj/argo-cd

View File

@@ -21,6 +21,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Arctiq Inc.](https://www.arctiq.ca)
1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/)
1. [Axual B.V.](https://axual.com)
1. [Back Market](https://www.backmarket.com)
1. [Baloise](https://www.baloise.com)
1. [BCDevExchange DevOps Platform](https://bcdevexchange.org/DevOpsPlatform)
1. [Beat](https://thebeat.co/en/)
@@ -79,6 +80,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [gloat](https://gloat.com/)
1. [GLOBIS](https://globis.com)
1. [Glovo](https://www.glovoapp.com)
1. [GlueOps](https://glueops.dev)
1. [GMETRI](https://gmetri.com/)
1. [Gojek](https://www.gojek.io/)
1. [Greenpass](https://www.greenpass.com.br/)
@@ -186,6 +188,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Schwarz IT](https://jobs.schwarz/it-mission)
1. [Skit](https://skit.ai/)
1. [Skyscanner](https://www.skyscanner.net/)
1. [Smart Pension](https://www.smartpension.co.uk/)
1. [Smilee.io](https://smilee.io)
1. [Snapp](https://snapp.ir/)
1. [Snyk](https://snyk.io/)
@@ -222,6 +225,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [ungleich.ch](https://ungleich.ch/)
1. [Unifonic Inc](https://www.unifonic.com/)
1. [Universidad Mesoamericana](https://www.umes.edu.gt/)
1. [Urbantz](https://urbantz.com/)
1. [Viaduct](https://www.viaduct.ai/)
1. [Virtuo](https://www.govirtuo.com/)
1. [VISITS Technologies](https://visits.world/en)

View File

@@ -1 +1 @@
2.5.16
2.5.22

View File

@@ -2,6 +2,7 @@ package controllers
import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
@@ -46,7 +47,6 @@ type addRateLimitingInterface interface {
}
func (h *clusterSecretEventHandler) queueRelatedAppGenerators(q addRateLimitingInterface, object client.Object) {
// Check for label, lookup all ApplicationSets that might match the cluster, queue them all
if object.GetLabels()[generators.ArgoCDSecretTypeLabel] != generators.ArgoCDSecretTypeCluster {
return
@@ -73,6 +73,40 @@ func (h *clusterSecretEventHandler) queueRelatedAppGenerators(q addRateLimitingI
foundClusterGenerator = true
break
}
if generator.Matrix != nil {
ok, err := nestedGeneratorsHaveClusterGenerator(generator.Matrix.Generators)
if err != nil {
h.Log.
WithFields(log.Fields{
"namespace": appSet.GetNamespace(),
"name": appSet.GetName(),
}).
WithError(err).
Error("Unable to check if ApplicationSet matrix generators have cluster generator")
}
if ok {
foundClusterGenerator = true
break
}
}
if generator.Merge != nil {
ok, err := nestedGeneratorsHaveClusterGenerator(generator.Merge.Generators)
if err != nil {
h.Log.
WithFields(log.Fields{
"namespace": appSet.GetNamespace(),
"name": appSet.GetName(),
}).
WithError(err).
Error("Unable to check if ApplicationSet merge generators have cluster generator")
}
if ok {
foundClusterGenerator = true
break
}
}
}
if foundClusterGenerator {
@@ -82,3 +116,42 @@ func (h *clusterSecretEventHandler) queueRelatedAppGenerators(q addRateLimitingI
}
}
}
// nestedGeneratorsHaveClusterGenerator iterate over provided nested generators to check if they have a cluster generator.
func nestedGeneratorsHaveClusterGenerator(generators []argoprojiov1alpha1.ApplicationSetNestedGenerator) (bool, error) {
for _, generator := range generators {
if ok, err := nestedGeneratorHasClusterGenerator(generator); ok || err != nil {
return ok, err
}
}
return false, nil
}
// nestedGeneratorHasClusterGenerator checks if the provided generator has a cluster generator.
func nestedGeneratorHasClusterGenerator(nested argoprojiov1alpha1.ApplicationSetNestedGenerator) (bool, error) {
if nested.Clusters != nil {
return true, nil
}
if nested.Matrix != nil {
nestedMatrix, err := argoprojiov1alpha1.ToNestedMatrixGenerator(nested.Matrix)
if err != nil {
return false, fmt.Errorf("unable to get nested matrix generator: %w", err)
}
if nestedMatrix != nil {
return nestedGeneratorsHaveClusterGenerator(nestedMatrix.ToMatrixGenerator().Generators)
}
}
if nested.Merge != nil {
nestedMerge, err := argoprojiov1alpha1.ToNestedMergeGenerator(nested.Merge)
if err != nil {
return false, fmt.Errorf("unable to get nested merge generator: %w", err)
}
if nestedMerge != nil {
return nestedGeneratorsHaveClusterGenerator(nestedMerge.ToMergeGenerator().Generators)
}
}
return false, nil
}

View File

@@ -6,6 +6,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
@@ -163,7 +164,6 @@ func TestClusterEventHandler(t *testing.T) {
{NamespacedName: types.NamespacedName{Namespace: "another-namespace", Name: "my-app-set"}},
},
},
{
name: "non-argo cd secret should not match",
items: []argov1alpha1.ApplicationSet{
@@ -189,6 +189,348 @@ func TestClusterEventHandler(t *testing.T) {
},
expectedRequests: []reconcile.Request{},
},
{
name: "a matrix generator with a cluster generator should produce a request",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Matrix: &argov1alpha1.MatrixGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
Clusters: &argov1alpha1.ClusterGenerator{},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{{
NamespacedName: types.NamespacedName{Namespace: "argocd", Name: "my-app-set"},
}},
},
{
name: "a matrix generator with non cluster generator should not match",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Matrix: &argov1alpha1.MatrixGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
List: &argov1alpha1.ListGenerator{},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{},
},
{
name: "a matrix generator with a nested matrix generator containing a cluster generator should produce a request",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Matrix: &argov1alpha1.MatrixGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
Matrix: &apiextensionsv1.JSON{
Raw: []byte(
`{
"generators": [
{
"clusters": {
"selector": {
"matchLabels": {
"argocd.argoproj.io/secret-type": "cluster"
}
}
}
}
]
}`,
),
},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{{
NamespacedName: types.NamespacedName{Namespace: "argocd", Name: "my-app-set"},
}},
},
{
name: "a matrix generator with a nested matrix generator containing non cluster generator should not match",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Matrix: &argov1alpha1.MatrixGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
Matrix: &apiextensionsv1.JSON{
Raw: []byte(
`{
"generators": [
{
"list": {
"elements": [
"a",
"b"
]
}
}
]
}`,
),
},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{},
},
{
name: "a merge generator with a cluster generator should produce a request",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Merge: &argov1alpha1.MergeGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
Clusters: &argov1alpha1.ClusterGenerator{},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{{
NamespacedName: types.NamespacedName{Namespace: "argocd", Name: "my-app-set"},
}},
},
{
name: "a matrix generator with non cluster generator should not match",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Merge: &argov1alpha1.MergeGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
List: &argov1alpha1.ListGenerator{},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{},
},
{
name: "a merge generator with a nested merge generator containing a cluster generator should produce a request",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Merge: &argov1alpha1.MergeGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
Merge: &apiextensionsv1.JSON{
Raw: []byte(
`{
"generators": [
{
"clusters": {
"selector": {
"matchLabels": {
"argocd.argoproj.io/secret-type": "cluster"
}
}
}
}
]
}`,
),
},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{{
NamespacedName: types.NamespacedName{Namespace: "argocd", Name: "my-app-set"},
}},
},
{
name: "a merge generator with a nested merge generator containing non cluster generator should not match",
items: []argov1alpha1.ApplicationSet{
{
ObjectMeta: v1.ObjectMeta{
Name: "my-app-set",
Namespace: "argocd",
},
Spec: argov1alpha1.ApplicationSetSpec{
Generators: []argov1alpha1.ApplicationSetGenerator{
{
Merge: &argov1alpha1.MergeGenerator{
Generators: []argov1alpha1.ApplicationSetNestedGenerator{
{
Merge: &apiextensionsv1.JSON{
Raw: []byte(
`{
"generators": [
{
"list": {
"elements": [
"a",
"b"
]
}
}
]
}`,
),
},
},
},
},
},
},
},
},
},
secret: corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Namespace: "argocd",
Name: "my-secret",
Labels: map[string]string{
generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster,
},
},
},
expectedRequests: []reconcile.Request{},
},
}
for _, test := range tests {

View File

@@ -1,11 +1,12 @@
package generators
import (
"fmt"
"reflect"
"github.com/argoproj/argo-cd/v2/applicationset/utils"
"github.com/jeremywohl/flatten"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
@@ -25,7 +26,10 @@ type TransformResult struct {
// Transform a spec generator to list of paramSets and a template
func Transform(requestedGenerator argoprojiov1alpha1.ApplicationSetGenerator, allGenerators map[string]Generator, baseTemplate argoprojiov1alpha1.ApplicationSetTemplate, appSet *argoprojiov1alpha1.ApplicationSet, genParams map[string]interface{}) ([]TransformResult, error) {
selector, err := metav1.LabelSelectorAsSelector(requestedGenerator.Selector)
// This is a custom version of the `LabelSelectorAsSelector` that is in k8s.io/apimachinery. This has been copied
// verbatim from that package, with the difference that we do not have any restrictions on label values. This is done
// so that, among other things, we can match on cluster urls.
selector, err := utils.LabelSelectorAsSelector(requestedGenerator.Selector)
if err != nil {
return nil, err
}
@@ -70,8 +74,17 @@ func Transform(requestedGenerator argoprojiov1alpha1.ApplicationSetGenerator, al
}
var filterParams []map[string]interface{}
for _, param := range params {
flatParam, err := flattenParameters(param)
if err != nil {
log.WithError(err).WithField("generator", g).
Error("error flattening params")
if firstError == nil {
firstError = err
}
continue
}
if requestedGenerator.Selector != nil && !selector.Matches(labels.Set(keepOnlyStringValues(param))) {
if requestedGenerator.Selector != nil && !selector.Matches(labels.Set(flatParam)) {
continue
}
filterParams = append(filterParams, param)
@@ -86,18 +99,6 @@ func Transform(requestedGenerator argoprojiov1alpha1.ApplicationSetGenerator, al
return res, firstError
}
func keepOnlyStringValues(in map[string]interface{}) map[string]string {
var out map[string]string = map[string]string{}
for key, value := range in {
if _, ok := value.(string); ok {
out[key] = value.(string)
}
}
return out
}
func GetRelevantGenerators(requestedGenerator *argoprojiov1alpha1.ApplicationSetGenerator, generators map[string]Generator) []Generator {
var res []Generator
@@ -120,6 +121,20 @@ func GetRelevantGenerators(requestedGenerator *argoprojiov1alpha1.ApplicationSet
return res
}
func flattenParameters(in map[string]interface{}) (map[string]string, error) {
flat, err := flatten.Flatten(in, "", flatten.DotStyle)
if err != nil {
return nil, err
}
out := make(map[string]string, len(flat))
for k, v := range flat {
out[k] = fmt.Sprintf("%v", v)
}
return out, nil
}
func mergeGeneratorTemplate(g Generator, requestedGenerator *argoprojiov1alpha1.ApplicationSetGenerator, applicationSetTemplate argoprojiov1alpha1.ApplicationSetTemplate) (argoprojiov1alpha1.ApplicationSetTemplate, error) {
// Make a copy of the value from `GetTemplate()` before merge, rather than copying directly into
// the provided parameter (which will touch the original resource object returned by client-go)

View File

@@ -94,8 +94,160 @@ func TestMatchValues(t *testing.T) {
}
}
func emptyTemplate() argoprojiov1alpha1.ApplicationSetTemplate {
return argoprojiov1alpha1.ApplicationSetTemplate{
func TestMatchValuesGoTemplate(t *testing.T) {
testCases := []struct {
name string
elements []apiextensionsv1.JSON
selector *metav1.LabelSelector
expected []map[string]interface{}
}{
{
name: "no filter",
elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}},
selector: &metav1.LabelSelector{},
expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}},
},
{
name: "nil",
elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url"}`)}},
selector: nil,
expected: []map[string]interface{}{{"cluster": "cluster", "url": "url"}},
},
{
name: "values.foo should be foo but is ignore element",
elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url","values":{"foo":"bar"}}`)}},
selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"values.foo": "foo",
},
},
expected: []map[string]interface{}{},
},
{
name: "values.foo should be bar",
elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url","values":{"foo":"bar"}}`)}},
selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"values.foo": "bar",
},
},
expected: []map[string]interface{}{{"cluster": "cluster", "url": "url", "values": map[string]interface{}{"foo": "bar"}}},
},
{
name: "values.0 should be bar",
elements: []apiextensionsv1.JSON{{Raw: []byte(`{"cluster": "cluster","url": "url","values":["bar"]}`)}},
selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"values.0": "bar",
},
},
expected: []map[string]interface{}{{"cluster": "cluster", "url": "url", "values": []interface{}{"bar"}}},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
var listGenerator = NewListGenerator()
var data = map[string]Generator{
"List": listGenerator,
}
applicationSetInfo := argov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
},
Spec: argov1alpha1.ApplicationSetSpec{
GoTemplate: true,
},
}
results, err := Transform(argov1alpha1.ApplicationSetGenerator{
Selector: testCase.selector,
List: &argov1alpha1.ListGenerator{
Elements: testCase.elements,
Template: emptyTemplate(),
}},
data,
emptyTemplate(),
&applicationSetInfo, nil)
assert.NoError(t, err)
assert.ElementsMatch(t, testCase.expected, results[0].Params)
})
}
}
func TestTransForm(t *testing.T) {
testCases := []struct {
name string
selector *metav1.LabelSelector
expected []map[string]interface{}
}{
{
name: "server filter",
selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"server": "https://production-01.example.com"},
},
expected: []map[string]interface{}{{
"metadata.annotations.foo.argoproj.io": "production",
"metadata.labels.argocd.argoproj.io/secret-type": "cluster",
"metadata.labels.environment": "production",
"metadata.labels.org": "bar",
"name": "production_01/west",
"nameNormalized": "production-01-west",
"server": "https://production-01.example.com",
}},
},
{
name: "server filter with long url",
selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"server": "https://some-really-long-url-that-will-exceed-63-characters.com"},
},
expected: []map[string]interface{}{{
"metadata.annotations.foo.argoproj.io": "production",
"metadata.labels.argocd.argoproj.io/secret-type": "cluster",
"metadata.labels.environment": "production",
"metadata.labels.org": "bar",
"name": "some-really-long-server-url",
"nameNormalized": "some-really-long-server-url",
"server": "https://some-really-long-url-that-will-exceed-63-characters.com",
}},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
testGenerators := map[string]Generator{
"Clusters": getMockClusterGenerator(),
}
applicationSetInfo := argov1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "set",
},
Spec: argov1alpha1.ApplicationSetSpec{},
}
results, err := Transform(
argov1alpha1.ApplicationSetGenerator{
Selector: testCase.selector,
Clusters: &argov1alpha1.ClusterGenerator{
Selector: metav1.LabelSelector{},
Template: argov1alpha1.ApplicationSetTemplate{},
Values: nil,
}},
testGenerators,
emptyTemplate(),
&applicationSetInfo, nil)
assert.NoError(t, err)
assert.ElementsMatch(t, testCase.expected, results[0].Params)
})
}
}
func emptyTemplate() argov1alpha1.ApplicationSetTemplate {
return argov1alpha1.ApplicationSetTemplate{
Spec: argov1alpha1.ApplicationSpec{
Project: "project",
},
@@ -152,8 +304,35 @@ func getMockClusterGenerator() Generator {
},
Type: corev1.SecretType("Opaque"),
},
&corev1.Secret{
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "some-really-long-server-url",
Namespace: "namespace",
Labels: map[string]string{
"argocd.argoproj.io/secret-type": "cluster",
"environment": "production",
"org": "bar",
},
Annotations: map[string]string{
"foo.argoproj.io": "production",
},
},
Data: map[string][]byte{
"config": []byte("{}"),
"name": []byte("some-really-long-server-url"),
"server": []byte("https://some-really-long-url-that-will-exceed-63-characters.com"),
},
Type: corev1.SecretType("Opaque"),
},
}
runtimeClusters := []runtime.Object{}
for _, clientCluster := range clusters {
runtimeClusters = append(runtimeClusters, clientCluster)
}
appClientset := kubefake.NewSimpleClientset(runtimeClusters...)
fakeClient := fake.NewClientBuilder().WithObjects(clusters...).Build()

View File

@@ -0,0 +1,261 @@
package utils
import (
"fmt"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/klog/v2"
"sort"
"strconv"
"strings"
)
var (
unaryOperators = []string{
string(selection.Exists), string(selection.DoesNotExist),
}
binaryOperators = []string{
string(selection.In), string(selection.NotIn),
string(selection.Equals), string(selection.DoubleEquals), string(selection.NotEquals),
string(selection.GreaterThan), string(selection.LessThan),
}
validRequirementOperators = append(binaryOperators, unaryOperators...)
)
// Selector represents a label selector.
type Selector interface {
// Matches returns true if this selector matches the given set of labels.
Matches(labels.Labels) bool
// Add adds requirements to the Selector
Add(r ...Requirement) Selector
}
type internalSelector []Requirement
// ByKey sorts requirements by key to obtain deterministic parser
type ByKey []Requirement
func (a ByKey) Len() int { return len(a) }
func (a ByKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByKey) Less(i, j int) bool { return a[i].key < a[j].key }
// Matches for a internalSelector returns true if all
// its Requirements match the input Labels. If any
// Requirement does not match, false is returned.
func (s internalSelector) Matches(l labels.Labels) bool {
for ix := range s {
if matches := s[ix].Matches(l); !matches {
return false
}
}
return true
}
// Add adds requirements to the selector. It copies the current selector returning a new one
func (s internalSelector) Add(reqs ...Requirement) Selector {
ret := make(internalSelector, 0, len(s)+len(reqs))
ret = append(ret, s...)
ret = append(ret, reqs...)
sort.Sort(ByKey(ret))
return ret
}
type nothingSelector struct{}
func (n nothingSelector) Matches(l labels.Labels) bool {
return false
}
func (n nothingSelector) Add(r ...Requirement) Selector {
return n
}
// Nothing returns a selector that matches no labels
func nothing() Selector {
return nothingSelector{}
}
// Everything returns a selector that matches all labels.
func everything() Selector {
return internalSelector{}
}
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
// labels.Selector
// Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go
func LabelSelectorAsSelector(ps *v1.LabelSelector) (Selector, error) {
if ps == nil {
return nothing(), nil
}
if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
return everything(), nil
}
requirements := make([]Requirement, 0, len(ps.MatchLabels)+len(ps.MatchExpressions))
for k, v := range ps.MatchLabels {
r, err := newRequirement(k, selection.Equals, []string{v})
if err != nil {
return nil, err
}
requirements = append(requirements, *r)
}
for _, expr := range ps.MatchExpressions {
var op selection.Operator
switch expr.Operator {
case v1.LabelSelectorOpIn:
op = selection.In
case v1.LabelSelectorOpNotIn:
op = selection.NotIn
case v1.LabelSelectorOpExists:
op = selection.Exists
case v1.LabelSelectorOpDoesNotExist:
op = selection.DoesNotExist
default:
return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
}
r, err := newRequirement(expr.Key, op, append([]string(nil), expr.Values...))
if err != nil {
return nil, err
}
requirements = append(requirements, *r)
}
selector := newSelector()
selector = selector.Add(requirements...)
return selector, nil
}
// NewSelector returns a nil selector
func newSelector() Selector {
return internalSelector(nil)
}
func validateLabelKey(k string, path *field.Path) *field.Error {
if errs := validation.IsQualifiedName(k); len(errs) != 0 {
return field.Invalid(path, k, strings.Join(errs, "; "))
}
return nil
}
// NewRequirement is the constructor for a Requirement.
// If any of these rules is violated, an error is returned:
// (1) The operator can only be In, NotIn, Equals, DoubleEquals, Gt, Lt, NotEquals, Exists, or DoesNotExist.
// (2) If the operator is In or NotIn, the values set must be non-empty.
// (3) If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value.
// (4) If the operator is Exists or DoesNotExist, the value set must be empty.
// (5) If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer.
// (6) The key is invalid due to its length, or sequence
//
// of characters. See validateLabelKey for more details.
//
// The empty string is a valid value in the input values set.
// Returned error, if not nil, is guaranteed to be an aggregated field.ErrorList
func newRequirement(key string, op selection.Operator, vals []string, opts ...field.PathOption) (*Requirement, error) {
var allErrs field.ErrorList
path := field.ToPath(opts...)
if err := validateLabelKey(key, path.Child("key")); err != nil {
allErrs = append(allErrs, err)
}
valuePath := path.Child("values")
switch op {
case selection.In, selection.NotIn:
if len(vals) == 0 {
allErrs = append(allErrs, field.Invalid(valuePath, vals, "for 'in', 'notin' operators, values set can't be empty"))
}
case selection.Equals, selection.DoubleEquals, selection.NotEquals:
if len(vals) != 1 {
allErrs = append(allErrs, field.Invalid(valuePath, vals, "exact-match compatibility requires one single value"))
}
case selection.Exists, selection.DoesNotExist:
if len(vals) != 0 {
allErrs = append(allErrs, field.Invalid(valuePath, vals, "values set must be empty for exists and does not exist"))
}
case selection.GreaterThan, selection.LessThan:
if len(vals) != 1 {
allErrs = append(allErrs, field.Invalid(valuePath, vals, "for 'Gt', 'Lt' operators, exactly one value is required"))
}
for i := range vals {
if _, err := strconv.ParseInt(vals[i], 10, 64); err != nil {
allErrs = append(allErrs, field.Invalid(valuePath.Index(i), vals[i], "for 'Gt', 'Lt' operators, the value must be an integer"))
}
}
default:
allErrs = append(allErrs, field.NotSupported(path.Child("operator"), op, validRequirementOperators))
}
return &Requirement{key: key, operator: op, strValues: vals}, allErrs.ToAggregate()
}
// Requirement contains values, a key, and an operator that relates the key and values.
// The zero value of Requirement is invalid.
// Requirement implements both set based match and exact match
// Requirement should be initialized via NewRequirement constructor for creating a valid Requirement.
// +k8s:deepcopy-gen=true
type Requirement struct {
key string
operator selection.Operator
// In the majority of cases we have at most one value here.
// It is generally faster to operate on a single-element slice
// than on a single-element map, so we have a slice here.
strValues []string
}
func (r *Requirement) hasValue(value string) bool {
for i := range r.strValues {
if r.strValues[i] == value {
return true
}
}
return false
}
func (r *Requirement) Matches(ls labels.Labels) bool {
switch r.operator {
case selection.In, selection.Equals, selection.DoubleEquals:
if !ls.Has(r.key) {
return false
}
return r.hasValue(ls.Get(r.key))
case selection.NotIn, selection.NotEquals:
if !ls.Has(r.key) {
return true
}
return !r.hasValue(ls.Get(r.key))
case selection.Exists:
return ls.Has(r.key)
case selection.DoesNotExist:
return !ls.Has(r.key)
case selection.GreaterThan, selection.LessThan:
if !ls.Has(r.key) {
return false
}
lsValue, err := strconv.ParseInt(ls.Get(r.key), 10, 64)
if err != nil {
klog.V(10).Infof("ParseInt failed for value %+v in label %+v, %+v", ls.Get(r.key), ls, err)
return false
}
// There should be only one strValue in r.strValues, and can be converted to an integer.
if len(r.strValues) != 1 {
klog.V(10).Infof("Invalid values count %+v of requirement %#v, for 'Gt', 'Lt' operators, exactly one value is required", len(r.strValues), r)
return false
}
var rValue int64
for i := range r.strValues {
rValue, err = strconv.ParseInt(r.strValues[i], 10, 64)
if err != nil {
klog.V(10).Infof("ParseInt failed for value %+v in requirement %#v, for 'Gt', 'Lt' operators, the value must be an integer", r.strValues[i], r)
return false
}
}
return (r.operator == selection.GreaterThan && lsValue > rValue) || (r.operator == selection.LessThan && lsValue < rValue)
default:
return false
}
}

View File

@@ -248,7 +248,10 @@ func (r *Render) Replace(tmpl string, replaceMap map[string]interface{}, useGoTe
return tmpl, nil
}
fstTmpl := fasttemplate.New(tmpl, "{{", "}}")
fstTmpl, err := fasttemplate.NewTemplate(tmpl, "{{", "}}")
if err != nil {
return "", fmt.Errorf("invalid template: %w", err)
}
replacedTmpl := fstTmpl.ExecuteFuncString(func(w io.Writer, tag string) (int, error) {
trimmedTag := strings.TrimSpace(tag)
replacement, ok := replaceMap[trimmedTag].(string)

View File

@@ -464,6 +464,14 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) {
}
}
func Test_Render_Replace_no_panic_on_missing_closing_brace(t *testing.T) {
r := &Render{}
assert.NotPanics(t, func() {
_, err := r.Replace("{{properly.closed}} {{improperly.closed}", nil, false)
assert.Error(t, err)
})
}
func TestRenderTemplateKeys(t *testing.T) {
t.Run("fasttemplate", func(t *testing.T) {
application := &argoappsv1.Application{

View File

@@ -9,13 +9,16 @@ 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() *cobra.Command {
var (
port int
address string
port int
address string
compressionStr string
)
cmd := &cobra.Command{
Use: "dashboard",
@@ -23,7 +26,9 @@ func NewDashboardCommand() *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
ctx := cmd.Context()
errors.CheckError(headless.StartLocalServer(ctx, &argocdclient.ClientOptions{Core: true}, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address))
compression, err := cache.CompressionTypeFromString(compressionStr)
errors.CheckError(err)
errors.CheckError(headless.StartLocalServer(ctx, &argocdclient.ClientOptions{Core: true}, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address, compression))
println(fmt.Sprintf("Argo CD UI is available at http://%s:%d", address, port))
<-ctx.Done()
},
@@ -31,5 +36,6 @@ func NewDashboardCommand() *cobra.Command {
initialize.InitCommand(cmd)
cmd.Flags().IntVar(&port, "port", common.DefaultPortAPIServer, "Listen on given port")
cmd.Flags().StringVar(&address, "address", common.DefaultAddressAPIServer, "Listen on given address")
cmd.Flags().StringVar(&compressionStr, "redis-compress", env.StringFromEnv("REDIS_COMPRESSION", string(cache.RedisCompressionNone)), "Enable this if the application controller is configured with redis compression enabled. (possible values: none, gzip)")
return cmd
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"os"
"strings"
"github.com/ghodss/yaml"
log "github.com/sirupsen/logrus"
@@ -373,6 +374,9 @@ func resolveRBACResourceName(name string) string {
// isValidRBACAction checks whether a given action is a valid RBAC action
func isValidRBACAction(action string) bool {
if strings.HasPrefix(action, rbacpolicy.ActionAction+"/") {
return true
}
_, ok := validRBACActions[action]
return ok
}

View File

@@ -27,6 +27,11 @@ func Test_isValidRBACAction(t *testing.T) {
})
}
func Test_isValidRBACAction_ActionAction(t *testing.T) {
ok := isValidRBACAction("action/apps/Deployment/restart")
assert.True(t, ok)
}
func Test_isValidRBACResource(t *testing.T) {
for k := range validRBACResources {
t.Run(k, func(t *testing.T) {

View File

@@ -1020,7 +1020,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, resources
unstructureds = append(unstructureds, obj)
}
groupedObjs := groupObjsByKey(unstructureds, liveObjs, app.Spec.Destination.Namespace)
items = groupObjsForDiff(resources, groupedObjs, items, argoSettings, app.Name)
items = groupObjsForDiff(resources, groupedObjs, items, argoSettings, app.InstanceName(argoSettings.ControllerNamespace))
} else if diffOptions.serversideRes != nil {
var unstructureds []*unstructured.Unstructured
for _, mfst := range diffOptions.serversideRes.Manifests {
@@ -1029,7 +1029,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, resources
unstructureds = append(unstructureds, obj)
}
groupedObjs := groupObjsByKey(unstructureds, liveObjs, app.Spec.Destination.Namespace)
items = groupObjsForDiff(resources, groupedObjs, items, argoSettings, app.Name)
items = groupObjsForDiff(resources, groupedObjs, items, argoSettings, app.InstanceName(argoSettings.ControllerNamespace))
} else {
for i := range resources.Items {
res := resources.Items[i]

View File

@@ -38,11 +38,12 @@ import (
)
type forwardCacheClient struct {
namespace string
context string
init sync.Once
client cache.CacheClient
err error
namespace string
context string
init sync.Once
client cache.CacheClient
compression cache.RedisCompressionType
err error
}
func (c *forwardCacheClient) doLazy(action func(client cache.CacheClient) error) error {
@@ -58,7 +59,7 @@ func (c *forwardCacheClient) doLazy(action func(client cache.CacheClient) error)
}
redisClient := redis.NewClient(&redis.Options{Addr: fmt.Sprintf("localhost:%d", redisPort)})
c.client = cache.NewRedisCache(redisClient, time.Hour, cache.RedisCompressionNone)
c.client = cache.NewRedisCache(redisClient, time.Hour, c.compression)
})
if c.err != nil {
return c.err
@@ -139,7 +140,7 @@ func testAPI(ctx context.Context, clientOpts *apiclient.ClientOptions) error {
// StartLocalServer allows executing command in a headless mode: on the fly starts Argo CD API server and
// changes provided client options to use started API server port
func StartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string) error {
func StartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string, compression cache.RedisCompressionType) error {
flags := pflag.NewFlagSet("tmp", pflag.ContinueOnError)
clientConfig := cli.AddKubectlFlagsToSet(flags)
startInProcessAPI := clientOpts.Core
@@ -200,7 +201,7 @@ func StartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions,
if err != nil {
return err
}
appstateCache := appstatecache.NewCache(cache.NewCache(&forwardCacheClient{namespace: namespace, context: ctxStr}), time.Hour)
appstateCache := appstatecache.NewCache(cache.NewCache(&forwardCacheClient{namespace: namespace, context: ctxStr, compression: compression}), time.Hour)
srv := server.NewServer(ctx, server.ArgoCDServerOpts{
EnableGZip: false,
Namespace: namespace,
@@ -242,7 +243,7 @@ func NewClientOrDie(opts *apiclient.ClientOptions, c *cobra.Command) apiclient.C
ctx := c.Context()
ctxStr := initialize.RetrieveContextIfChanged(c.Flag("context"))
err := StartLocalServer(ctx, opts, ctxStr, nil, nil)
err := StartLocalServer(ctx, opts, ctxStr, nil, nil, cache.RedisCompressionNone)
if err != nil {
log.Fatal(err)
}

View File

@@ -3,6 +3,7 @@ package commands
import (
"fmt"
"os"
"strconv"
"text/tabwriter"
log "github.com/sirupsen/logrus"
@@ -233,15 +234,12 @@ func printRepoTable(repos appsv1.Repositories) {
_, _ = fmt.Fprintf(w, "TYPE\tNAME\tREPO\tINSECURE\tOCI\tLFS\tCREDS\tSTATUS\tMESSAGE\tPROJECT\n")
for _, r := range repos {
var hasCreds string
if !r.HasCredentials() {
hasCreds = "false"
if r.InheritedCreds {
hasCreds = "inherited"
} else {
if r.InheritedCreds {
hasCreds = "inherited"
} else {
hasCreds = "true"
}
hasCreds = strconv.FormatBool(r.HasCredentials())
}
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%v\t%v\t%s\t%s\t%s\t%s\n", r.Type, r.Name, r.Repo, r.IsInsecure(), r.EnableOCI, r.EnableLFS, hasCreds, r.ConnectionState.Status, r.ConnectionState.Message, r.Project)
}
_ = w.Flush()

View File

@@ -483,10 +483,11 @@ func (c *liveStateCache) getSyncedCluster(server string) (clustercache.ClusterCa
func (c *liveStateCache) invalidate(cacheSettings cacheSettings) {
log.Info("invalidating live state cache")
c.lock.Lock()
defer c.lock.Unlock()
c.cacheSettings = cacheSettings
for _, clust := range c.clusters {
clusters := c.clusters
c.lock.Unlock()
for _, clust := range clusters {
clust.Invalidate(clustercache.SetSettings(cacheSettings.clusterSettings))
}
log.Info("live state cache invalidated")
@@ -696,12 +697,14 @@ func (c *liveStateCache) handleModEvent(oldCluster *appv1.Cluster, newCluster *a
}
func (c *liveStateCache) handleDeleteEvent(clusterServer string) {
c.lock.Lock()
defer c.lock.Unlock()
c.lock.RLock()
cluster, ok := c.clusters[clusterServer]
c.lock.RUnlock()
if ok {
cluster.Invalidate()
c.lock.Lock()
delete(c.clusters, clusterServer)
c.lock.Unlock()
}
}

View File

@@ -1,10 +1,13 @@
package cache
import (
"context"
"errors"
"net"
"net/url"
"sync"
"testing"
"time"
apierr "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -14,8 +17,10 @@ import (
"github.com/argoproj/gitops-engine/pkg/cache"
"github.com/argoproj/gitops-engine/pkg/cache/mocks"
"github.com/stretchr/testify/mock"
"k8s.io/client-go/kubernetes/fake"
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
argosettings "github.com/argoproj/argo-cd/v2/util/settings"
)
type netError string
@@ -106,6 +111,98 @@ func TestHandleAddEvent_ClusterExcluded(t *testing.T) {
assert.Len(t, clustersCache.clusters, 0)
}
func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) {
testCluster := &appv1.Cluster{
Server: "https://mycluster",
Config: appv1.ClusterConfig{Username: "bar"},
}
fakeClient := fake.NewSimpleClientset()
settingsMgr := argosettings.NewSettingsManager(context.TODO(), fakeClient, "argocd")
externalLockRef := sync.RWMutex{}
gitopsEngineClusterCache := &mocks.ClusterCache{}
clustersCache := liveStateCache{
clusters: map[string]cache.ClusterCache{
testCluster.Server: gitopsEngineClusterCache,
},
clusterFilter: func(cluster *appv1.Cluster) bool {
return true
},
settingsMgr: settingsMgr,
// Set the lock here so we can reference it later
// nolint We need to overwrite here to have access to the lock
lock: externalLockRef,
}
channel := make(chan string)
// Mocked lock held by the gitops-engine cluster cache
mockMutex := sync.RWMutex{}
// Locks to force trigger condition during test
// Condition order:
// EnsuredSynced -> Locks gitops-engine
// handleDeleteEvent -> Locks liveStateCache
// EnsureSynced via sync, newResource, populateResourceInfoHandler -> attempts to Lock liveStateCache
// handleDeleteEvent via cluster.Invalidate -> attempts to Lock gitops-engine
handleDeleteWasCalled := sync.Mutex{}
engineHoldsLock := sync.Mutex{}
handleDeleteWasCalled.Lock()
engineHoldsLock.Lock()
gitopsEngineClusterCache.On("EnsureSynced").Run(func(args mock.Arguments) {
// Held by EnsureSync calling into sync and watchEvents
mockMutex.Lock()
defer mockMutex.Unlock()
// Continue Execution of timer func
engineHoldsLock.Unlock()
// Wait for handleDeleteEvent to be called triggering the lock
// on the liveStateCache
handleDeleteWasCalled.Lock()
t.Logf("handleDelete was called, EnsureSynced continuing...")
handleDeleteWasCalled.Unlock()
// Try and obtain the lock on the liveStateCache
alreadyFailed := !externalLockRef.TryLock()
if alreadyFailed {
channel <- "DEADLOCKED -- EnsureSynced could not obtain lock on liveStateCache"
return
}
externalLockRef.Lock()
t.Logf("EnsureSynce was able to lock liveStateCache")
externalLockRef.Unlock()
}).Return(nil).Once()
gitopsEngineClusterCache.On("Invalidate").Run(func(args mock.Arguments) {
// If deadlock is fixed should be able to acquire lock here
alreadyFailed := !mockMutex.TryLock()
if alreadyFailed {
channel <- "DEADLOCKED -- Invalidate could not obtain lock on gitops-engine"
return
}
mockMutex.Lock()
t.Logf("Invalidate was able to lock gitops-engine cache")
mockMutex.Unlock()
}).Return()
go func() {
// Start the gitops-engine lock holds
go func() {
err := gitopsEngineClusterCache.EnsureSynced()
if err != nil {
assert.Fail(t, err.Error())
}
}()
// Wait for EnsureSynced to grab the lock for gitops-engine
engineHoldsLock.Lock()
t.Log("EnsureSynced has obtained lock on gitops-engine")
engineHoldsLock.Unlock()
// Run in background
go clustersCache.handleDeleteEvent(testCluster.Server)
// Allow execution to continue on clusters cache call to trigger lock
handleDeleteWasCalled.Unlock()
channel <- "PASSED"
}()
select {
case str := <-channel:
assert.Equal(t, "PASSED", str, str)
case <-time.After(5 * time.Second):
assert.Fail(t, "Ended up in deadlock")
}
}
func TestIsRetryableError(t *testing.T) {
var (
tlsHandshakeTimeoutErr net.Error = netError("net/http: TLS handshake timeout")

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
docs/assets/extra_info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

View File

@@ -9,16 +9,6 @@ setTimeout(function() {
caret.innerHTML = "<i class='fa fa-caret-down dropdown-caret'></i>"
caret.classList.add('dropdown-caret')
div.querySelector('.rst-current-version').appendChild(caret);
div.querySelector('.rst-current-version').addEventListener('click', function() {
const classes = container.className.split(' ');
const index = classes.indexOf('shift-up');
if (index === -1) {
classes.push('shift-up');
} else {
classes.splice(index, 1);
}
container.className = classes.join(' ');
});
}
var CSSLink = document.createElement('link');

View File

@@ -9,12 +9,7 @@ To test:
```bash
make serve-docs
```
Check for broken external links:
```bash
make lint-docs
```
Once running, you can view your locally built documentation at [http://0.0.0.0:8000/](http://0.0.0.0:8000/).
## Deploying

View File

@@ -6,7 +6,10 @@ metadata:
namespace: argocd
# Add this finalizer ONLY if you want these to cascade delete.
finalizers:
# The default behaviour is foreground cascading deletion
- resources-finalizer.argocd.argoproj.io
# Alternatively, you can use background cascading deletion
# - resources-finalizer.argocd.argoproj.io/background
# Add labels to your application object.
labels:
name: guestbook
@@ -131,7 +134,12 @@ spec:
# name: in-cluster
# The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace
namespace: guestbook
# Extra information to show in the Argo CD Application details tab
info:
- name: 'Example:'
value: 'https://example.com'
# Sync policy
syncPolicy:
automated: # automated sync by default retries failed attempts 5 times with following delays between attempts ( 5s, 10s, 20s, 40s, 80s ); retry controlled using `retry` field.
@@ -164,6 +172,9 @@ spec:
kind: "*"
managedFieldsManagers:
- kube-controller-manager
# Name and namespace are optional. If specified, they must match exactly, these are not glob patterns.
name: my-deployment
namespace: my-namespace
# RevisionHistoryLimit limits the number of items kept in the application's revision history, which is used for
# informational purposes as well as for rollbacks to previous versions. This should only be changed in exceptional

View File

@@ -6,7 +6,7 @@ Generators are primarily based on the data source that they use to generate the
As of this writing there are eight generators:
- [List generator](Generators-List.md): The List generator allows you to target Argo CD Applications to clusters based on a fixed list of cluster name/URL values.
- [List generator](Generators-List.md): The List generator allows you to target Argo CD Applications to clusters based on a fixed list of any chosen key/value element pairs.
- [Cluster generator](Generators-Cluster.md): The Cluster generator allows you to target Argo CD Applications to clusters, based on the list of clusters defined within (and managed by) Argo CD (which includes automatically responding to cluster addition/removal events from Argo CD).
- [Git generator](Generators-Git.md): The Git generator allows you to create Applications based on files within a Git repository, or based on the directory structure of a Git repository.
- [Matrix generator](Generators-Matrix.md): The Matrix generator may be used to combine the generated parameters of two separate generators.

View File

@@ -87,6 +87,10 @@ By activating Go Templating, `{{ .path }}` becomes an object. Therefore, some ch
generators' templating:
- `{{ path }}` becomes `{{ .path.path }}`
- `{{ path.basename }}` becomes `{{ .path.basename }}`
- `{{ path.basenameNormalized }}` becomes `{{ .path.basenameNormalized }}`
- `{{ path.filename }}` becomes `{{ .path.filename }}`
- `{{ path.filenameNormalized }}` becomes `{{ .path.filenameNormalized }}`
- `{{ path[n] }}` becomes `{{ index .path.segments n }}`
Here is an example:

View File

@@ -7,7 +7,7 @@ metadata:
name: argocd-ssh-known-hosts-cm
data:
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf

View File

@@ -389,9 +389,25 @@ data:
### SSH known host public keys
If you are connecting repositories via SSH, Argo CD will need to know the SSH known hosts public key of the repository servers. You can manage the SSH known hosts data in the ConfigMap named `argocd-ssh-known-hosts-cm`. This ConfigMap contains a single key/value pair, with `ssh_known_hosts` as the key and the actual public keys of the SSH servers as data. As opposed to TLS configuration, the public key(s) of each single repository server Argo CD will connect via SSH must be configured, otherwise the connections to the repository will fail. There is no fallback. The data can be copied from any existing `ssh_known_hosts` file, or from the output of the `ssh-keyscan` utility. The basic format is `<servername> <keydata>`, one entry per line.
If you are configuring repositories to use SSH, Argo CD will need to know their SSH public keys. In order for Argo CD to connect via SSH the public key(s) for each repository server must be pre-configured in Argo CD (unlike TLS configuration), otherwise the connections to the repository will fail.
An example ConfigMap object:
You can manage the SSH known hosts data in the `argocd-ssh-known-hosts-cm` ConfigMap. This ConfigMap contains a single entry, `ssh_known_hosts`, with the public keys of the SSH servers as its value. The value can be filled in from any existing `ssh_known_hosts` file, or from the output of the `ssh-keyscan` utility (which is part of OpenSSH's client package). The basic format is `<server_name> <keytype> <base64-encoded_key>`, one entry per line.
Here is an example of running `ssh-keyscan`:
```bash
$ for host in bitbucket.org github.com gitlab.com ssh.dev.azure.com vs-ssh.visualstudio.com ; do ssh-keyscan $host 2> /dev/null ; done
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
```
Here is an example `ConfigMap` object using the output from `ssh-keyscan` above:
```yaml
apiVersion: v1
@@ -404,7 +420,7 @@ metadata:
app.kubernetes.io/part-of: argocd
data:
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf

View File

@@ -15,13 +15,13 @@ export VERSION=v1.0.1
Export to a backup:
```bash
docker run -v ~/.kube:/home/argocd/.kube --rm argoproj/argocd:$VERSION argocd admin export > backup.yaml
docker run -v ~/.kube:/home/argocd/.kube --rm quay.io/argoproj/argocd:$VERSION argocd admin export > backup.yaml
```
Import from a backup:
```bash
docker run -i -v ~/.kube:/home/argocd/.kube --rm argoproj/argocd:$VERSION argocd admin import - < backup.yaml
docker run -i -v ~/.kube:/home/argocd/.kube --rm quay.io/argoproj/argocd:$VERSION argocd admin import - < backup.yaml
```
!!! note

View File

@@ -538,15 +538,15 @@ spec:
- secretName: secret-yourdomain-com
rules:
- host: argocd.yourdomain.com
http:
paths:
- pathType: ImplementationSpecific
path: "/*" # "*" is needed. Without this, the UI Javascript and CSS will not load properly
backend:
service:
name: argocd-server
port:
number: 80
http:
paths:
- pathType: ImplementationSpecific
path: "/*" # "*" is needed. Without this, the UI Javascript and CSS will not load properly
backend:
service:
name: argocd-server
port:
number: 80
```
If you use the version `1.21.3-gke.1600` or later, you should use the following Ingress resource:
@@ -563,15 +563,15 @@ spec:
- secretName: secret-yourdomain-com
rules:
- host: argocd.yourdomain.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: argocd-server
port:
number: 80
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: argocd-server
port:
number: 80
```
As you may know already, it can take some minutes to deploy the load balancer and become ready to accept connections. Once it's ready, get the public IP address for your Load Balancer, go to your DNS server (Google or third party) and point your domain or subdomain (i.e. argocd.yourdomain.com) to that IP address.

View File

@@ -74,7 +74,7 @@ kind: Kustomization
namespace: argocd
resources:
- github.com/argoproj/argo-cd/manifests/ha?ref=v2.6.2
- github.com/argoproj/argo-cd/manifests/ha/base?ref=v2.6.2
```
## Helm

View File

@@ -17,8 +17,9 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/st
* Add Email username and password token to `argocd-notifications-secret` secret
```bash
export EMAIL_USER=<your-username>
export PASSWORD=<your-password>
EMAIL_USER=<your-username>
PASSWORD=<your-password>
kubectl apply -n argocd -f - << EOF
apiVersion: v1
kind: Secret

View File

@@ -64,7 +64,7 @@ See [Web-based Terminal](web_based_terminal.md) for more info.
#### The `applicationsets` resource
[ApplicationSets](applicationset) provide a declarative way to automatically create/update/delete Applications.
[ApplicationSets](applicationset/index.md) provide a declarative way to automatically create/update/delete Applications.
Granting `applicationsets, create` effectively grants the ability to create Applications. While it doesn't allow the
user to create Applications directly, they can create Applications via an ApplicationSet.

View File

@@ -195,3 +195,8 @@ response and will therefore fail to create/update the Application.
To solve the issue, upgrade the CLI to at least 2.5.16, or 2.6.7.
CLIs older than 2.5.0-rc1 are unaffected.
## Golang upgrade in 2.5.20
In 2.5.20, we upgrade the Golang version used to build Argo CD from 1.18 to 1.19. If you use Argo CD as a library, you
may need to upgrade your Go version.

View File

@@ -19,7 +19,7 @@ metadata:
spec:
accessTokenSkewMillis: 120000
accessTokenTimeToLive: 1200000
authChainName: LoginService
authChainName: login-service
clientId: argocd
codeLastMileKeyName: lastmile-oidc
codeTokenSkewMilis: 60000

View File

@@ -22,7 +22,7 @@ or
argocd app delete APPNAME
```
# Deletion Using `kubectl`
## Deletion Using `kubectl`
To perform a non-cascade delete, make sure the finalizer is unset and then delete the app:
@@ -38,16 +38,23 @@ kubectl patch app APPNAME -p '{"metadata": {"finalizers": ["resources-finalizer
kubectl delete app APPNAME
```
# About The Deletion Finalizer
## About The Deletion Finalizer
For the technical amongst you, the Argo CD application controller watches for this finalizer:
```yaml
metadata:
finalizers:
# The default behaviour is foreground cascading deletion
- resources-finalizer.argocd.argoproj.io
# Alternatively, you can use background cascading deletion
# - resources-finalizer.argocd.argoproj.io/background
```
Argo CD's app controller watches for this and will then delete both the app and its resources.
The default propagation policy for cascading deletion is [foreground cascading deletion](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion).
ArgoCD performs [background cascading deletion](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#background-deletion) when `resources-finalizer.argocd.argoproj.io/background` is set.
When you invoke `argocd app delete` with `--cascade`, the finalizer is added automatically.
You can set the propagation policy with `--propagation-policy <foreground|background>`.

View File

@@ -25,6 +25,7 @@ argocd admin dashboard [flags]
--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: none, gzip) (default "none")
--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")
--tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
--token string Bearer token for authentication to the API server

View File

@@ -60,8 +60,8 @@ To ignore fields owned by specific managers defined in your live resources:
```yaml
spec:
ignoreDifferences:
- group: *
kind: *
- group: "*"
kind: "*"
managedFieldsManagers:
- kube-controller-manager
```

View File

@@ -0,0 +1,28 @@
# Add extra Application info
You can add additional information to an Application on your ArgoCD dashboard.
If you wish to add clickable links, see [Add external URL](https://argo-cd.readthedocs.io/en/stable/user-guide/external-url/).
This is done by providing the 'info' field a key-value in your Application manifest.
Example:
```yaml
project: argo-demo
source:
repoURL: 'https://demo'
path: argo-demo
destination:
server: https://demo
namespace: argo-demo
info:
- name: Example:
value: >-
https://example.com
```
![External link](../assets/extra_info-1.png)
The additional information will be visible on the ArgoCD Application details page.
![External link](../assets/extra_info.png)
![External link](../assets/extra_info-2.png)

View File

@@ -37,6 +37,29 @@ argocd app set helm-guestbook --values values-production.yaml
location in which case it can be accessed using a relative path relative to the root directory of
the Helm chart.
## Values
Argo CD supports the equivalent of a values file directly in the Application manifest using the `source.helm.values` key.
```
source:
helm:
values: |
ingress:
enabled: true
path: /
hosts:
- mydomain.example.com
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
labels: {}
tls:
- secretName: mydomain-tls
hosts:
- mydomain.example.com
```
## Helm Parameters
Helm has the ability to set parameter values, which override any values in
@@ -94,11 +117,14 @@ Argo CD supports many (most?) Helm hooks by mapping the Helm annotations onto Ar
| `helm.sh/hook: test-success` | Not supported. No equivalent in Argo CD. |
| `helm.sh/hook: test-failure` | Not supported. No equivalent in Argo CD. |
| `helm.sh/hook-delete-policy` | Supported. See also `argocd.argoproj.io/hook-delete-policy`). |
| `helm.sh/hook-delete-timeout` | No supported. Never used in Helm stable |
| `helm.sh/hook-delete-timeout` | Not supported. Never used in Helm stable |
| `helm.sh/hook-weight` | Supported as equivalent to `argocd.argoproj.io/sync-wave`. |
Unsupported hooks are ignored. In Argo CD, hooks are created by using `kubectl apply`, rather than `kubectl create`. This means that if the hook is named and already exists, it will not change unless you have annotated it with `before-hook-creation`.
!!! warning "Helm hooks + ArgoCD hooks"
If you define some Argo CD hooks in addition to the Helm ones, the Helm hooks will be ignored.
!!! warning "'install' vs 'upgrade' vs 'sync'"
Argo CD cannot know if it is running a first-time "install" or an "upgrade" - every operation is a "sync'. This means that, by default, apps that have `pre-install` and `pre-upgrade` will have those hooks run at the same time.

View File

@@ -276,7 +276,7 @@ You can list all configured SSH known host entries using the `argocd cert list`
```bash
$ argocd cert list --cert-type ssh
HOSTNAME TYPE SUBTYPE FINGERPRINT/SUBJECT
bitbucket.org ssh ssh-rsa SHA256:zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A
bitbucket.org ssh ssh-rsa SHA256:46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E
github.com ssh ssh-rsa SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8
gitlab.com ssh ecdsa-sha2-nistp256 SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw
gitlab.com ssh ssh-ed25519 SHA256:eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8

View File

@@ -294,7 +294,7 @@ stringData:
All the examples above talk about Git repositories, but the same principles apply to clusters as well.
With cluster-scoped clusters we can also restrict projects to only allow applications whose destinations belong to the
With project-scoped clusters we can also restrict projects to only allow applications whose destinations belong to the
same project. The default behavior allows for applications to be installed onto clusters which are not a part of the same
project, as the example below demonstrates:

View File

@@ -1,5 +1,5 @@
# This file was automatically generated. DO NOT EDIT
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf

View File

@@ -14,11 +14,11 @@ chmod 0644 $KNOWN_HOSTS_FILE
# - bitbucket.org: https://confluence.atlassian.com/bitbucket/ssh-keys-935365775.html
# - ssh.dev.azure.com, vs-ssh.visualstudio.com: https://docs.microsoft.com/en-us/azure/devops/repos/git/use-ssh-keys-to-authenticate?view=azure-devops
diff - <(ssh-keygen -l -f $KNOWN_HOSTS_FILE | sort -k 3) <<EOF
2048 SHA256:zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A bitbucket.org (RSA)
2048 SHA256:46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E bitbucket.org (RSA)
2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)
256 SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw gitlab.com (ECDSA)
256 SHA256:eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8 gitlab.com (ED25519)
2048 SHA256:ROQFvPThGrW4RuWLoL9tq9I9zJ42fK4XywyRtbOz/EQ gitlab.com (RSA)
2048 SHA256:ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og ssh.dev.azure.com (RSA)
2048 SHA256:ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og vs-ssh.visualstudio.com (RSA)
EOF
EOF

View File

@@ -7,7 +7,7 @@ metadata:
name: argocd-ssh-known-hosts-cm
data:
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
@@ -15,4 +15,4 @@ data:
ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl

View File

@@ -37,7 +37,7 @@ spec:
type: RuntimeDefault
containers:
- name: dex
image: ghcr.io/dexidp/dex:v2.35.3
image: ghcr.io/dexidp/dex:v2.37.0
imagePullPolicy: Always
command: [/shared/argocd-dex, rundex]
env:

View File

@@ -5,7 +5,7 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.5.16
newTag: v2.5.22
resources:
- ./application-controller
- ./dex

View File

@@ -23,7 +23,7 @@ spec:
serviceAccountName: argocd-redis
containers:
- name: redis
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: Always
args:
- "--save"

View File

@@ -9500,8 +9500,8 @@ metadata:
---
apiVersion: v1
data:
ssh_known_hosts: |-
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
@@ -9635,7 +9635,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -9717,7 +9717,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -9893,7 +9893,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -9944,7 +9944,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -10151,7 +10151,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -12,4 +12,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.5.16
newTag: v2.5.22

View File

@@ -11,7 +11,7 @@ patchesStrategicMerge:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.5.16
newTag: v2.5.22
resources:
- ../../base/application-controller
- ../../base/applicationset-controller

View File

@@ -1071,7 +1071,7 @@ spec:
topologyKey: kubernetes.io/hostname
initContainers:
- name: config-init
image: haproxy:2.6.9-alpine
image: haproxy:2.6.14-alpine
imagePullPolicy: IfNotPresent
resources:
{}
@@ -1089,7 +1089,7 @@ spec:
mountPath: /data
containers:
- name: haproxy
image: haproxy:2.6.9-alpine
image: haproxy:2.6.14-alpine
imagePullPolicy: IfNotPresent
securityContext:
null
@@ -1179,7 +1179,7 @@ spec:
automountServiceAccountToken: false
initContainers:
- name: config-init
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
resources:
{}
@@ -1206,7 +1206,7 @@ spec:
containers:
- name: redis
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
@@ -1256,7 +1256,7 @@ spec:
- /bin/sh
- /readonly-config/trigger-failover-if-master.sh
- name: sentinel
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
command:
- redis-sentinel
@@ -1300,7 +1300,7 @@ spec:
{}
- name: split-brain-fix
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
command:
- sh

View File

@@ -11,14 +11,14 @@ redis-ha:
IPv6:
enabled: false
image:
tag: 2.6.9-alpine
tag: 2.6.14-alpine
containerSecurityContext: null
timeout:
server: 6m
client: 6m
checkInterval: 3s
image:
tag: 7.0.8-alpine
tag: 7.0.11-alpine
containerSecurityContext: null
sentinel:
bind: "0.0.0.0"

View File

@@ -10514,8 +10514,8 @@ metadata:
---
apiVersion: v1
data:
ssh_known_hosts: |-
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
@@ -10836,7 +10836,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -10917,7 +10917,7 @@ spec:
key: dexserver.disable.tls
name: argocd-cmd-params-cm
optional: true
image: ghcr.io/dexidp/dex:v2.35.3
image: ghcr.io/dexidp/dex:v2.37.0
imagePullPolicy: Always
name: dex
ports:
@@ -10946,7 +10946,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -10999,7 +10999,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -11070,7 +11070,7 @@ spec:
app.kubernetes.io/name: argocd-redis-ha-haproxy
topologyKey: kubernetes.io/hostname
containers:
- image: haproxy:2.6.9-alpine
- image: haproxy:2.6.14-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -11106,7 +11106,7 @@ spec:
- /readonly/haproxy_init.sh
command:
- sh
image: haproxy:2.6.9-alpine
image: haproxy:2.6.14-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:
@@ -11296,7 +11296,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -11347,7 +11347,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -11620,7 +11620,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -11855,7 +11855,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-application-controller
ports:
@@ -11932,7 +11932,7 @@ spec:
- /data/conf/redis.conf
command:
- redis-server
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -11985,7 +11985,7 @@ spec:
- /data/conf/sentinel.conf
command:
- redis-sentinel
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -12037,7 +12037,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
name: split-brain-fix
resources: {}
@@ -12066,7 +12066,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:

View File

@@ -1180,8 +1180,8 @@ metadata:
---
apiVersion: v1
data:
ssh_known_hosts: |-
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
@@ -1502,7 +1502,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1583,7 +1583,7 @@ spec:
key: dexserver.disable.tls
name: argocd-cmd-params-cm
optional: true
image: ghcr.io/dexidp/dex:v2.35.3
image: ghcr.io/dexidp/dex:v2.37.0
imagePullPolicy: Always
name: dex
ports:
@@ -1612,7 +1612,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1665,7 +1665,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1736,7 +1736,7 @@ spec:
app.kubernetes.io/name: argocd-redis-ha-haproxy
topologyKey: kubernetes.io/hostname
containers:
- image: haproxy:2.6.9-alpine
- image: haproxy:2.6.14-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -1772,7 +1772,7 @@ spec:
- /readonly/haproxy_init.sh
command:
- sh
image: haproxy:2.6.9-alpine
image: haproxy:2.6.14-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:
@@ -1962,7 +1962,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2013,7 +2013,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2286,7 +2286,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2521,7 +2521,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-application-controller
ports:
@@ -2598,7 +2598,7 @@ spec:
- /data/conf/redis.conf
command:
- redis-server
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -2651,7 +2651,7 @@ spec:
- /data/conf/sentinel.conf
command:
- redis-sentinel
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -2703,7 +2703,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
name: split-brain-fix
resources: {}
@@ -2732,7 +2732,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:

View File

@@ -9736,8 +9736,8 @@ metadata:
---
apiVersion: v1
data:
ssh_known_hosts: |-
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
@@ -9955,7 +9955,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -10036,7 +10036,7 @@ spec:
key: dexserver.disable.tls
name: argocd-cmd-params-cm
optional: true
image: ghcr.io/dexidp/dex:v2.35.3
image: ghcr.io/dexidp/dex:v2.37.0
imagePullPolicy: Always
name: dex
ports:
@@ -10065,7 +10065,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -10118,7 +10118,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -10195,7 +10195,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -10371,7 +10371,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -10422,7 +10422,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -10691,7 +10691,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -10924,7 +10924,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -402,8 +402,8 @@ metadata:
---
apiVersion: v1
data:
ssh_known_hosts: |-
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
ssh_known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
@@ -621,7 +621,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -702,7 +702,7 @@ spec:
key: dexserver.disable.tls
name: argocd-cmd-params-cm
optional: true
image: ghcr.io/dexidp/dex:v2.35.3
image: ghcr.io/dexidp/dex:v2.37.0
imagePullPolicy: Always
name: dex
ports:
@@ -731,7 +731,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -784,7 +784,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -861,7 +861,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:7.0.8-alpine
image: redis:7.0.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -1037,7 +1037,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1088,7 +1088,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1357,7 +1357,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -1590,7 +1590,7 @@ spec:
key: application.namespaces
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.5.16
image: quay.io/argoproj/argocd:v2.5.22
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -155,6 +155,7 @@ nav:
- user-guide/best_practices.md
- user-guide/status-badge.md
- user-guide/external-url.md
- user-guide/extra_info.md
- Notification subscriptions: user-guide/subscriptions.md
- Command Reference: user-guide/commands/argocd.md
- Developer Guide:

View File

@@ -388,6 +388,7 @@ type ApplicationSourceKustomize struct {
func (k *ApplicationSourceKustomize) AllowsConcurrentProcessing() bool {
return len(k.Images) == 0 &&
len(k.CommonLabels) == 0 &&
len(k.CommonAnnotations) == 0 &&
k.NamePrefix == "" &&
k.NameSuffix == ""
}

View File

@@ -2812,11 +2812,21 @@ func TestRetryStrategy_NextRetryAtCustomBackoff(t *testing.T) {
}
func TestSourceAllowsConcurrentProcessing_KustomizeParams(t *testing.T) {
src := ApplicationSource{Path: ".", Kustomize: &ApplicationSourceKustomize{
NameSuffix: "test",
}}
t.Run("Has NameSuffix", func(t *testing.T) {
src := ApplicationSource{Path: ".", Kustomize: &ApplicationSourceKustomize{
NameSuffix: "test",
}}
assert.False(t, src.AllowsConcurrentProcessing())
assert.False(t, src.AllowsConcurrentProcessing())
})
t.Run("Has CommonAnnotations", func(t *testing.T) {
src := ApplicationSource{Path: ".", Kustomize: &ApplicationSourceKustomize{
CommonAnnotations: map[string]string{"foo": "bar"},
}}
assert.False(t, src.AllowsConcurrentProcessing())
})
}
func TestUnSetCascadedDeletion(t *testing.T) {

View File

@@ -277,6 +277,7 @@ func (s *Service) runRepoOperation(
var helmClient helm.Client
var err error
revision = textutils.FirstNonEmpty(revision, source.TargetRevision)
unresolvedRevision := revision
if source.IsHelm() {
helmClient, revision, err = s.newHelmClientResolveRevision(repo, revision, source.Chart, settings.noCache || settings.noRevisionCache)
if err != nil {
@@ -388,7 +389,7 @@ func (s *Service) runRepoOperation(
return operation(gitClient.Root(), commitSHA, revision, func() (*operationContext, error) {
var signature string
if verifyCommit {
signature, err = gitClient.VerifyCommitSignature(revision)
signature, err = gitClient.VerifyCommitSignature(unresolvedRevision)
if err != nil {
return nil, err
}

View File

@@ -396,9 +396,7 @@ func (t *TestServerStream) SendHeader(metadata.MD) error {
return nil
}
func (t *TestServerStream) SetTrailer(metadata.MD) {
return
}
func (t *TestServerStream) SetTrailer(metadata.MD) {}
func (t *TestServerStream) Context() context.Context {
return t.ctx
@@ -449,9 +447,7 @@ func (t *TestResourceTreeServer) SendHeader(metadata.MD) error {
return nil
}
func (t *TestResourceTreeServer) SetTrailer(metadata.MD) {
return
}
func (t *TestResourceTreeServer) SetTrailer(metadata.MD) {}
func (t *TestResourceTreeServer) Context() context.Context {
return t.ctx
@@ -481,9 +477,7 @@ func (t *TestPodLogsServer) SendHeader(metadata.MD) error {
return nil
}
func (t *TestPodLogsServer) SetTrailer(metadata.MD) {
return
}
func (t *TestPodLogsServer) SetTrailer(metadata.MD) {}
func (t *TestPodLogsServer) Context() context.Context {
return t.ctx
@@ -550,6 +544,7 @@ func TestNoAppEnumeration(t *testing.T) {
appServer := newTestAppServerWithEnforcerConfigure(f, t, testApp, testDeployment)
noRoleCtx := context.Background()
// nolint:staticcheck
adminCtx := context.WithValue(noRoleCtx, "claims", &jwt.MapClaims{"groups": []string{"admin"}})
t.Run("Get", func(t *testing.T) {

View File

@@ -5,6 +5,7 @@ import (
"reflect"
"context"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/text"
log "github.com/sirupsen/logrus"
@@ -163,6 +164,7 @@ func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.R
GitHubAppEnterpriseBaseURL: repo.GitHubAppEnterpriseBaseURL,
Proxy: repo.Proxy,
Project: repo.Project,
InheritedCreds: repo.InheritedCreds,
}
item.ConnectionState = s.getConnectionState(ctx, item.Repo, q.ForceRefresh)
@@ -186,15 +188,16 @@ func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuer
}
// remove secrets
items = append(items, &appsv1.Repository{
Repo: repo.Repo,
Type: rType,
Name: repo.Name,
Username: repo.Username,
Insecure: repo.IsInsecure(),
EnableLFS: repo.EnableLFS,
EnableOCI: repo.EnableOCI,
Proxy: repo.Proxy,
Project: repo.Project,
Repo: repo.Repo,
Type: rType,
Name: repo.Name,
Username: repo.Username,
Insecure: repo.IsInsecure(),
EnableLFS: repo.EnableLFS,
EnableOCI: repo.EnableOCI,
Proxy: repo.Proxy,
Project: repo.Project,
InheritedCreds: repo.InheritedCreds,
})
}
}

View File

@@ -87,7 +87,18 @@ var (
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
},
}
fakeRepo = appsv1.Repository{
Repo: "https://test",
Type: "test",
Name: "test",
Username: "argo",
Insecure: false,
EnableLFS: false,
EnableOCI: false,
Proxy: "test",
Project: "argocd",
InheritedCreds: true,
}
guestbookApp = &appsv1.Application{
TypeMeta: metav1.TypeMeta{
Kind: "Application",
@@ -196,6 +207,33 @@ func TestRepositoryServer(t *testing.T) {
assert.Equal(t, repo.Repo, url)
})
t.Run("Test_GetInherited", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil)
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
url := "https://test"
db := &dbmocks.ArgoDB{}
testRepo := &appsv1.Repository{
Repo: url,
Type: "git",
Username: "foo",
InheritedCreds: true,
}
db.On("GetRepository", context.TODO(), url).Return(testRepo, nil)
db.On("RepositoryExists", context.TODO(), url).Return(true, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr)
repo, err := s.Get(context.TODO(), &repository.RepoQuery{
Repo: url,
})
assert.Nil(t, err)
testRepo.ConnectionState = repo.ConnectionState // overwrite connection state on our test object to simplify comparison below
assert.Equal(t, testRepo, repo)
})
t.Run("Test_GetWithErrorShouldReturn403", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
@@ -279,6 +317,23 @@ func TestRepositoryServer(t *testing.T) {
assert.Equal(t, repo.Repo, "test")
})
t.Run("Test_ListRepositories", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil)
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(nil, nil)
db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil)
db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{&fakeRepo, &fakeRepo}, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr)
resp, err := s.ListRepositories(context.TODO(), &repository.RepoQuery{})
assert.NoError(t, err)
assert.Equal(t, 2, len(resp.Items))
})
}
func TestRepositoryServerListApps(t *testing.T) {

View File

@@ -24,6 +24,8 @@ import (
// nolint:staticcheck
golang_proto "github.com/golang/protobuf/proto"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"github.com/argoproj/notifications-engine/pkg/api"
"github.com/argoproj/pkg/sync"
@@ -287,7 +289,9 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer {
apiFactory := api.NewFactory(settings_notif.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), opts.Namespace, secretInformer, configMapInformer)
return &ArgoCDServer{
dbInstance := db.NewDB(opts.Namespace, settingsMgr, opts.KubeClientset)
a := &ArgoCDServer{
ArgoCDServerOpts: opts,
log: log.NewEntry(log.StandardLogger()),
settings: settings,
@@ -303,11 +307,19 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer {
policyEnforcer: policyEnf,
userStateStorage: userStateStorage,
staticAssets: http.FS(staticFS),
db: db.NewDB(opts.Namespace, settingsMgr, opts.KubeClientset),
db: dbInstance,
apiFactory: apiFactory,
secretInformer: secretInformer,
configMapInformer: configMapInformer,
}
err = a.logInClusterWarnings()
if err != nil {
// Just log. It's not critical.
log.Warnf("Failed to log in-cluster warnings: %v", err)
}
return a
}
const (
@@ -354,6 +366,47 @@ func (l *Listeners) Close() error {
return nil
}
// logInClusterWarnings checks the in-cluster configuration and prints out any warnings.
func (a *ArgoCDServer) logInClusterWarnings() error {
labelSelector := labels.NewSelector()
req, err := labels.NewRequirement(common.LabelKeySecretType, selection.Equals, []string{common.LabelValueSecretTypeCluster})
if err != nil {
return fmt.Errorf("failed to construct cluster-type label selector: %w", err)
}
labelSelector = labelSelector.Add(*req)
secretsLister, err := a.settingsMgr.GetSecretsLister()
if err != nil {
return fmt.Errorf("failed to get secrets lister: %w", err)
}
clusterSecrets, err := secretsLister.Secrets(a.ArgoCDServerOpts.Namespace).List(labelSelector)
if err != nil {
return fmt.Errorf("failed to list cluster secrets: %w", err)
}
var inClusterSecrets []string
for _, clusterSecret := range clusterSecrets {
cluster, err := db.SecretToCluster(clusterSecret)
if err != nil {
return fmt.Errorf("could not unmarshal cluster secret %q: %w", clusterSecret.Name, err)
}
if cluster.Server == v1alpha1.KubernetesInternalAPIServerAddr {
inClusterSecrets = append(inClusterSecrets, clusterSecret.Name)
}
}
if len(inClusterSecrets) > 0 {
// Don't make this call unless we actually have in-cluster secrets, to save time.
dbSettings, err := a.settingsMgr.GetSettings()
if err != nil {
return fmt.Errorf("could not get DB settings: %w", err)
}
if !dbSettings.InClusterEnabled {
for _, clusterName := range inClusterSecrets {
log.Warnf("cluster %q uses in-cluster server address but it's disabled in Argo CD settings", clusterName)
}
}
}
return nil
}
func startListener(host string, port int) (net.Listener, error) {
var conn net.Listener
var realErr error
@@ -455,11 +508,11 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) {
var httpL net.Listener
var httpsL net.Listener
if !a.useTLS() {
httpL = tcpm.Match(cmux.HTTP1Fast())
httpL = tcpm.Match(cmux.HTTP1Fast("PATCH"))
grpcL = tcpm.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"))
} else {
// We first match on HTTP 1.1 methods.
httpL = tcpm.Match(cmux.HTTP1Fast())
httpL = tcpm.Match(cmux.HTTP1Fast("PATCH"))
// If not matched, we assume that its TLS.
tlsl := tcpm.Match(cmux.Any())
@@ -474,7 +527,7 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) {
// Now, we build another mux recursively to match HTTPS and gRPC.
tlsm = cmux.New(tlsl)
httpsL = tlsm.Match(cmux.HTTP1Fast())
httpsL = tlsm.Match(cmux.HTTP1Fast("PATCH"))
grpcL = tlsm.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"))
}
@@ -893,7 +946,8 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl
// Webhook handler for git events (Note: cache timeouts are hardcoded because API server does not write to cache and not really using them)
argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset)
acdWebhookHandler := webhook.NewHandler(a.Namespace, a.AppClientset, a.settings, a.settingsMgr, repocache.NewCache(a.Cache.GetCache(), 24*time.Hour, 3*time.Minute), a.Cache, argoDB)
acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.AppClientset, a.settings, a.settingsMgr, repocache.NewCache(a.Cache.GetCache(), 24*time.Hour, 3*time.Minute), a.Cache, argoDB)
mux.HandleFunc("/api/webhook", acdWebhookHandler.Handler)
// Serve cli binaries directly from API server

View File

@@ -1,5 +1,5 @@
# This file was automatically generated. DO NOT EDIT
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf

View File

@@ -1,4 +1,4 @@
FROM docker.io/library/redis:7.0.8-alpine as redis
FROM docker.io/library/redis:7.0.11-alpine as redis
# There are libraries we will want to copy from here in the final stage of the
# build, but the COPY directive does not have a way to determine system

View File

@@ -1,6 +1,6 @@
controller: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}"
api-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} "
dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.35.3 serve /dex.yaml"
controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}"
api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} "
dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.37.0 serve /dex.yaml"
redis: sh -c "/usr/local/bin/redis-server --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}"
repo-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_BINARY_NAME=argocd-repo-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
ui: sh -c "test $ARGOCD_IN_CI = true && exit 0; cd ui && ARGOCD_E2E_YARN_HOST=0.0.0.0 ${ARGOCD_E2E_YARN_CMD:-yarn} start"

View File

@@ -249,7 +249,7 @@ func TestSyncToSignedCommitWithoutKnownKey(t *testing.T) {
Expect(HealthIs(health.HealthStatusMissing))
}
func TestSyncToSignedCommitKeyWithKnownKey(t *testing.T) {
func TestSyncToSignedCommitWithKnownKey(t *testing.T) {
SkipOnEnv(t, "GPG")
Given(t).
Project("gpg").
@@ -267,6 +267,62 @@ func TestSyncToSignedCommitKeyWithKnownKey(t *testing.T) {
Expect(HealthIs(health.HealthStatusHealthy))
}
func TestSyncToSignedTagWithKnownKey(t *testing.T) {
SkipOnEnv(t, "GPG")
Given(t).
Project("gpg").
Revision("signed-tag").
Path(guestbookPath).
GPGPublicKeyAdded().
Sleep(2).
When().
AddSignedTag("signed-tag").
IgnoreErrors().
CreateApp().
Sync().
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy))
}
func TestSyncToSignedTagWithUnknownKey(t *testing.T) {
SkipOnEnv(t, "GPG")
Given(t).
Project("gpg").
Revision("signed-tag").
Path(guestbookPath).
Sleep(2).
When().
AddSignedTag("signed-tag").
IgnoreErrors().
CreateApp().
Sync().
Then().
Expect(OperationPhaseIs(OperationError)).
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
Expect(HealthIs(health.HealthStatusMissing))
}
func TestSyncToUnsignedTag(t *testing.T) {
SkipOnEnv(t, "GPG")
Given(t).
Project("gpg").
Revision("unsigned-tag").
Path(guestbookPath).
GPGPublicKeyAdded().
Sleep(2).
When().
AddTag("unsigned-tag").
IgnoreErrors().
CreateApp().
Sync().
Then().
Expect(OperationPhaseIs(OperationError)).
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
Expect(HealthIs(health.HealthStatusMissing))
}
func TestAppCreation(t *testing.T) {
ctx := Given(t)
ctx.
@@ -361,6 +417,24 @@ func TestDeleteAppResource(t *testing.T) {
Expect(HealthIs(health.HealthStatusMissing))
}
// Fix for issue #2677, support PATCH in HTTP service
func TestPatchHttp(t *testing.T) {
ctx := Given(t)
ctx.
Path(guestbookPath).
When().
CreateApp().
Sync().
PatchAppHttp(`{"metadata": {"labels": { "test": "patch" }, "annotations": { "test": "patch" }}}`).
Then().
And(func(app *Application) {
assert.Equal(t, "patch", app.Labels["test"])
assert.Equal(t, "patch", app.Annotations["test"])
})
}
// demonstrate that we cannot use a standard sync when an immutable field is changed, we must use "force"
func TestImmutableChange(t *testing.T) {
SkipOnEnv(t, "OPENSHIFT")

View File

@@ -1,12 +1,14 @@
package app
import (
"encoding/json"
"fmt"
"os"
log "github.com/sirupsen/logrus"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
client "github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
. "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/test/e2e/fixture"
"github.com/argoproj/argo-cd/v2/util/errors"
@@ -64,6 +66,18 @@ func (a *Actions) AddSignedFile(fileName, fileContents string) *Actions {
return a
}
func (a *Actions) AddSignedTag(name string) *Actions {
a.context.t.Helper()
fixture.AddSignedTag(name)
return a
}
func (a *Actions) AddTag(name string) *Actions {
a.context.t.Helper()
fixture.AddTag(name)
return a
}
func (a *Actions) CreateFromPartialFile(data string, flags ...string) *Actions {
a.context.t.Helper()
tmpFile, err := os.CreateTemp("", "")
@@ -238,6 +252,28 @@ func (a *Actions) PatchApp(patch string) *Actions {
return a
}
func (a *Actions) PatchAppHttp(patch string) *Actions {
a.context.t.Helper()
var application Application
var patchType = "merge"
var appName = a.context.AppQualifiedName()
var appNamespace = a.context.AppNamespace()
patchRequest := &client.ApplicationPatchRequest{
Name: &appName,
PatchType: &patchType,
Patch: &patch,
AppNamespace: &appNamespace,
}
jsonBytes, err := json.MarshalIndent(patchRequest, "", " ")
errors.CheckError(err)
err = fixture.DoHttpJsonRequest("PATCH",
fmt.Sprintf("/api/v1/applications/%v", appName),
&application,
jsonBytes...)
errors.CheckError(err)
return a
}
func (a *Actions) AppSet(flags ...string) *Actions {
a.context.t.Helper()
args := []string{"app", "set", a.context.AppQualifiedName()}

View File

@@ -92,6 +92,7 @@ type ACL struct {
const (
RepoURLTypeFile = "file"
RepoURLTypeHTTPS = "https"
RepoURLTypeHTTPSOrg = "https-org"
RepoURLTypeHTTPSClientCert = "https-cc"
RepoURLTypeHTTPSSubmodule = "https-sub"
RepoURLTypeHTTPSSubmoduleParent = "https-par"
@@ -103,6 +104,8 @@ const (
RepoURLTypeHelmOCI = "helm-oci"
GitUsername = "admin"
GitPassword = "password"
GithubAppID = "2978632978"
GithubAppInstallationID = "7893789433789"
GpgGoodKeyID = "D56C4FCA57A46444"
HelmOCIRegistryURL = "localhost:5000/myrepo"
)
@@ -251,6 +254,7 @@ const (
EnvRepoURLTypeSSHSubmodule = "ARGOCD_E2E_REPO_SSH_SUBMODULE"
EnvRepoURLTypeSSHSubmoduleParent = "ARGOCD_E2E_REPO_SSH_SUBMODULE_PARENT"
EnvRepoURLTypeHTTPS = "ARGOCD_E2E_REPO_HTTPS"
EnvRepoURLTypeHTTPSOrg = "ARGOCD_E2E_REPO_HTTPS_ORG"
EnvRepoURLTypeHTTPSClientCert = "ARGOCD_E2E_REPO_HTTPS_CLIENT_CERT"
EnvRepoURLTypeHTTPSSubmodule = "ARGOCD_E2E_REPO_HTTPS_SUBMODULE"
EnvRepoURLTypeHTTPSSubmoduleParent = "ARGOCD_E2E_REPO_HTTPS_SUBMODULE_PARENT"
@@ -272,6 +276,9 @@ func RepoURL(urlType RepoURLType) string {
// Git server via HTTPS
case RepoURLTypeHTTPS:
return GetEnvWithDefault(EnvRepoURLTypeHTTPS, "https://localhost:9443/argo-e2e/testdata.git")
// Git "organisation" via HTTPS
case RepoURLTypeHTTPSOrg:
return GetEnvWithDefault(EnvRepoURLTypeHTTPSOrg, "https://localhost:9443/argo-e2e")
// Git server via HTTPS - Client Cert protected
case RepoURLTypeHTTPSClientCert:
return GetEnvWithDefault(EnvRepoURLTypeHTTPSClientCert, "https://localhost:9444/argo-e2e/testdata.git")
@@ -747,6 +754,26 @@ func AddSignedFile(path, contents string) {
}
}
func AddSignedTag(name string) {
prevGnuPGHome := os.Getenv("GNUPGHOME")
os.Setenv("GNUPGHOME", TmpDir+"/gpg")
defer os.Setenv("GNUPGHOME", prevGnuPGHome)
FailOnErr(Run(repoDirectory(), "git", "-c", fmt.Sprintf("user.signingkey=%s", GpgGoodKeyID), "tag", "-sm", "add signed tag", name))
if IsRemote() {
FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master"))
}
}
func AddTag(name string) {
prevGnuPGHome := os.Getenv("GNUPGHOME")
os.Setenv("GNUPGHOME", TmpDir+"/gpg")
defer os.Setenv("GNUPGHOME", prevGnuPGHome)
FailOnErr(Run(repoDirectory(), "git", "tag", name))
if IsRemote() {
FailOnErr(Run(repoDirectory(), "git", "push", "--tags", "-f", "origin", "master"))
}
}
// create the resource by creating using "kubectl apply", with bonus templating
func Declarative(filename string, values interface{}) (string, error) {

View File

@@ -7,9 +7,11 @@ import (
"github.com/stretchr/testify/assert"
repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/test/e2e/fixture"
"github.com/argoproj/argo-cd/v2/test/e2e/fixture/app"
"github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos"
. "github.com/argoproj/argo-cd/v2/util/errors"
argoio "github.com/argoproj/argo-cd/v2/util/io"
"github.com/argoproj/argo-cd/v2/util/settings"
)
@@ -52,6 +54,38 @@ func TestAddRemovePublicRepo(t *testing.T) {
})
}
func TestGetRepoWithInheritedCreds(t *testing.T) {
app.Given(t).And(func() {
// create repo credentials
FailOnErr(fixture.RunCli("repocreds", "add", fixture.RepoURL(fixture.RepoURLTypeHTTPSOrg), "--github-app-id", fixture.GithubAppID, "--github-app-installation-id", fixture.GithubAppInstallationID, "--github-app-private-key-path", repos.CertKeyPath))
repoUrl := fixture.RepoURL(fixture.RepoURLTypeHTTPS)
// Hack: First we need to create repo with valid credentials
FailOnErr(fixture.RunCli("repo", "add", repoUrl, "--username", fixture.GitUsername, "--password", fixture.GitPassword, "--insecure-skip-server-verification"))
// Then, we remove username/password so that the repo inherits the credentials from our repocreds
conn, repoClient, err := fixture.ArgoCDClientset.NewRepoClient()
assert.NoError(t, err)
defer argoio.Close(conn)
_, err = repoClient.UpdateRepository(context.Background(), &repositorypkg.RepoUpdateRequest{
Repo: &v1alpha1.Repository{
Repo: repoUrl,
},
})
assert.NoError(t, err)
// CLI output should indicate that repo has inherited credentials
out, err := fixture.RunCli("repo", "get", repoUrl)
assert.NoError(t, err)
assert.Contains(t, out, "inherited")
_, err = fixture.RunCli("repo", "rm", repoUrl)
assert.NoError(t, err)
})
}
func TestUpsertExistingRepo(t *testing.T) {
app.Given(t).And(func() {
fixture.SetRepos(settings.RepositoryCredentials{URL: fixture.RepoURL(fixture.RepoURLTypeFile)})

View File

@@ -35,7 +35,7 @@ test('gitlab.com', () => {
'git@gitlab.com:alex_collins/private-repo.git',
'b1fe9426ead684d7af16958920968342ee295c1f',
'https://gitlab.com/alex_collins/private-repo',
'https://gitlab.com/alex_collins/private-repo/commit/b1fe9426ead684d7af16958920968342ee295c1f');
'https://gitlab.com/alex_collins/private-repo/-/commit/b1fe9426ead684d7af16958920968342ee295c1f');
});
test('bitbucket.org', () => {

View File

@@ -33,6 +33,12 @@ export function revisionUrl(url: string, revision: string): string {
urlSubPath = isSHA(revision) ? 'commits' : 'src';
}
// Gitlab changed the way urls to commit look like
// Ref: https://docs.gitlab.com/ee/update/deprecations.html#legacy-urls-replaced-or-removed
if (parsed.source === 'gitlab.com') {
urlSubPath = '-/' + urlSubPath;
}
if (!supportedSource(parsed)) {
return null;
}

View File

@@ -100,13 +100,14 @@ export class ApplicationsService {
public getManifest(name: string, appNamespace: string, revision: string): Promise<models.ManifestResponse> {
return requests
.get(`/applications/${name}/manifests`)
.query({name, revision})
.query({name, revision, appNamespace})
.then(res => res.body as models.ManifestResponse);
}
public updateSpec(appName: string, appNamespace: string, spec: models.ApplicationSpec): Promise<models.ApplicationSpec> {
return requests
.put(`/applications/${appName}/spec`)
.query({appNamespace})
.send(spec)
.then(res => res.body as models.ApplicationSpec);
}

View File

@@ -176,7 +176,7 @@ XWyb96wrUlv+E8I=
// Taken from hack/ssh_known_hosts
const Test_ValidSSHKnownHostsData = `
# BitBucket
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
# GitHub
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
# GitLab
@@ -189,7 +189,7 @@ vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOf
`
const Test_InvalidSSHKnownHostsData = `
bitbucket.org AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
# GitHub
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
# GitLab
@@ -322,7 +322,7 @@ func Test_MatchHostName(t *testing.T) {
func Test_SSHFingerprintSHA256(t *testing.T) {
// actual SHA256 fingerprints for keys defined above
fingerprints := [...]string{
"zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A",
"46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E",
"nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8",
"HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw",
"eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8",
@@ -344,7 +344,7 @@ func Test_SSHFingerprintSHA256(t *testing.T) {
func Test_SSHFingerPrintSHA256FromString(t *testing.T) {
// actual SHA256 fingerprints for keys defined above
fingerprints := [...]string{
"zzXQOXSRBEiUtuE8AikJYKwbHaxvSc0ojez9YXaGp1A",
"46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E",
"nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8",
"HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw",
"eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8",

View File

@@ -185,7 +185,7 @@ XWyb96wrUlv+E8I=
// Taken from hack/ssh_known_hosts
const Test_ValidSSHKnownHostsData = `
# BitBucket
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
# GitHub
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
# GitLab
@@ -198,7 +198,7 @@ vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOf
`
const Test_InvalidSSHKnownHostsData = `
bitbucket.org AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
bitbucket.org AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
# GitHub
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
# GitLab

View File

@@ -68,7 +68,7 @@ func (db *db) ListClusters(ctx context.Context) (*appv1.ClusterList, error) {
inClusterEnabled := settings.InClusterEnabled
hasInClusterCredentials := false
for _, clusterSecret := range clusterSecrets {
cluster, err := secretToCluster(clusterSecret)
cluster, err := SecretToCluster(clusterSecret)
if err != nil {
log.Errorf("could not unmarshal cluster secret %s", clusterSecret.Name)
continue
@@ -77,8 +77,6 @@ func (db *db) ListClusters(ctx context.Context) (*appv1.ClusterList, error) {
if inClusterEnabled {
hasInClusterCredentials = true
clusterList.Items = append(clusterList.Items, *cluster)
} else {
log.Errorf("failed to add cluster %q to cluster list: in-cluster server address is disabled in Argo CD settings", cluster.Name)
}
} else {
clusterList.Items = append(clusterList.Items, *cluster)
@@ -122,7 +120,7 @@ func (db *db) CreateCluster(ctx context.Context, c *appv1.Cluster) (*appv1.Clust
return nil, err
}
cluster, err := secretToCluster(clusterSecret)
cluster, err := SecretToCluster(clusterSecret)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "could not unmarshal cluster secret %s", clusterSecret.Name)
}
@@ -150,7 +148,7 @@ func (db *db) WatchClusters(ctx context.Context,
common.LabelValueSecretTypeCluster,
func(secret *apiv1.Secret) {
cluster, err := secretToCluster(secret)
cluster, err := SecretToCluster(secret)
if err != nil {
log.Errorf("could not unmarshal cluster secret %s", secret.Name)
return
@@ -165,12 +163,12 @@ func (db *db) WatchClusters(ctx context.Context,
},
func(oldSecret *apiv1.Secret, newSecret *apiv1.Secret) {
oldCluster, err := secretToCluster(oldSecret)
oldCluster, err := SecretToCluster(oldSecret)
if err != nil {
log.Errorf("could not unmarshal cluster secret %s", oldSecret.Name)
return
}
newCluster, err := secretToCluster(newSecret)
newCluster, err := SecretToCluster(newSecret)
if err != nil {
log.Errorf("could not unmarshal cluster secret %s", newSecret.Name)
return
@@ -220,7 +218,7 @@ func (db *db) GetCluster(_ context.Context, server string) (*appv1.Cluster, erro
return nil, err
}
if len(res) > 0 {
return secretToCluster(res[0].(*apiv1.Secret))
return SecretToCluster(res[0].(*apiv1.Secret))
}
if server == appv1.KubernetesInternalAPIServerAddr {
return db.getLocalCluster(), nil
@@ -241,7 +239,7 @@ func (db *db) GetProjectClusters(ctx context.Context, project string) ([]*appv1.
}
var res []*appv1.Cluster
for i := range secrets {
cluster, err := secretToCluster(secrets[i].(*apiv1.Secret))
cluster, err := SecretToCluster(secrets[i].(*apiv1.Secret))
if err != nil {
return nil, err
}
@@ -295,7 +293,7 @@ func (db *db) UpdateCluster(ctx context.Context, c *appv1.Cluster) (*appv1.Clust
if err != nil {
return nil, err
}
cluster, err := secretToCluster(clusterSecret)
cluster, err := SecretToCluster(clusterSecret)
if err != nil {
log.Errorf("could not unmarshal cluster secret %s", clusterSecret.Name)
return nil, err
@@ -362,8 +360,8 @@ func clusterToSecret(c *appv1.Cluster, secret *apiv1.Secret) error {
return nil
}
// secretToCluster converts a secret into a Cluster object
func secretToCluster(s *apiv1.Secret) (*appv1.Cluster, error) {
// SecretToCluster converts a secret into a Cluster object
func SecretToCluster(s *apiv1.Secret) (*appv1.Cluster, error) {
var config appv1.ClusterConfig
if len(s.Data["config"]) > 0 {
err := json.Unmarshal(s.Data["config"], &config)

View File

@@ -43,7 +43,7 @@ func Test_secretToCluster(t *testing.T) {
"config": []byte("{\"username\":\"foo\"}"),
},
}
cluster, err := secretToCluster(secret)
cluster, err := SecretToCluster(secret)
require.NoError(t, err)
assert.Equal(t, *cluster, v1alpha1.Cluster{
Name: "test",
@@ -89,7 +89,7 @@ func Test_secretToCluster_NoConfig(t *testing.T) {
"server": []byte("http://mycluster"),
},
}
cluster, err := secretToCluster(secret)
cluster, err := SecretToCluster(secret)
assert.NoError(t, err)
assert.Equal(t, *cluster, v1alpha1.Cluster{
Name: "test",
@@ -111,7 +111,7 @@ func Test_secretToCluster_InvalidConfig(t *testing.T) {
"config": []byte("{'tlsClientConfig':{'insecure':false}}"),
},
}
cluster, err := secretToCluster(secret)
cluster, err := SecretToCluster(secret)
require.Error(t, err)
assert.Nil(t, cluster)
}

View File

@@ -151,7 +151,7 @@ func replaceListSecrets(obj []interface{}, secretValues map[string]string) []int
// https://dexidp.io/docs/connectors/
func needsRedirectURI(connectorType string) bool {
switch connectorType {
case "oidc", "saml", "microsoft", "linkedin", "gitlab", "github", "bitbucket-cloud", "openshift":
case "oidc", "saml", "microsoft", "linkedin", "gitlab", "github", "bitbucket-cloud", "openshift", "gitea", "google", "oauth":
return true
}
return false

View File

@@ -270,7 +270,7 @@ func Test_GenerateDexConfig(t *testing.T) {
})
t.Run("Redirect config", func(t *testing.T) {
types := []string{"oidc", "saml", "microsoft", "linkedin", "gitlab", "github", "bitbucket-cloud"}
types := []string{"oidc", "saml", "microsoft", "linkedin", "gitlab", "github", "bitbucket-cloud", "openshift", "gitea", "google", "oauth"}
for _, c := range types {
assert.True(t, needsRedirectURI(c))
}

View File

@@ -1407,7 +1407,7 @@ func (mgr *SettingsManager) updateSettingsFromSecret(settings *ArgoCDSettings, a
// return values are nil, no external secret has been configured.
func (mgr *SettingsManager) externalServerTLSCertificate() (*tls.Certificate, error) {
var cert tls.Certificate
secret, err := mgr.clientset.CoreV1().Secrets(mgr.namespace).Get(mgr.ctx, externalServerTLSSecretName, metav1.GetOptions{})
secret, err := mgr.secrets.Secrets(mgr.namespace).Get(externalServerTLSSecretName)
if err != nil {
if apierr.IsNotFound(err) {
return nil, nil

View File

@@ -3,6 +3,7 @@ package webhook
import (
"context"
"fmt"
"github.com/argoproj/argo-cd/v2/util/glob"
"html"
"net/http"
"net/url"
@@ -45,6 +46,7 @@ type ArgoCDWebhookHandler struct {
serverCache *servercache.Cache
db db.ArgoDB
ns string
appNs []string
appClientset appclientset.Interface
github *github.Webhook
gitlab *gitlab.Webhook
@@ -54,7 +56,7 @@ type ArgoCDWebhookHandler struct {
settingsSrc settingsSource
}
func NewHandler(namespace string, appClientset appclientset.Interface, set *settings.ArgoCDSettings, settingsSrc settingsSource, repoCache *cache.Cache, serverCache *servercache.Cache, argoDB db.ArgoDB) *ArgoCDWebhookHandler {
func NewHandler(namespace string, applicationNamespaces []string, appClientset appclientset.Interface, set *settings.ArgoCDSettings, settingsSrc settingsSource, repoCache *cache.Cache, serverCache *servercache.Cache, argoDB db.ArgoDB) *ArgoCDWebhookHandler {
githubWebhook, err := github.New(github.Options.Secret(set.WebhookGitHubSecret))
if err != nil {
log.Warnf("Unable to init the GitHub webhook")
@@ -78,6 +80,7 @@ func NewHandler(namespace string, appClientset appclientset.Interface, set *sett
acdWebhook := ArgoCDWebhookHandler{
ns: namespace,
appNs: applicationNamespaces,
appClientset: appClientset,
github: githubWebhook,
gitlab: gitlabWebhook,
@@ -214,7 +217,14 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload interface{}) {
for _, webURL := range webURLs {
log.Infof("Received push event repo: %s, revision: %s, touchedHead: %v", webURL, revision, touchedHead)
}
appIf := a.appClientset.ArgoprojV1alpha1().Applications(a.ns)
nsFilter := a.ns
if len(a.appNs) > 0 {
// Retrieve app from all namespaces
nsFilter = ""
}
appIf := a.appClientset.ArgoprojV1alpha1().Applications(nsFilter)
apps, err := appIf.List(context.Background(), metav1.ListOptions{})
if err != nil {
log.Warnf("Failed to list applications: %v", err)
@@ -232,13 +242,22 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload interface{}) {
return
}
// Skip any application that is neither in the control plane's namespace
// nor in the list of enabled namespaces.
var filteredApps []v1alpha1.Application
for _, app := range apps.Items {
if app.Namespace == a.ns || glob.MatchStringInList(a.appNs, app.Namespace, false) {
filteredApps = append(filteredApps, app)
}
}
for _, webURL := range webURLs {
repoRegexp, err := getWebUrlRegex(webURL)
if err != nil {
log.Warnf("Failed to get repoRegexp: %s", err)
continue
}
for _, app := range apps.Items {
for _, app := range filteredApps {
if appRevisionHasChanged(&app, revision, touchedHead) && appUsesURL(&app, webURL, repoRegexp) {
if appFilesHaveChanged(&app, changedFiles) {
_, err = argo.RefreshApp(appIf, app.ObjectMeta.Name, v1alpha1.RefreshTypeNormal)

View File

@@ -16,6 +16,8 @@ import (
bitbucketserver "gopkg.in/go-playground/webhooks.v5/bitbucket-server"
"gopkg.in/go-playground/webhooks.v5/github"
"gopkg.in/go-playground/webhooks.v5/gitlab"
"k8s.io/apimachinery/pkg/runtime"
kubetesting "k8s.io/client-go/testing"
"github.com/argoproj/argo-cd/v2/util/cache/appstate"
@@ -45,10 +47,25 @@ func (f fakeSettingsSrc) GetTrackingMethod() (string, error) {
return "", nil
}
func NewMockHandler() *ArgoCDWebhookHandler {
appClientset := appclientset.NewSimpleClientset()
type reactorDef struct {
verb string
resource string
reaction kubetesting.ReactionFunc
}
func NewMockHandler(reactor *reactorDef, applicationNamespaces []string, objects ...runtime.Object) *ArgoCDWebhookHandler {
appClientset := appclientset.NewSimpleClientset(objects...)
if reactor != nil {
defaultReactor := appClientset.ReactionChain[0]
appClientset.ReactionChain = nil
appClientset.AddReactor("list", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
return defaultReactor.React(action)
})
appClientset.AddReactor(reactor.verb, reactor.resource, reactor.reaction)
}
cacheClient := cacheutil.NewCache(cacheutil.NewInMemoryCache(1 * time.Hour))
return NewHandler("", appClientset, &settings.ArgoCDSettings{}, &fakeSettingsSrc{}, cache.NewCache(
return NewHandler("argocd", applicationNamespaces, appClientset, &settings.ArgoCDSettings{}, &fakeSettingsSrc{}, cache.NewCache(
cacheClient,
1*time.Minute,
1*time.Minute,
@@ -57,8 +74,8 @@ func NewMockHandler() *ArgoCDWebhookHandler {
func TestGitHubCommitEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-GitHub-Event", "push")
eventJSON, err := os.ReadFile("testdata/github-commit-event.json")
assert.NoError(t, err)
@@ -71,10 +88,98 @@ func TestGitHubCommitEvent(t *testing.T) {
hook.Reset()
}
// TestGitHubCommitEvent_AppsInOtherNamespaces makes sure that webhooks properly find apps in the configured set of
// allowed namespaces when Apps are allowed in any namespace
func TestGitHubCommitEvent_AppsInOtherNamespaces(t *testing.T) {
hook := test.NewGlobal()
patchedApps := make([]string, 0, 3)
reaction := func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
patchAction := action.(kubetesting.PatchAction)
patchedApps = append(patchedApps, patchAction.GetName())
return true, nil, nil
}
h := NewMockHandler(&reactorDef{"patch", "applications", reaction}, []string{"end-to-end-tests", "app-team-*"},
&v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app-to-refresh-in-default-namespace",
Namespace: "argocd",
},
Spec: v1alpha1.ApplicationSpec{
Source: v1alpha1.ApplicationSource{
RepoURL: "https://github.com/jessesuen/test-repo",
Path: ".",
},
},
}, &v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app-to-ignore",
Namespace: "kube-system",
},
Spec: v1alpha1.ApplicationSpec{
Source: v1alpha1.ApplicationSource{
RepoURL: "https://github.com/jessesuen/test-repo",
Path: ".",
},
},
}, &v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app-to-refresh-in-exact-match-namespace",
Namespace: "end-to-end-tests",
},
Spec: v1alpha1.ApplicationSpec{
Source: v1alpha1.ApplicationSource{
RepoURL: "https://github.com/jessesuen/test-repo",
Path: ".",
},
},
}, &v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app-to-refresh-in-globbed-namespace",
Namespace: "app-team-two",
},
Spec: v1alpha1.ApplicationSpec{
Source: v1alpha1.ApplicationSource{
RepoURL: "https://github.com/jessesuen/test-repo",
Path: ".",
},
},
},
)
req := httptest.NewRequest("POST", "/api/webhook", nil)
req.Header.Set("X-GitHub-Event", "push")
eventJSON, err := os.ReadFile("testdata/github-commit-event.json")
assert.NoError(t, err)
req.Body = io.NopCloser(bytes.NewReader(eventJSON))
w := httptest.NewRecorder()
h.Handler(w, req)
assert.Equal(t, w.Code, http.StatusOK)
logMessages := make([]string, 0, len(hook.Entries))
for _, entry := range hook.Entries {
logMessages = append(logMessages, entry.Message)
}
assert.Contains(t, logMessages, "Requested app 'app-to-refresh-in-default-namespace' refresh")
assert.Contains(t, logMessages, "Requested app 'app-to-refresh-in-exact-match-namespace' refresh")
assert.Contains(t, logMessages, "Requested app 'app-to-refresh-in-globbed-namespace' refresh")
assert.NotContains(t, logMessages, "Requested app 'app-to-ignore' refresh")
assert.Contains(t, patchedApps, "app-to-refresh-in-default-namespace")
assert.Contains(t, patchedApps, "app-to-refresh-in-exact-match-namespace")
assert.Contains(t, patchedApps, "app-to-refresh-in-globbed-namespace")
assert.NotContains(t, patchedApps, "app-to-ignore")
assert.Len(t, patchedApps, 3)
hook.Reset()
}
func TestGitHubTagEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-GitHub-Event", "push")
eventJSON, err := os.ReadFile("testdata/github-tag-event.json")
assert.NoError(t, err)
@@ -89,8 +194,8 @@ func TestGitHubTagEvent(t *testing.T) {
func TestGitHubPingEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-GitHub-Event", "ping")
eventJSON, err := os.ReadFile("testdata/github-ping-event.json")
assert.NoError(t, err)
@@ -105,8 +210,8 @@ func TestGitHubPingEvent(t *testing.T) {
func TestBitbucketServerRepositoryReferenceChangedEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-Event-Key", "repo:refs_changed")
eventJSON, err := os.ReadFile("testdata/bitbucket-server-event.json")
assert.NoError(t, err)
@@ -123,7 +228,7 @@ func TestBitbucketServerRepositoryReferenceChangedEvent(t *testing.T) {
func TestBitbucketServerRepositoryDiagnosticPingEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
h := NewMockHandler(nil, []string{})
eventJSON := "{\"test\": true}"
req := httptest.NewRequest("POST", "/api/webhook", bytes.NewBufferString(eventJSON))
req.Header.Set("X-Event-Key", "diagnostics:ping")
@@ -137,8 +242,8 @@ func TestBitbucketServerRepositoryDiagnosticPingEvent(t *testing.T) {
func TestGogsPushEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-Gogs-Event", "push")
eventJSON, err := os.ReadFile("testdata/gogs-event.json")
assert.NoError(t, err)
@@ -153,8 +258,8 @@ func TestGogsPushEvent(t *testing.T) {
func TestGitLabPushEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-Gitlab-Event", "Push Hook")
eventJSON, err := os.ReadFile("testdata/gitlab-event.json")
assert.NoError(t, err)
@@ -169,8 +274,8 @@ func TestGitLabPushEvent(t *testing.T) {
func TestInvalidMethod(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("GET", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodGet, "/api/webhook", nil)
req.Header.Set("X-GitHub-Event", "push")
w := httptest.NewRecorder()
h.Handler(w, req)
@@ -183,8 +288,8 @@ func TestInvalidMethod(t *testing.T) {
func TestInvalidEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-GitHub-Event", "push")
w := httptest.NewRecorder()
h.Handler(w, req)
@@ -197,8 +302,8 @@ func TestInvalidEvent(t *testing.T) {
func TestUnknownEvent(t *testing.T) {
hook := test.NewGlobal()
h := NewMockHandler()
req := httptest.NewRequest("POST", "/api/webhook", nil)
h := NewMockHandler(nil, []string{})
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
req.Header.Set("X-Unknown-Event", "push")
w := httptest.NewRecorder()
h.Handler(w, req)