Compare commits

..

460 Commits

Author SHA1 Message Date
argo-bot
41828a5fb1 Bump version to 2.2.16 2022-11-01 20:26:51 +00:00
argo-bot
18ced792ee Bump version to 2.2.16 2022-11-01 20:26:33 +00:00
Chromo-residuum-opec
80861b64bb docs: fix 'bellow' typos (#11038)
Signed-off-by: backfire-monism-net <development.0extl@simplelogin.com>

Signed-off-by: backfire-monism-net <development.0extl@simplelogin.com>
2022-10-22 20:16:36 -04:00
Michael Crenshaw
f1a8ebc224 chore: fix CI (#11022)
* chore: fix CI

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

* no more set global

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

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-21 11:26:15 -04:00
Michael Crenshaw
f58059aed2 chore: fix e2e (#11005)
* chore: fix e2e

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

* more config

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

* global

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

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-21 11:26:15 -04:00
Alex Eftimie
57edeec3ef docs: mention that OCI helm does not support version ranges (#11026)
* docs: mention that OCI helm does not support version ranges

Signed-off-by: Alex Eftimie <alex.eftimie@getyourguide.com>

* Apply suggestions from code review

Signed-off-by: Alex Eftimie <alex.eftimie@getyourguide.com>

Signed-off-by: Alex Eftimie <alex.eftimie@getyourguide.com>
2022-10-21 11:19:24 -04:00
Allex
d025f7edc1 fix: Update custom health check for kiali.io/Kiali (#10995)
With Kiali v1.57.1 an additional status condition was added:
```
    - lastTransitionTime: '2022-10-14T11:56:24Z'
      message: ''
      reason: ''
      status: 'False'
      type: Failure
```

Based on the discussion in https://github.com/kiali/kiali/issues/5560 this should not lead to a degraded health state.

This will no longer return Degraded as a catch-all and use the `type` and `status` fields of the condition to determine the CR health.

Signed-off-by: Allex Veldman <allexveldman+github@gmail.com>

Signed-off-by: Allex Veldman <allexveldman+github@gmail.com>
2022-10-19 12:17:47 -04:00
Michael Crenshaw
ff19401bbf chore: upgrade actions/checkout to v3, i.e. Node.js 16 (#10947)
* chore: updgrade actions/checkout to v3, i.e. Node.js 16

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

* more node 12

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

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-19 11:35:07 -04:00
argo-bot
b26224950a Bump version to 2.2.15 2022-10-18 21:49:38 +00:00
argo-bot
63b9f6975a Bump version to 2.2.15 2022-10-18 21:49:25 +00:00
Leonardo Luz Almeida
a381e704e2 chore: update actions/setup-go to v2 (#8349)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-10-18 17:43:48 -04:00
Michael Crenshaw
e0a3009c1a Revert "Bump version to 2.2.15"
This reverts commit e71faec22c.

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-18 17:15:39 -04:00
Michael Crenshaw
06cc50d163 Revert "Bump version to 2.2.15"
This reverts commit 9a0033c305.

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-18 17:15:30 -04:00
Michael Crenshaw
fd7293bc7f chore: fix bad merge
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-18 17:10:31 -04:00
Leonardo Luz Almeida
de1836d3c3 chore: Use go install to add spdx-sbom-generator (#8346)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-10-18 17:02:41 -04:00
Leonardo Luz Almeida
dbaa1f247b chore: generate sbom for the released docker image (#8338)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-10-18 17:02:37 -04:00
Leonardo Luz Almeida
d1949d3f26 chore: generate and upload sbom during release (#8332)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-10-18 17:02:30 -04:00
argo-bot
9a0033c305 Bump version to 2.2.15 2022-10-18 19:55:13 +00:00
argo-bot
e71faec22c Bump version to 2.2.15 2022-10-18 19:54:57 +00:00
Michael Crenshaw
4f92ad2448 chore: use one checksum file
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-18 15:43:35 -04:00
34FathomBelow
0aa414e875 chore: release signature of sbom (#10969)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>

Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-10-18 15:40:18 -04:00
Jessie Teng
cda32ec297 fix: Resource list in sync page msg style#10887 (#10970)
* fix: Resource list in sync page msg style#10887

Signed-off-by: Teng, Jessie <yilin.teng@fmr.com>

* fix: Resource list in sync page msg style#10887

Signed-off-by: Teng, Jessie <yilin.teng@fmr.com>

* fix: Resource list in sync page msg style#10887

Signed-off-by: Teng, Jessie <yilin.teng@fmr.com>

* fix: Resource list in sync page msg style#10887

Signed-off-by: Teng, Jessie <yilin.teng@fmr.com>

Signed-off-by: Teng, Jessie <yilin.teng@fmr.com>
2022-10-18 14:02:17 -04:00
34FathomBelow
7284f5a9a5 chore: provide checksums for cli-binaries (#9260)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-10-17 15:20:51 -04:00
Alex Collins
da58f265a9 ci: Cancel redundant builds. Fixes #9222 (#9223)
Signed-off-by: Alex Collins <alex_collins@intuit.com>
2022-10-17 13:20:53 -04:00
34FathomBelow
f57fdec7fb chore: sign checksums file for release binaries (#10963)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>

Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-10-17 13:04:09 -04:00
34FathomBelow
ebfb31e53e chore: implement signed images (#10925)
* consolidate checksums into one file

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

* sign container images

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

* sign container images

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

* remove id-token permissions

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

Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-10-17 13:02:43 -04:00
Michael Crenshaw
b12281728e chore: upgrade dex to v2.35.3 to avoid CVE-2022-27665 (#10939)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-17 12:33:19 -04:00
Aiman Fatima
cd3de4afa7 fix: Display pointer on labels for resource names in sync panel (#10959)
Signed-off-by: Aiman Fatima <aimanfatimadl@gmail.com>

Signed-off-by: Aiman Fatima <aimanfatimadl@gmail.com>
2022-10-17 09:30:50 -04:00
Chris Davis
deb4829c77 fix: Use os.PathSeparator instead of hard-coded string to resolve local file paths (#10945) (#10946)
fix: Use os.PathSeparator instead of hard-coded string to resolve local file paths (#10945) (#10946)
2022-10-14 13:54:54 -07:00
Michael Crenshaw
f1c64b43fb docs: more docs for directory apps (#10879)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-12 11:21:29 -04:00
Michael Crenshaw
e61b55fc7a docs: clarify how default RBAC policy works (#10896)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-12 11:17:25 -04:00
Mayursinh Sarvaiya
7b0bb8d0de fix(ui): sync option label doesn't check corresponding box (#10863) (#10876)
* fix(ui): sync option label doesn't check corresponding box

Signed-off-by: Mayursinh Sarvaiya <marvinduff97@gmail.com>

* fix: lint

Signed-off-by: Mayursinh Sarvaiya <marvinduff97@gmail.com>

Signed-off-by: Mayursinh Sarvaiya <marvinduff97@gmail.com>
2022-10-10 14:59:42 -04:00
Nir Shtein
11213c6adf fix: clicking HEAD in bitbucket leads to a 404 page (#10862)
* Wrap error objects to include context

Signed-off-by: Nir Shtein <89006520+nirsht@users.noreply.github.com>

* fix: duplicate source namespace validation (#10853)

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

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

* Fix CR

Signed-off-by: Nir Shtein <89006520+nirsht@users.noreply.github.com>

* Change 'branch' to 'src' when building url path

Signed-off-by: Nir Shtein <89006520+nirsht@users.noreply.github.com>

* Revert "Fix CR"

This reverts commit 4b92408412.

Signed-off-by: Nir Shtein <89006520+nirsht@users.noreply.github.com>

* Revert "Wrap error objects to include context"

This reverts commit d1789bd271.

Signed-off-by: Nir Shtein <89006520+nirsht@users.noreply.github.com>

Signed-off-by: Nir Shtein <89006520+nirsht@users.noreply.github.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>
2022-10-09 12:11:31 -04:00
Sakshi Jain
2100fe80a9 fix: added css to change cursor to pointer on hover (#10864) (#10867)
* added css to change cursor to pointer on hover

Signed-off-by: Sakshi <sakshi.jain7597@gmail.com>

* moved cursor change to only label and input

Signed-off-by: Sakshi <sakshi.jain7597@gmail.com>

Signed-off-by: Sakshi <sakshi.jain7597@gmail.com>
2022-10-09 12:05:50 -04:00
Matt Morrison
4293085a39 fix: consider destination cluster name when validating destinations (#10594)
Signed-off-by: Matt Morrison <matt.morrison@zapier.com>

Signed-off-by: Matt Morrison <matt.morrison@zapier.com>
2022-10-07 16:50:45 -04:00
Minchao
ab46c6b53a docs: fix advice about preferred version in high availability (#10619)
* docs: fix advice about preferred version in high availability

Signed-off-by: Minchao <minchao.220@gmail.com>

* Update docs/operator-manual/high_availability.md

Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: Minchao <minchao.220@gmail.com>

Signed-off-by: Minchao <minchao.220@gmail.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-07 16:11:11 -04:00
Lars Kellogg-Stedman
eef5148f4a docs: Correct grammar issues in docs on manifest path annotations (#10776)
The "Webhook and Manifest Paths Annotation" section of the documentation
contained a number of grammar and spelling issues as well as what appeared
to be some unintentionally pasted text.

This commit attempts to address these issues.

Signed-off-by: Lars Kellogg-Stedman <lars@oddbit.com>

Signed-off-by: Lars Kellogg-Stedman <lars@oddbit.com>
2022-10-07 15:35:30 -04:00
Denis Krivenko
b641828ea2 fix: Add missing statuses to MinIO Tenant health check (#10815)
Signed-off-by: dnskr <dnskrv88@gmail.com>

Signed-off-by: dnskr <dnskrv88@gmail.com>
2022-10-07 15:03:32 -04:00
Eddie Knight
b19fb7c514 chore: Added recommended permissions to github actions workflows (#10812)
* Added recommended permissions to 4 of 5 workflows

Signed-off-by: Eddie Knight <iv.eddieknight@gmail.com>

* Added release.yaml permissions... might need to add pagages:write

Signed-off-by: Eddie Knight <iv.eddieknight@gmail.com>

* Updated inline comments

Signed-off-by: Eddie Knight <iv.eddieknight@gmail.com>

Signed-off-by: Eddie Knight <iv.eddieknight@gmail.com>
2022-10-07 14:47:38 -04:00
argo-bot
4faaa02377 Bump version to 2.2.14 2022-10-05 17:02:26 +00:00
argo-bot
7ef987aef6 Bump version to 2.2.14 2022-10-05 17:02:10 +00:00
Michael Crenshaw
2da9044e5c chore: upgrade dex to v2.35.1 (#10797) (#10799)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-05 11:45:50 -04:00
argo-bot
c25f81cef4 Bump version to 2.2.13 2022-10-03 20:50:19 +00:00
argo-bot
a07a29dbb4 Bump version to 2.2.13 2022-10-03 20:50:08 +00:00
Michael Crenshaw
c4df950a58 chore: upgrade Dex to 2.35.0 (#10775)
* chore: upgrade dex to v2.35.0

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

* upgrade github workflow too

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

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-10-03 15:46:20 -04:00
Michael Crenshaw
05f6491358 chore: upgrade dex to v2.32.1-distroless (#10746)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2022-09-30 18:56:23 -04:00
JesseBot
3b37050047 docs: Add "Create Namespace" to sync options doc (#3490) (#10326)
* Add create namespace to the sync options doc

Signed-off-by: JesseBot <jessebot@linux.com>

* Update docs/user-guide/sync-options.md

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>

Signed-off-by: JesseBot <jessebot@linux.com>
Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
2022-08-17 15:12:49 -04:00
Michael Crenshaw
82ad3a8c3a docs: clusterResources in declarative cluster config (#10219)
* docs: clusterResources in declarative cluster config

Signed-off-by: CI <michael@crenshaw.dev>

* add article

Signed-off-by: CI <michael@crenshaw.dev>

Signed-off-by: CI <michael@crenshaw.dev>
2022-08-11 13:49:38 -04:00
argo-bot
fd74756aeb Bump version to 2.2.12 2022-07-29 14:39:29 +00:00
argo-bot
46622b0362 Bump version to 2.2.12 2022-07-29 14:39:15 +00:00
jannfis
014ab697fe chore: Remove deprecated K8s versions from test matrix
Signed-off-by: jannfis <jann@mistrust.net>
2022-07-29 07:41:02 +00:00
jannfis
890b6865f3 chore: Go mod tidy
Signed-off-by: jannfis <jann@mistrust.net>
2022-07-28 20:49:34 +00:00
jannfis
45d38a3c0e test: Remove circular symlinks from testdata (#9886)
* test: Remove circular symlinks from testdata

Signed-off-by: jannfis <jann@mistrust.net>

* Another test case

Signed-off-by: jannfis <jann@mistrust.net>

* Use defer for changing back to original workdir

Signed-off-by: jannfis <jann@mistrust.net>

* Abort the test on error in defer

Signed-off-by: jannfis <jann@mistrust.net>
2022-07-28 20:05:27 +00:00
jannfis
229830d737 test: Fix e2e tests for release-2.2 branch
Signed-off-by: jannfis <jann@mistrust.net>
2022-07-28 19:57:42 +00:00
jannfis
b1c6b960a4 fix: create serviceaccount token for v1.24 clusters (#9546)
* fix: create serviceaccount token for v1.24 clusters

Signed-off-by: Daniel Helfand <helfand.4@gmail.com>

* change create to get in err

Signed-off-by: Daniel Helfand <helfand.4@gmail.com>
2022-07-28 19:12:04 +00:00
Michael Crenshaw
7cd0a758fe chore: bump redoc vesion to avoid CVE-2021-23820 (#8604)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-07-27 16:45:44 -04:00
dependabot[bot]
a474dddc37 chore(deps): bump moment from 2.29.3 to 2.29.4 in /ui (#9897)
Bumps [moment](https://github.com/moment/moment) from 2.29.3 to 2.29.4.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.29.3...2.29.4)

Signed-off-by: CI <michael@crenshaw.dev>

---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-27 16:29:55 -04:00
Snyk bot
cb9052bc88 fix: upgrade moment from 2.29.2 to 2.29.3 (#9330)
Snyk has created this PR to upgrade moment from 2.29.2 to 2.29.3.

See this package in npm:

See this project in Snyk:
https://app.snyk.io/org/argoproj/project/d2931792-eef9-4d7c-b9d6-c0cbd2bd4dbe?utm_source=github&utm_medium=referral&page=upgrade-pr

Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 16:26:37 -04:00
Alexander Matyushentsev
a3b5b80ea7 chore: upgrade moment to latest version to fix CVE (#9005)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-07-27 16:21:04 -04:00
Michael Crenshaw
293c05ba3f chore: move dependencies to dev dependencies (#8541)
chore: move dependencies to dev dependencies (#8541)

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-07-27 15:51:11 -04:00
Michael Crenshaw
c00695f613 docs: add OpenSSH breaking change notes (#10104)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 15:28:58 -04:00
Michael Crenshaw
b378104777 fix: avoid CVE-2022-28948 (#10093)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 15:25:06 -04:00
Michael Crenshaw
d9fc07a309 chore: update parse-url (#10101)
* chore: upgrade parse-url

Signed-off-by: CI <michael@crenshaw.dev>

* edit a generated file, because that's smart

Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 15:00:37 -04:00
CI
8cd08af766 chore: fix codegen
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-27 09:26:02 -04:00
CI
3ab313b9f1 chore: fix codegen
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-26 16:04:39 -04:00
Michael Crenshaw
44d8cb8bed chore: upgrade base image to 22.04 (#10105)
Signed-off-by: douhunt <douhunt@protonmail.com>

Co-authored-by: douhunt <douhunt@protonmail.com>
Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

chore: update Kex-Algorithms (#9561)

* chore: update Kex-Algorithms

Signed-off-by: douhunt <douhunt@protonmail.com>

* sorted kex-algorithms

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

Co-authored-by: douhunt <douhunt@protonmail.com>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

chore upgrade base image for test containers Ubuntu:22.04 (#9563)

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

Co-authored-by: 34FathomBelow <34fathombelow@protonmail.com>
2022-07-26 14:53:40 -04:00
Michael Crenshaw
626f4c7d16 docs: simplify Docker toolchain docs (#9966) (#10006)
* docs: simplify Docker toolchain docs (#9966)

Signed-off-by: CI <michael@crenshaw.dev>

* to be or not to be

Signed-off-by: CI <michael@crenshaw.dev>

* pin dependencies to avoid absurdity

Signed-off-by: CI <michael@crenshaw.dev>
2022-07-26 14:07:26 -04:00
34FathomBelow
b9d3008334 chore: update redis to 6.2.7 avoid CVE-2022-30065/CVE-2022-2097 (#10068)
* chore: update redis to 6.2.7 avoid CVE-2022-30065/CVE-2022-2097

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

* use latest tag

Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-07-26 13:10:28 -04:00
Michael Crenshaw
b73d20a313 chore: upgrade Dex to 2.32.0 (#10036) (#10042)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-20 10:46:22 -04:00
34FathomBelow
191a99c952 chore: update haproxy to 2.0.29 for redis-ha (#10045)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-07-19 15:06:05 -04:00
CI
5fe9514d68 test: check for error messages from CI env (#9953)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-12 15:18:52 -04:00
argo-bot
aa3f3749f8 Bump version to 2.2.11 2022-07-12 16:04:32 +00:00
argo-bot
727e621f1e Bump version to 2.2.11 2022-07-12 16:04:15 +00:00
Michael Crenshaw
04ed9a4ceb Merge pull request from GHSA-7943-82jg-wmw5
* add tests to demonstrate issue

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

more

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

docs

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

settings tests

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

tests for OIDC handlers, consolidating test helpers

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

consolidate

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

consolidate

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

docs

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* fix log message

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-07-12 08:46:13 -04:00
Clive Jevons
0e83eda526 feat: enable specifying root ca for oidc (#6712)
When configuring an external OIDC provider which uses a private PKI
for its certificates it was not possible to properly verify the certificate
being served. Also, when using ArgoCD in insecure mode, e.g. when running
behind istio for providing mTLS, this resulted in errors.

Signed-off-by: Clive Jevons <clive@jevons-it.net>
2022-06-29 12:53:50 -04:00
Nicolas Fillot
4871daae6c [ArgoCD] Fixing webhook typo in case of error in GetManifests (#9671)
Signed-off-by: Nicolas Fillot <nfillot@weborama.com>

Co-authored-by: Nicolas Fillot <nfillot@weborama.com>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-23 09:26:55 -04:00
argo-bot
8db0e57b73 Bump version to 2.2.10 2022-06-21 16:27:37 +00:00
argo-bot
80a10d4185 Bump version to 2.2.10 2022-06-21 16:27:23 +00:00
Michael Crenshaw
29521a9aa4 chore: fix docs gen
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 10:46:49 -04:00
Michael Crenshaw
58cccd526e Merge pull request from GHSA-jhqp-vf4w-rpwq
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

defer instead of multiple close calls

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

oops

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

don't count jsonnet against max

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix codegen

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

add caveat about 300x ratio

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix versions

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix tests/lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 09:40:36 -04:00
Michael Crenshaw
265a64409e Merge pull request from GHSA-q4w5-4gq2-98vm
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 09:39:56 -04:00
Michael Crenshaw
1fe95747c4 Merge pull request from GHSA-2m7h-86qq-fp4v
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix references

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

use long enough state param for oauth2

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

typo

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

more entropy

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix test

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 09:39:01 -04:00
Michael Crenshaw
05e9079233 Merge pull request from GHSA-h4w9-6x78-8vrj
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 09:36:38 -04:00
Michael Crenshaw
fd42ba766d fix: missing Helm params (#9565) (#9566)
* fix: missing Helm params

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* use absolute paths, fix tests

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* fix race in test

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-14 22:25:05 -04:00
Michael Crenshaw
4040dee0ee test: directory app manifest generation (#9503)
* test: directory app manifest generation

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* git doesn't support empty dirs

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix bad cherry-pick

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-14 16:27:01 -04:00
Michael Crenshaw
845cfdee6f test: fix erroneous test change
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-13 18:00:09 -04:00
Michael Crenshaw
f4d17fff60 chore: eliminate go-mpatch dependency (#9045)
* chore: eliminate go-mpatch dependency

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: abstract out resource list function

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: don't exit the program in anything but the main function

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: better error messages

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: better error messages

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-13 17:58:56 -04:00
jannfis
a9238104c0 chore: Make unit tests run on platforms other than amd64 (#8995)
Signed-off-by: jannfis <jann@mistrust.net>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-13 17:54:52 -04:00
Alexander Matyushentsev
dc8785ee1b chore: remove obsolete repo-server unit test (#9559)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-06-13 17:54:31 -04:00
Tommaso Sardelli
ad778e87bb chore: upgrade golangci-lint to v1.46.2 (#9448)
* chore: upgrade golangci-lint to v1.46.2

Because:

* Installation of golangci-lint v1.45.2 is currently broken and fails
  silently due to a redacted dependency
  (https://github.com/blizzy78/varnamelen/issues/13)

This commit:

* Upgrades golangci-lint to v1.46.2

Signed-off-by: Tommaso Sardelli <lacapannadelloziotom@gmail.com>

* fix: lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* fix: lint

Signed-off-by: Tommaso Sardelli <lacapannadelloziotom@gmail.com>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-13 17:49:49 -04:00
Michael Crenshaw
273bc30a2a chore: update golangci-lint (#8988)
* chore: update golangci-lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-13 17:37:59 -04:00
argo-bot
38755a4c1e Bump version to 2.2.9 2022-05-18 11:55:29 +00:00
argo-bot
1c559fd7ba Bump version to 2.2.9 2022-05-18 11:55:16 +00:00
jannfis
0fc0d10a4e Merge pull request from GHSA-r642-gv9p-2wjj
Signed-off-by: jannfis <jann@mistrust.net>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-18 13:16:21 +02:00
Michael Crenshaw
5e767a4b9e Merge pull request from GHSA-6gcg-hp2x-q54h
* fix: do not allow symlinks from directory-type applications

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: fix imports and unnecessary parameters

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: use t.TempDir for simpler tests

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* address comments

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-18 13:13:41 +02:00
jannfis
5cee8f84e3 Merge pull request from GHSA-xmg8-99r8-jc2j
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-18 13:06:31 +02:00
argo-bot
93d588c86e Bump version to 2.2.8 2022-03-23 00:18:30 +00:00
argo-bot
377eb799ff Bump version to 2.2.8 2022-03-23 00:18:11 +00:00
Alexander Matyushentsev
ff11b58816 fix: fix broken e2e test (#8862)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-03-22 14:59:46 -07:00
Alexander Matyushentsev
b1625eb8cc Merge pull request from GHSA-2f5v-8r3f-8pww
* fix: application resource APIs must enforce project restrictions

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* Fix unit tests

Signed-off-by: jannfis <jann@mistrust.net>

Co-authored-by: jannfis <jann@mistrust.net>
2022-03-22 10:57:31 -07:00
argo-bot
b8e154f767 Bump version to 2.2.7 2022-03-09 00:58:23 +00:00
argo-bot
c4ab0938f9 Bump version to 2.2.7 2022-03-09 00:58:07 +00:00
Alexander Matyushentsev
3fe5753f33 fix: correct jsonnet paths resolution (#8721)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-03-08 15:59:33 -08:00
argo-bot
2e550c3f07 Bump version to 2.2.6 2022-03-06 05:50:51 +00:00
argo-bot
d841aae433 Bump version to 2.2.6 2022-03-06 05:50:37 +00:00
Alexander Matyushentsev
b570ab8b17 fix: prevent file traversal using helm file values param and application details api (#8606)
* fix: prevent file traversal using helm file values param and application details api

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* apply reviewer notes: move resolve.go into separate package; use uuid to generate random file

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-03-03 13:37:33 -08:00
Jesse Suen
8c82655c66 fix!: enforce app create/update privileges when getting repo details (#8558)
Signed-off-by: Jesse Suen <jesse@akuity.io>
2022-03-03 13:03:20 -08:00
Alexander Matyushentsev
a9e1040314 feat: support custom helm values file schemes (#8535)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-03-03 12:55:07 -08:00
Jesse Suen
6f4bbb5a55 docs: add security documentation related to git repositories (#8463)
Signed-off-by: Jesse Suen <jesse@akuity.io>
2022-02-11 13:49:01 -08:00
argo-bot
8f981ccfcf Bump version to 2.2.5 2022-02-05 01:26:23 +00:00
argo-bot
dbf043e6f1 Bump version to 2.2.5 2022-02-05 01:26:11 +00:00
jannfis
f6501652c4 fix: Resolve symlinked value files correctly (#8387)
* fix: Resolve symlinked value files correctly

Signed-off-by: jannfis <jann@mistrust.net>

* fix: Resolve symlinked value files correctly

Signed-off-by: jannfis <jann@mistrust.net>
2022-02-04 15:11:07 -08:00
argo-bot
78d749ec88 Bump version to 2.2.4 2022-02-03 20:33:05 +00:00
argo-bot
8217d70085 Bump version to 2.2.4 2022-02-03 20:32:49 +00:00
jannfis
02e61797b3 Merge pull request from GHSA-63qx-x74g-jcr7
Signed-off-by: jannfis <jann@mistrust.net>
2022-02-03 20:37:46 +01:00
jannfis
998f063a80 chore: upgrade dex to v2.30.2 (backport of #8237) (#8257)
Signed-off-by: jannfis <jann@mistrust.net>

Co-authored-by: Alexander Matyushentsev <Alexander_Matyushentsev@intuit.com>
2022-01-24 10:17:41 -08:00
argo-bot
987f6659b8 Bump version to 2.2.3 2022-01-18 17:45:46 +00:00
argo-bot
e099a6a851 Bump version to 2.2.3 2022-01-18 17:45:31 +00:00
Alexander Matyushentsev
afbd59ba63 refactor: introduce 'byClusterName' secret index to speedup cluster server URL lookup (#8133)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-01-17 19:25:00 -08:00
pasha-codefresh
b1e3a07d92 fix: application exist panic when execute api call (#8188)
fix: application exist panic when execute api call (#8188)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2022-01-15 09:05:19 +01:00
Ishita Sequeira
c3144c0059 fix: route health check stuck in 'Progressing' (#8170)
Signed-off-by: ishitasequeira <isequeir@redhat.com>
2022-01-14 09:03:39 +00:00
jannfis
33547f149b chore: Update to Redis 6.2.4 (#8157) (#8158)
Signed-off-by: jannfis <jann@mistrust.net>
2022-01-12 13:45:56 -08:00
Alexander Matyushentsev
06dc9aa836 docs: update roadmap document with v2.2 release changes (#8089)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-01-05 09:21:41 -08:00
argo-bot
03b17e0233 Bump version to 2.2.2 2022-01-01 06:18:52 +00:00
argo-bot
d5909f7168 Bump version to 2.2.2 2022-01-01 06:18:35 +00:00
pasha-codefresh
7d0d665747 fix: issue with project scoped resources (#8048)
fix: issue with project scoped resources (#8048)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-30 09:12:45 -08:00
Michael Crenshaw
834a102c09 chore: escape proj in regex (#7985)
* chore: escape proj in regex

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: test normal cases

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: typo

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2021-12-30 09:12:40 -08:00
plakyda-codefresh
4bcd8cf733 fix: Default value for retry validation #8055 (#8064)
fix: Default value for retry validation #8055 (#8064)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-12-30 09:04:56 -08:00
pasha-codefresh
a069c602dc fix: sync window panel is crashed if resource name not contain letters (#8053)
fix: sync window panel is crashed if resource name not contain letters (#8053)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-29 11:08:52 -08:00
Alexander Matyushentsev
e309ceebac fix: upgrade github.com/argoproj/gitops-engine to v0.5.2
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-22 13:45:57 -08:00
plakyda-codefresh
4a7f0bbfd8 fix: retry disabled text (#8004)
fix: retry disabled text (#8004)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-12-22 11:40:30 -08:00
Niklas Steiner
28a54bf2a2 fix: Opening app details shows UI error on some apps (#8016) (#8019)
Signed-off-by: Niklas Steiner <niklas@sbg.at>
2021-12-22 11:17:50 -08:00
Alexander Matyushentsev
e209426a7e fix: correctly handle project field during partial cluster update (#7994)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-21 11:10:39 -08:00
May Zhang
06a95f86ce fix: Cluster API does not support updating labels and annotations (#7901)
Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-12-21 11:10:32 -08:00
argo-bot
122ecefc3a Bump version to 2.2.1 2021-12-17 01:23:50 +00:00
argo-bot
004d73ce92 Bump version to 2.2.1 2021-12-17 01:23:35 +00:00
Alexander Matyushentsev
81e1a58328 fix: resource details page crashes when resource is not deployed and hide managed fields is selected (#7971)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-16 17:21:54 -08:00
pasha-codefresh
84f949ff17 fix: issue with headless installation (#7958)
fix: issue with headless installation (#7958)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-16 10:20:06 -08:00
jomenxiao
a7e7f32a0f fix nil point (#7905)
Signed-off-by: jomenxiao <jomenxiao@gmail.com>
2021-12-16 08:24:54 -08:00
argo-bot
6da92a8e81 Bump version to 2.2.0 2021-12-14 18:01:04 +00:00
argo-bot
d5368f5714 Bump version to 2.2.0 2021-12-14 18:00:47 +00:00
Jesse Suen
25cfb27d51 feat: update gitops-engine to v0.5.1 and add additional tuning options (#7917)
Signed-off-by: Jesse Suen <jesse@akuity.io>
2021-12-13 18:51:41 -08:00
Alexander Matyushentsev
47d23e1f07 fix: resource tracking normalization should not always drop old label (#7911)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-13 10:16:00 -08:00
Alexander Matyushentsev
1dc14dc172 fix: resource tracking normalization shuold drop empty labels (#7909)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-11 11:17:22 -08:00
Alexander Matyushentsev
5c06333914 fix: improve migration from label to annotation tracking (#7899)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-10 16:15:37 -08:00
jannfis
656bee1402 chore: Upgrade to golang 1.16.11 (#7874)
* chore: Upgrade to golang 1.16.11

Signed-off-by: jannfis <jann@mistrust.net>

* Missed this one

Signed-off-by: jannfis <jann@mistrust.net>
2021-12-09 07:04:49 +00:00
pasha-codefresh
2a30c92a7e fix: Resource tracking typo (#7873)
* move projects

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

* Revert "move projects"

This reverts commit d0e21353

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

* fix typo in resource tracking

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-08 09:59:05 -08:00
pasha-codefresh
6a1fec9d33 fix: issue with keepalive (#7861)
* fix issue with keepalive

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

* empty commit

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-08 09:58:43 -08:00
Alexander Matyushentsev
0faeeb843d refactor: add indexes to secret informers to speedup settings parsing (#7882)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-07 14:15:55 -08:00
Saumeya Katyal
48bdabad1a fix: css change for clear button in filters (#7868)
Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2021-12-07 10:02:34 -08:00
Alexander Matyushentsev
c3fd7f5f2d fix: fix UI build failure: use correct monaco editor setting name (#7856)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-03 14:32:37 -08:00
Alexander Matyushentsev
3f75a7faa3 feat: allow hiding managed fields in resource manifest viewer (#7855)
* fix: remove double scroll in editor

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* feat: add Hide Managed Fields checkbox

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-03 13:46:43 -08:00
Alexander Matyushentsev
0f14657301 refactor: avoid loading project in frequently executed controller methods (#7853)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-03 13:20:46 -08:00
Chetan Banavikalmutt
02768367b5 fix: admin dashboard doesn't use the right context (#7826)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-12-02 22:23:11 -08:00
Jesse Suen
3b628b3af8 fix: env vars to tune cluster cache were broken (#7779)
Signed-off-by: Jesse Suen <jesse@akuity.io>
2021-11-30 13:49:21 -08:00
Alexander Matyushentsev
d8d2920eff refactor: upgrade casbin to latest stable version (v2.39.1) (#7802)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-30 13:48:42 -08:00
Alexander Matyushentsev
1a72853ca3 refactor: use cached project while calculating resource tree (#7747)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-19 13:15:24 -08:00
Alexander Matyushentsev
5354e7d823 chore: use gitops-engine v0.5.0
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-19 13:14:53 -08:00
Mark Sarcevicz
34d8f12c99 Fix: Kuberenetes manifest to have new Github.com ssh known host keys for ArgoCD deployments (#7722)
* Kuberenetes manifest to have new ssh known host keys for ArgoCD deployments

https://github.blog/2021-09-01-improving-git-protocol-security-github/
Signed-off-by: smark88 <msarcevicz@influxdata.com>

* added to docs

Signed-off-by: smark88 <msarcevicz@influxdata.com>

* fix: regenerate manifests using 'make manifests'

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-17 13:33:44 -08:00
argo-bot
8840688e6e Bump version to 2.2.0-rc1 2021-11-12 16:25:15 +00:00
argo-bot
c081ef0b00 Bump version to 2.2.0-rc1 2021-11-12 16:24:57 +00:00
Alexander Matyushentsev
caa246a38d refactor: allow using own config maps to register the cmp plugins instead of 'argocd-cmp-cm' (#7677)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-10 14:57:14 -08:00
pasha-codefresh
ebf27dea3e feat: Improve unit test coverage for util/app/app.go (#7641)
feat: Improve unit test coverage for util/app/app.go (#7641)
Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-11-10 13:41:04 -08:00
Yuan Tang
98fcb417eb build: Pin Python to 3.9.8 to work with arch x64 on GitHub Actions (#7678)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-11-10 12:44:48 -08:00
Yuan Tang
a3517d594b docs: Update CI troubleshooting guide on build steps (#7639)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-11-08 09:49:00 -08:00
Yuan Tang
e0c9827a37 chore: Correct function names in docstring in server/project/project.go (#7650)
* docs: Correct function names in docstring in server/project/project.go

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-11-08 09:48:28 -08:00
May Zhang
375e27bd7a Feat: cmp server (#6585)
* feat: config management plugin enhancement (#6585)

Signed-off-by: kshamajain99 <kshamajain99@gmail.com>
Signed-off-by: May Zhang <may_zhang@intuit.com>
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-08 09:47:10 -08:00
Yuan Tang
46fdb6f364 fix: Add missing passCredentials in swagger.json (#7640)
* fix: Add missing passCredentials in swagger.json

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

* Retrigger CI pipeline

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-11-08 08:49:28 -08:00
pasha-codefresh
2e84638827 fix: timezone fix test (#7643)
* group diff should set resource id use new interface

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

* remove redundant

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

* remove eof

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

* sync window broken tests

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

* sync window broken tests

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-11-07 19:08:02 +01:00
Yuan Tang
0a64781616 build: Add Helm v3.7.1 checksum for arm64 to fix build on Apple M1 (#7635)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-11-05 14:39:57 -07:00
Yuan Tang
43a29e6b2d docs: Add -s to sign off empty commits that retriggers CI (#7628)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-11-05 14:39:42 -07:00
Leonardo Luz Almeida
b77f947e1d fix: TestRepository should assume git by default (#7630)
* fix: TestRepository should assume git by default

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>

* fix proto diff

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2021-11-05 13:51:02 -07:00
Leonardo Luz Almeida
dc24380065 chore: refactoring gpg test data embeding it in go code (#7625)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2021-11-05 08:45:14 +01:00
Leonardo Luz Almeida
b0278c4493 fix: handle repo creation when secret does not have proper label (#7617)
* fix: handle repo creation when secret does not have proper label

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>

* address code review comments with linters

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>

* remove gpg test data refactoring code

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2021-11-04 17:14:53 -07:00
Alexander Matyushentsev
1431e04b90 fix: add missing await on cluster list page (#7621)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-04 17:14:25 -07:00
Alexander Matyushentsev
5bb45435e0 docs: more post v2.3 roadmap items (#7509)
* docs: more post v2.3 roadmap items

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* replace multiple sources with helm + repo; add app dependencies feature

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-04 09:36:48 -07:00
pasha-codefresh
691b77ff9e feat: split yamls (#7595)
feat: split yamls (#7595)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-11-04 08:33:08 -07:00
Yuan Tang
b52793ab07 docs: Add link to awesome-argo for more resources (#7619)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-11-04 08:25:34 -07:00
Chandler Wilkerson
fc13eda8d6 feat: Add KubeVirt custom health checks (#7176)
Signed-off-by: cwilkers <cwilkers@redhat.com>
2021-11-04 08:23:48 -07:00
Ishita Sequeira
ff45418948 feat: add timezone option to sync window (#7442)
* feat: add timezone option to sync window

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* Retrigger CI pipeline

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* Addressed PR comments

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* feat: add timezone option to sync window

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* Addressed PR comments

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* Addressed PR comments

Signed-off-by: ishitasequeira <isequeir@redhat.com>
2021-11-04 08:22:24 +01:00
Leonardo Luz Almeida
0d4e40ed6a fix: Address issue during diff when secret data is nil (#7603)
* fix: update gitops-engine to latest + log improvements

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>

* run go mod tidy

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2021-11-03 12:46:05 -07:00
pasha-codefresh
fe3cc7218c feat: cache argo cd rbac (#7587)
feat: cache argo cd rbac (#7587)

Part of: #4296

Signed-off-by: Jan Jansen <jan.jansen@gdata.de>
Signed-off-by: pashavictorovich <pavel@codefresh.io>
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-03 11:28:52 -07:00
Alexander Matyushentsev
513d8a4ae0 fix: fix invalid resource icons (#7610)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-03 08:19:06 +01:00
plakyda-codefresh
6036e9b4c9 feat: remove cluster confirmation (#7602)
feat: remove cluster confirmation (#7602)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-11-02 11:37:59 -07:00
Leonardo Luz Almeida
8a6b759c4a fix: address edge cases with sync windows (#7517)
* fix: address edge cases with sync windows

Signed-off-by: Leonardo Luz Almeida <leoluz@users.noreply.github.com>

* trigger build

Signed-off-by: Leonardo Luz Almeida <leoluz@users.noreply.github.com>

* trigger build

Signed-off-by: Leonardo Luz Almeida <leoluz@users.noreply.github.com>
2021-11-02 08:48:00 -07:00
Saumeya Katyal
c2b3e74089 feat: autocompletion for resource shortnames (#7466)
* feat: autocompletion for resource shortnames

Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2021-11-02 08:33:51 -07:00
John Keates
8b10b64dfa Update USERS.md (#7589)
Add Wehkamp as a argocd user.
2021-11-01 11:31:57 -07:00
jphelton
e5c34f472e fix: argocd-dex now merges existing dex.config.oauth2 block instead of overwriting (#7583)
* fix: argocd-dex now merges existing dex.config.oauth2 block with autogenerated block

Signed-off-by: Joshua Helton <jdoghelton@gmail.com>
Signed-off-by: jphelton <jdoghelton@gmail.com>

* simplified statement based on PR feedback

Signed-off-by: Joshua Helton <jdoghelton@gmail.com>
2021-11-01 11:30:42 -07:00
Ben Ye
49b71522c4 feat: support pprof endpoints (#7533)
Signed-off-by: Ben Ye <ben.ye@bytedance.com>
2021-11-01 10:49:43 -07:00
Alexander Matyushentsev
7a6b2ffe56 fix: controller fails to connect to cluster using exec auth provider (#7586)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-11-01 10:02:57 +01:00
jannfis
c7792522c5 fix: Improve user experience for update-password CLI command (#7581)
* fix: Improve user experience for update-password CLI command

Signed-off-by: jannfis <jann@mistrust.net>

* Regenerate CLI docs

Signed-off-by: jannfis <jann@mistrust.net>
2021-10-30 10:30:58 +02:00
Simon Ninon
f4fd836a1b fix: return a codes.NotFound error when trying to get a non-existent repository (#7548)
* fix: return a codes.NotFound error when trying to get a non-existent repository

Signed-off-by: Simon Ninon <simon.ninon@gmail.com>

* move s.db.RepositoryExists call after the permission check

Signed-off-by: Simon Ninon <simon.ninon@gmail.com>

* update ArgoDB mock and add unit tests

Signed-off-by: Simon Ninon <simon.ninon@gmail.com>
2021-10-30 10:11:19 +02:00
Mathieu Parent
2770c690a5 Update to Helm v3.7.1, allow to pass credentials and new OCI support (#7249)
* chore: Update Helm to v3.7.1

Signed-off-by: Mathieu Parent <math.parent@gmail.com>
2021-10-29 17:48:27 -07:00
Nills Franssens
5b914750a4 docs: remove mention of ksonnet in basics (#7567)
Signed-off-by: Nills Franssens <nills.franssens@gmail.com>
2021-10-29 10:46:05 -07:00
Yuan Tang
43cba9cc0b docs: Remove misleading minus sign after version number (#7559)
* docs: Remove unnecessary version numbers in high_availability.md

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

* Fix

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-10-28 15:49:32 -07:00
Alex Stockinger
0dbffb8557 Clarify key/cert encoding in cluster credentials (#7545)
Fixes #7544

Signed-off-by: Alex Stockinger <mail@alexstockinger.de>
2021-10-28 13:02:19 -07:00
pasha-codefresh
7b0cf773cc feat: Replace option in cli, sync command (#7526)
feat: Replace option in cli, sync command (#7526)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-28 13:01:32 -07:00
Denis Lavrushko
d3bec0faaa docs: Added iits-consulting to the Users.md (#7566)
* added IITS organizations to the USERS.md file

Signed-off-by: Denis Lavrushko <denis.lavrushko@iits-consulting.de>
2021-10-28 12:21:09 -07:00
Saumeya Katyal
7750f579bb docs: toolchain doc minor command update (#7568)
Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2021-10-28 12:16:54 -07:00
Jeff Maaks
5aeb113968 Update private-repositories.md -- add Azure Repos (#7040)
Added a link to the documentation for creating an access token on Azure Repos
2021-10-28 12:11:40 -07:00
Engin Diri
4522a88289 feat: Show "Open application" link in Application details list view (#7455)
Signed-off-by: Engin Diri <engin.diri@mail.schwarz>
2021-10-28 12:04:29 -07:00
Ben Ye
5f4ecf1ef2 feat: improve cluster info fetch from secret by reducing unnecessary unmarshalling (#7530)
Signed-off-by: Ben Ye <ben.ye@bytedance.com>
2021-10-28 11:11:25 -07:00
Masakinpo
7ced59f346 chore: fix typo in docs/operator-manual/high_availability.md (#7551)
* fix typo in docs/operator-manual/high_availability.md

Signed-off-by: Masakinpo <masakinpo.jp@gmail.com>

* chore: fix typo in docs/operator-manual/high_availability.md

Signed-off-by: Masakinpo <masakinpo.jp@gmail.com>
2021-10-27 10:44:43 -07:00
Omer Kahani
a912611b7a Adding Snyk (#7537)
Signed-off-by: Omer Kahani <kahaniomer@gmail.com>
2021-10-25 18:19:21 -07:00
Alexander Matyushentsev
a21b0363e3 fix: Argo CD should provide apiversion and kinds to 'helm template' command (#7519)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-25 16:52:19 -07:00
Viktor Farcic
07b8a1f63c docs: Video about Image Updater (#7547)
Signed-off-by: Viktor Farcic <viktor@farcic.com>
2021-10-25 20:23:57 +02:00
Keith Chong
1804d771c7 feat: Add banner position option #7313 (#7462)
Signed-off-by: Keith Chong <kykchong@redhat.com>
2021-10-23 11:09:17 -07:00
kiran
7fe8e5ff37 Added paytmlabs argocd blog in readme (#7529)
Signed-off-by: kiran <kiran.sundaravarathan@paytm.com>

Co-authored-by: kiran <kiran.sundaravarathan@paytm.com>
2021-10-22 17:26:47 -07:00
pasha-codefresh
b8510f35f1 fix: mkdocs doesnt work with 3.10.0 python (#7518)
fix: mkdocs doesnt work with 3.10.0 python (#7518)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-21 15:46:31 -07:00
pasha-codefresh
aa6aed3c04 feat: max cookie length (#7515)
feat: max cookie length (#7515)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-21 14:37:39 -07:00
Snyk bot
d6d620e98c fix: upgrade @types/react-helmet from 5.0.8 to 5.0.17 (#7473)
Snyk has created this PR to upgrade @types/react-helmet from 5.0.8 to 5.0.17.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/argoproj/project/e257be49-1bf5-455e-a11b-cdab3dbef067?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-10-21 11:13:23 -07:00
Michael Crenshaw
3e17a69df3 chore: default to no gpg for Procfile - avoids missing temp dir failure (#7506)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

Co-authored-by: Michael Crenshaw <michael_crenshaw@intuit.com>
2021-10-21 11:12:47 -07:00
Alexander Matyushentsev
da63fb26d1 fix: don't use revision caching during app creation (#7508)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-20 20:24:14 -07:00
Mohammad Yosefpor
401b266235 fix: supporting OCI dependencies. Fixes #6062 (#6994)
* fix: supporting OCI dependencies

Signed-off-by: Mohammad Yosefpor <myusefpur@gmail.com>

* chore: add org to USERS.md

Signed-off-by: Mohammad Yosefpor <myusefpur@gmail.com>

* fix(tests): remove invalid TestRepoPermission e2e test

Signed-off-by: Mohammad Yosefpor <myusefpur@gmail.com>
2021-10-20 18:22:37 -07:00
Alexander Matyushentsev
f46ac844b8 chore: add pasha-codefresh to reviewers list (#7503)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-20 13:09:13 -07:00
May Zhang
046840dcf7 fix: docker image for ui-test (#7461)
fix: docker image for ui-test (#7461)

Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-10-20 11:34:28 -07:00
Atsushin
d460f844a4 fix: Fix Color Support in Logs (#7476)
Signed-off-by: Atsushi Neki <nekiaiken@gmail.com>
2021-10-20 11:31:24 -07:00
Leonardo Luz Almeida
970bb80b28 feat: add new sync option to fail if finds shared resources (#7444)
* feat: add new sync option to fail if finds shared resources

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>

* docs: add docs for FailOnSharedResource sync option

Signed-off-by: Leonardo Luz Almeida <leoluz@users.noreply.github.com>
2021-10-20 08:06:41 -07:00
Alexander Matyushentsev
81e801d8ee fix: Invalid memory address or nil pointer dereference in processRequestedAppOperation (#7501)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-20 08:03:55 -07:00
Alexander Matyushentsev
872eff292b fix: Operation has completed with phase: Running (#7482)
* fix: Operation has completed with phase: Running

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-19 17:16:31 -07:00
Julian Strobl
00874af5f2 fix: client certificate ignored during (re)login (#7423)
fix: client certificate ignored during (re)login (#7423)

Signed-off-by: Julian Strobl <julian.strobl@telekom.de>

Co-authored-by: Julian Strobl <julian.strobl@telekom.de>
2021-10-19 13:12:35 -07:00
Hritik Gupta
ad97ed52d5 doc: fixed content in toolchain guide (#7470)
doc: fixed content in toolchain guide (#7470)

Signed-off-by: hgupta3 <hritik_gupta@intuit.com>
2021-10-19 13:08:41 -07:00
Alexander Matyushentsev
7ea35924c9 fix: Application status panel shows Syncing instead of Deleting (#7486)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-19 10:30:09 -07:00
Byungjin Park (Claud)
c7074fe67a docs: Add KarrotPay to Users (#7467)
Signed-off-by: Byungjin Park <posquit0.bj@gmail.com>
2021-10-19 10:13:27 -07:00
jannfis
9a11790df2 fix: Allow plugins to lock repository at top-level to prevent git races (#6223)
* fix: Allow plugins to lock complete repository

Signed-off-by: jannfis <jann@mistrust.net>

* Add some documentation

Signed-off-by: jannfis <jann@mistrust.net>

* Adapt documentation

Signed-off-by: jannfis <jann@mistrust.net>

* Codegen

Signed-off-by: jannfis <jann@mistrust.net>

* Update codegen

Signed-off-by: jannfis <jann@mistrust.net>

* Update codegen

Signed-off-by: jannfis <jann@mistrust.net>
2021-10-19 18:51:59 +02:00
Yuan Tang
695699d08e docs: Add Akuity to the list of users (#7480)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-10-19 08:20:32 -07:00
Álvaro González
374965a606 docs: add a google warning and fix some formats (#7340)
Signed-off-by: alvarogonzalez-packlink <alvarogonzalez@packlink.com>
2021-10-19 01:36:59 -07:00
pasha-codefresh
ddc9f56d05 feat: Cluster name as part of sync (#7394)
feat: Cluster name as part of sync (#7394)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-18 18:44:54 -07:00
pasha-codefresh
3312dc0037 feat: Resource id tracking method doc (#7468)
feat: Resource id tracking method doc (#7468)
Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-18 18:44:08 -07:00
pasha-codefresh
67dd012b87 feat: add cluster name UI (#7409)
* group diff should set resource id use new interface

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

* add cluster destination should support name

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-18 13:03:49 -07:00
Leonardo Luz Almeida
10bb1c4e1f docs: add remaining metric docs (#7469)
Signed-off-by: Leonardo Luz Almeida <leoluz@users.noreply.github.com>
2021-10-18 10:10:34 -07:00
ChangZhuo Chen (陳昌倬)
f3730da01e fix: Fix typo in SparkApplication health check script (#7433) (#7434)
Closes: #7433

Signed-off-by: ChangZhuo Chen (陳昌倬) <czchen@czchen.org>
2021-10-17 22:24:42 -07:00
Snyk bot
d8f6ee2d72 fix: upgrade @types/react-dom from 16.8.5 to 16.9.14 (#7400)
Snyk has created this PR to upgrade @types/react-dom from 16.8.5 to 16.9.14.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/argoproj/project/e257be49-1bf5-455e-a11b-cdab3dbef067?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-10-17 20:35:07 -07:00
Leonardo Luz Almeida
b5d1433a1f Fix argocd_cluster_connection_status metric (#7419)
* bug: fix argocd_cluster_connection_status metric + docs

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2021-10-17 19:58:02 -07:00
Vaibhav Thakur
83ff035df7 Add Tigera to USERS.md (#7435)
Signed-off-by: Vaibhav Thakur <vaibhav@tigera.io>

Co-authored-by: Vaibhav Thakur <vaibhav@tigera.io>
2021-10-17 11:50:02 -07:00
jiraguha
1d4b91efa2 Add Rise the money app for teens to USERS.md (#7465)
Signed-off-by: jpiraguha <jiraguha@gmail.com>
2021-10-17 11:39:43 -07:00
May Zhang
43bcbfb093 fix: makeslice: cap out of range (#7463)
Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-10-17 10:43:14 -07:00
May Zhang
f0cd21a9f3 fix: invalid memory address or nil pointer dereference during cluster… (#7445)
Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-10-16 21:57:39 -07:00
Guy Elia
d7d8fe3da2 Add BigPanda to USERS.md (#7416)
Add BigPanda as an ArgoCD user
2021-10-12 10:00:51 -07:00
Assel Meher
c80c1d4f95 fix: fix parameter name when the value is a list (#7360) (#7362)
* fix: #7360

Signed-off-by: Assel Meher <asselmeher@gmail.com>

* fix assert in tests

Signed-off-by: Assel Meher <asselmeher@gmail.com>
2021-10-12 09:50:50 -07:00
Alexander Krantz
6644cbe452 fix: prevent displayed namespace from being undefined (#7401)
Signed-off-by: Alex Krantz <alex@krantz.dev>
2021-10-12 08:28:24 -07:00
Regina Scott
ae02bc27fc feat: add hide toggle for health status bar (#7153)
Signed-off-by: Regina Scott <rescott@redhat.com>
2021-10-11 14:41:48 -07:00
Mustafa
5faea8f339 docs: Append echo to kubectl in getting_started.md (#7403)
Add echo to the end of the kubectl command to fetch initial admin secrets so that '%' new line character is not printed at the end of the secret.

Signed-off-by: mustafa89 <mustafa.mujahid@outlook.com>

Co-authored-by: Mustafa Mujahid <mustafa.mujahid@tradebyte.com>
2021-10-11 22:49:06 +02:00
pasha-codefresh
678d35d850 feat: project destination cli (#7407)
feat: project destination cli (#7407)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-11 06:42:47 -07:00
c1_zh
363e1d2d49 feat: Make Casbin matcher configurable on runtime(globMatch(default) or RegexMatch) (#7165)
* feat: Make Casbin matcher configurable on runtime(globMatch(default) or RegexMatch)

Signed-off-by: cezhang <c1zhang.dev@gmail.com>
2021-10-09 12:01:09 -07:00
Alexander Matyushentsev
b2c70df619 docs: update v2.3+ roadmap (#7353)
* docs: update v2.3+ roadmap

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* Address reviewer notes: Add 'Merge Argo CD Image Updater into Argo CD' and 'Multi-tenancy improvements'

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-08 15:46:15 -07:00
May Zhang
3c874ae065 fix: Utilize a backoff for git retried operations (#7395)
* fix: git retry duration

Signed-off-by: May Zhang <may_zhang@intuit.com>

* fix: adjust default values

Signed-off-by: May Zhang <may_zhang@intuit.com>

* fix: adjust default values

Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-10-08 14:00:09 -07:00
Jan-Otto Kröpke
4dd570eb11 docs: Kustomize load_restrictor -> load-restrictor (#7358)
Signed-off-by: Jan-Otto Kröpke <joe@adorsys.de>
2021-10-08 11:56:05 -07:00
Chetan Banavikalmutt
1bc231dd99 fix: failing automated UI smoke tests (#7392)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-10-08 11:49:00 -07:00
Hritik Gupta
8a8373faba feat(ui): Ability to view previous container logs in log viewer (#7393)
feat(ui): Ability to view previous container logs in log viewer (#7393)

Signed-off-by: hgupta3 <hritik_gupta@intuit.com>
2021-10-08 11:33:26 -07:00
Leonardo Luz Almeida
384f5b2bae Expose Application labels in prometheus metric (#7374)
Expose Application labels in prometheus metric (#7374)

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2021-10-08 10:15:51 -07:00
pasha-codefresh
b0736219b6 feat: Resources should be normalized in order to prevent our of sync during migration (#7388)
feat: Resources should be normalized in order to prevent our of sync during migration (#7388)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-07 09:51:29 -07:00
Hrittik Roy
4399348ae5 docs: Add p3r to Users.md (#7346)
docs: Add p3r to Users.md (#7346)

* Update USERS.md

* Add p3r to Users.md

Signed-off-by: GitHub <noreply@github.com>

* Update USERS.md

Signed-off-by: GitHub <noreply@github.com>
2021-10-07 09:49:39 -07:00
Chetan Banavikalmutt
df5cce866f fix: unable to read jqPathExpressions (#7375)
The commit introduces the following changes:
1. Update the admin settings resource-overrides CLI to work with jqPathExpressions
2. Allow jqPathExpressions to be set from the UI

Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-10-06 09:59:09 -07:00
pasha-codefresh
07eeddf5f1 feat: group diff should set resource id use new interface (#7381)
feat: group diff should set resource id use new interface (#7381)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-06 09:08:20 -07:00
Chetan Banavikalmutt
0c757534ed fix: remove misleading Helm labels from Redis resources in HA mode (#7368)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-10-05 13:00:26 +02:00
Chetan Banavikalmutt
d8d7b30f58 fix: username is required with access token (#7359)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-10-04 14:58:16 -07:00
Alexander Matyushentsev
9d88e614cd fix: creating JWT token fails (#7366)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-10-04 14:43:49 -07:00
Fabiano Arruda
4e025838c0 Update USERS.md (#7348) 2021-10-04 09:49:15 -07:00
pasha-codefresh
d0c6280d38 feat: change annotation format (#7345)
* change annotation format

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-04 09:48:51 -07:00
Keith Chong
e084a110e4 feat: Allow Banner to be non-closable #7261 (#7312)
Signed-off-by: Keith Chong <kykchong@redhat.com>
2021-10-04 09:45:13 -07:00
pasha-codefresh
df7e5ffd96 feat: annotation-label tracking method (#7342)
feat: annotation-label tracking method (#7342)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-03 16:08:51 -07:00
Oleksandr Saulyak
6f8b10c324 fix: updated argo-ui package with fixes for #7192 / #7262 (#7344)
Signed-off-by: oleksandr-codefresh <oleksandr.saulyak@codefresh.io>
2021-10-02 10:50:32 -07:00
Jille Timmermans
eb70a1e3fa docs: Add an example for setting up Helm charts with GitOps (#7060)
Took me embarrassingly long to figure out.

Signed-off-by: Jille Timmermans <jille@quis.cx>
2021-10-01 11:18:30 -07:00
plakyda-codefresh
35bd9e1ed6 fix: retry options in app details modal (#7329)
fix: retry options in app details modal (#7329)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-10-01 10:24:46 -07:00
Matt Pursley
778be231b9 fix: a few typos in kustomize.md (#7334)
Signed-off-by: Matt Pursley <mattpursley@improbable.io>
2021-10-01 10:17:47 -07:00
Abhishek Veeramalla
d790e96aa9 fix: Retry with exponential backoff result in time to wait of zero(#7173) (#7339)
* fix: Retry with exponential backoff result in time to wait of zero(#7173)

Signed-off-by: iam-veeramalla <abhishek.veeramalla@gmail.com>

* fix issue reported by golintci

Signed-off-by: iam-veeramalla <abhishek.veeramalla@gmail.com>
2021-10-01 10:02:44 -07:00
Saumeya Katyal
a6039e1be9 fix: add url check and wrapping for commit msg field (#7218)
* fix: add url check and wrapping for commit msg field

Signed-off-by: saumeya <saumeyakatyal@gmail.com>

* move url regex to util

lint check

Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2021-10-01 09:23:49 -07:00
pasha-codefresh
3d4deeb4f0 fix: compare app state (#7341)
* fix compare app state

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-10-01 09:18:01 -07:00
pasha-codefresh
ebd87b77ed feat: improve sync logic (#7328)
feat: improve sync logic (#7328)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-30 14:49:29 -07:00
Yuan Tang
31b2cbee70 chore: More informative error message when redirect URL is invalid (#7331)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-09-30 13:29:12 -07:00
pasha-codefresh
a2677f5537 fix: Rm browser history (#7327)
fix: Rm browser history (#7327)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-30 13:25:46 -07:00
Álvaro González
65d669565b docs: configuring Google OIDC and Google groups for RBAC (#7308)
Signed-off-by: alvarogonzalez-packlink <alvarogonzalez@packlink.com>
2021-09-30 02:02:19 -07:00
Ishita Sequeira
07f4034aaa feat: lua script for pause/resume action for Deployments (#7293)
Signed-off-by: ishitasequeira <isequeir@redhat.com>
2021-09-29 17:58:35 -07:00
Yi Cai
459833d7c3 fix: default schedule options are cropped #5261 (#7289)
* fix: default schedule options are cropped #5261

Signed-off-by: ciiay <yicai@redhat.com>
2021-09-29 14:53:49 -07:00
Andrii Shaforostov
bbdbf81108 feat: update argo-ui (#7323)
* use merged argo-ui, align dependencies with argo-ui

Signed-off-by: andrii-codefresh <andrii@codefresh.io>

* use merged argo-ui, align dependencies with argo-ui

Signed-off-by: andrii-codefresh <andrii@codefresh.io>
2021-09-29 14:51:42 -07:00
Alexander Matyushentsev
1842c98374 fix: core-install.yaml always refers to latest argocd image (#7321)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-29 14:05:18 -07:00
Chetan Banavikalmutt
94372adcd4 fix: handle applicationset backup forbidden error (#7306)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-09-29 12:33:58 -07:00
plakyda-codefresh
e3df023310 fix: Move orphaned filter to Filters block (#7082)
fix: Move orphaned filter to Filters block (#7082)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-09-29 12:29:21 -07:00
Duy Le
6f5f7ffeee fix: tooltip zindex overwrite toolbar (#7220)
Signed-off-by: Duy Le <duyngoc834@gmail.com>
2021-09-29 12:24:41 -07:00
chandu484
97302103d9 Add Keeeb User to userlist (#7288) 2021-09-29 11:03:29 -07:00
Regina Scott
380037b63d fix: preventOverflow console warnings (#7298)
Signed-off-by: Regina Scott <rescott@redhat.com>
2021-09-29 10:27:25 -07:00
pasha-codefresh
0d68194205 feat: tracking method for annotations should be in another format (#7316)
feat: tracking method for annotations should be in another format (#7316)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-29 10:14:49 -07:00
Abhishek Veeramalla
20313adbe2 docs: minor formatting change in the docs (#7305)
Signed-off-by: iam-veeramalla <abhishek.veeramalla@gmail.com>
2021-09-29 11:43:57 +02:00
pasha-codefresh
a731997c59 feat: tracking method e2e (#7310)
feat: tracking method e2e (#7310)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-28 12:46:01 -07:00
pasha-codefresh
bb88a1c975 feat: rename app identifier (#7251)
feat: rename app identifier (#7251)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-28 08:35:17 -07:00
Alexander Matyushentsev
917d0797fa fix: deploy CI task should start docker using current user id to avoid permission denied error (#7300)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-27 19:01:55 -07:00
plakyda-codefresh
993cb838a9 feat: Project autocomplete (Connect repo SSH) (#7286)
feat: Project autocomplete (Connect repo SSH) (#7286)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-09-27 17:19:00 -07:00
Regina Scott
eb2c69d45e fix: long banner messages get cut off (#7264)
Signed-off-by: Regina Scott <rescott@redhat.com>
2021-09-27 13:31:14 -07:00
Alexander Matyushentsev
65012f502b chore: use kustomize verison bundled into argocd to upgrade argocd manifests in argoproj/argoproj-deployments (#7299)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-27 12:58:15 -07:00
ml
2f6e91ad22 chore: fix typo in directory name (#7248)
Signed-off-by: ml <ml@visu.li>
2021-09-27 11:33:00 -07:00
shivjm
b264729bfb docs: fix example ServiceMonitor for argocd-repo-server (#7254)
Signed-off-by: Shiv Jha-Mathur <shivjm@users.noreply.github.com>
2021-09-23 12:46:19 -07:00
pasha-codefresh
3952f66fc7 fix: remove not existing repo (#7280)
* remove not existing repo

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

* fix test

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-22 14:27:07 +02:00
plakyda-codefresh
b1f979aad6 feat: retry option app creation (#7252)
feat: retry option app creation (#7252)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-09-21 15:42:26 -07:00
Yuan Tang
2a579a6c05 docs: Add missing links to 1.8-2.1 upgrading guides (#7263)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-09-21 15:02:26 -07:00
dependabot[bot]
9e234b9dec chore(deps): bump tmpl from 1.0.4 to 1.0.5 in /ui (#7266)
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-21 15:02:14 -07:00
John Chen
4f69e93802 docs: add comment about current-user-password (#7258)
It is not immediately clear what the `<current-user-password>` should be as shown by this issue: https://github.com/argoproj/argo-cd/issues/4096.
This comment should make it more clear that when users are setting passwords as the default `admin` user, they should be using the `admin` password here.

Signed-off-by: John Chen <johnchen456@gmail.com>
2021-09-21 14:34:13 -07:00
Alexander Matyushentsev
3799d706df refactor: cache virtual project calculation to improve performance (#7274)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-21 12:20:49 -07:00
yyyyyy888
344353cb16 docs: Add Sutpc company into the user list. (#7267)
Signed-off-by: yangtian9999 <yangtian9999@163.com>
2021-09-21 12:20:08 -07:00
dependabot[bot]
d698e5d68a chore(deps): bump prismjs from 1.24.1 to 1.25.0 in /ui (#7265)
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.24.1 to 1.25.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.24.1...v1.25.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-21 11:32:50 -07:00
dependabot[bot]
5f9993a75b chore(deps): bump nth-check from 2.0.0 to 2.0.1 in /ui (#7270)
Bumps [nth-check](https://github.com/fb55/nth-check) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/fb55/nth-check/releases)
- [Commits](https://github.com/fb55/nth-check/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: nth-check
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-21 09:43:13 -07:00
Alexander Matyushentsev
f613fab6f3 refactor: stop using @beyonk/google-fonts-webpack-plugin to download google fonts (#7253)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-18 08:22:53 +02:00
Alexander Matyushentsev
183d729d40 fix: Argo CD should not use cached git/helm revision during app creation/update validation (#7244)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-16 18:35:15 -07:00
Regina Scott
b26e92873f fix: typo causing docs to not render properly (#7242)
Signed-off-by: Regina Scott <rescott@redhat.com>
2021-09-16 13:00:02 -07:00
Alexander Matyushentsev
36ab4dadda fix: Argo CD server address unspecified with Argo CD CLI v2.1.x (#7238)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-16 11:23:29 -07:00
pasha-codefresh
91fea1470f feat: add test to redis_hook.go (#7233)
* add test to redis_hook.go

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

* restart action

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-16 08:06:29 -07:00
pasha-codefresh
17e6ebdce1 feat: show difference in repos that exist and that should be changed (#7224)
* show difference in repos that exist and that should be changed

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-16 08:02:50 -07:00
pasha-codefresh
6f794d0dc9 fix: Redis should reconnect on connectivity issue (#7207)
fix: Redis should reconnect on connectivity issue (#7207)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-15 09:05:48 -07:00
Miguel Ángel Cabrera Miñagorri
9cf71bef90 fix: support gpg keys generation in centos-7 distros (#7221)
Signed-off-by: Miguel A. Cabrera Minagorri <mcabrera@vmware.com>
2021-09-15 08:26:46 -07:00
gin
25db5038c7 docs(users): add mixi in users.md (#7210)
Signed-off-by: gin <10017674+lirlia@users.noreply.github.com>
2021-09-14 12:52:19 -07:00
Remington Breeze
b6c458e8f4 fix(ui): Add Error Boundary around Extensions and comply with new Extensions API (#7215)
* fix: Add error boundary around Extensions and change path where UI looks for extensions

Signed-off-by: Remington Breeze <remington@breeze.software>

* Add error message to error boundary

Signed-off-by: Remington Breeze <remington@breeze.software>
2021-09-14 12:51:37 -07:00
Alexander Matyushentsev
2147ed3aea fix: cluster API should not drop system labels and annotations (#7212)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-14 10:37:57 -07:00
Remington Breeze
3df6be73e7 fix(ui): More tab was displayed for resources that did not have extensions installed (#7209)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-09-13 22:18:38 -07:00
jannfis
d823efee5d proposal: Change application identifier to allow app names longer than 63 chars (#6425)
proposal: Change application identifier to allow app names longer than 63 chars (#6425)

Signed-off-by: jannfis <jann@mistrust.net>
2021-09-13 08:49:15 -07:00
pasha-codefresh
1817b6b4d4 Scoped resources doc (#7206)
* add doc about scoped resources

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

* docs: explain project scoped resources

Signed-off-by: Kostis Kapelonis <kostis@codefresh.io>

Co-authored-by: Kostis Kapelonis <kostis@codefresh.io>
2021-09-13 08:47:39 -07:00
pasha-codefresh
7ed06cc9f6 feat: Scoped resources cluster e2e (#7199)
feat: Scoped resources cluster e2e (#7199)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-12 19:05:49 -07:00
Yuan Tang
49378a95c4 chore: Update Ingress apiVersion to networking.k8s.io/v1beta1 (#7188)
* chore: Update Ingress apiVersion to networking.k8s.io/v1beta1

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

* Revert changes in  controller/cache/info_test.go

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-09-10 10:04:52 -07:00
jannfis
a38f3176e2 chore: Update haproxy for redis-ha to 2.0.25 (#7194)
Signed-off-by: jannfis <jann@mistrust.net>
2021-09-10 09:13:27 -07:00
pasha-codefresh
08d1cf0e55 feat: Ability to test rbac and implement it with scoped repos (#7187)
feat: Ability to test rbac and implement it with scoped repos (#7187)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-09 21:42:32 -07:00
Thomas
85c45ca76e fix: use selected helm-values (#7166)
Signed-off-by: Thomas Münzl <thomasmuenzl@icloud.com>
2021-09-09 20:48:32 -07:00
Yi Cai
626c963b1c docs: minor update on dependencies.md (#7190)
Signed-off-by: ciiay <yicai@redhat.com>
2021-09-09 15:28:49 -07:00
Suraj Bodade
fc49eb2e46 fixed small typos in github credentials types (#7161)
Signed-off-by: suraj-zemoso <suraj.bodade@zemosolabs.com>
2021-09-09 11:40:06 -07:00
irizzant
e0c07b8027 #7144 fix: add custom volume as Helm working dir (#7162)
#7144 fix: add custom volume as Helm working dir (#7162)

Signed-off-by: irizzant <i.rizzante@gmail.com>
2021-09-09 10:31:03 -07:00
Chetan Banavikalmutt
7122b83fc3 feat: support adding labels and annotations to cluster secret (#7139)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-09-09 09:03:32 -07:00
pasha-codefresh
c64e8df84c feat: ability to switch user during test execution (#7164)
feat: ability to switch user during test execution (#7164)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-09-09 08:58:46 -07:00
Ben Ye
be884d2172 feat: Support delete-resource command in cli (#7093)
* feat: support delete-resource command in argocd cli

Signed-off-by: Ben Ye <ben.ye@bytedance.com>

* add E2E test and fix documents

Signed-off-by: Ben Ye <ben.ye@bytedance.com>

* sync app

Signed-off-by: Ben Ye <ben.ye@bytedance.com>
2021-09-06 09:11:06 -07:00
Ijeh Onyeka
d2100a30a0 add youverify to companies actively using argocd (#7163) 2021-09-04 15:09:51 -07:00
ThoTischner
9559613c8f feat: Closes #6956 - Adding confluent health checks (#6957)
* Issue argoproj#6956 - Adding confluent health checks

Signed-off-by: ThoTischner <thomas-schwaig@web.de>

* Issue argoproj#6956 - Change Unknown to Progressing

Signed-off-by: ThoTischner <thomas-schwaig@web.de>
2021-09-03 21:51:00 +02:00
dependabot[bot]
bd7f8c8eda chore(deps): bump tar from 6.1.3 to 6.1.11 in /ui (#7123)
Bumps [tar](https://github.com/npm/node-tar) from 6.1.3 to 6.1.11.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v6.1.3...v6.1.11)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-03 19:32:33 +02:00
jannfis
a90ab1a2e1 chore: Upgrade github.com/bradleyfalzon/ghinstallation to v2.0.2 (#7151)
Signed-off-by: jannfis <jann@mistrust.net>
2021-09-03 10:28:10 -07:00
Thomas
a5126648e1 fix: use basehref as cookie-path (#7105)
Signed-off-by: Thomas Münzl <thomasmuenzl@icloud.com>
2021-09-03 19:21:31 +02:00
Petr Drastil
d9e8a0fc31 chore: Upgrade dex server image to 2.30.0 (#7102)
* chore: Upgrade dex server to 2.30.0

Signed-off-by: Petr Drastil <petr.drastil@gmail.com>

* Revert dex server probes

Signed-off-by: Petr Drastil <petr.drastil@gmail.com>
2021-09-03 19:20:01 +02:00
Ishita Sequeira
b559bf88d1 feat: Add health checks for route.openshift.io (#7112)
* feat: Add health checks for route.openshift.io

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* Addressed PR comments

Signed-off-by: ishitasequeira <isequeir@redhat.com>
2021-09-03 17:27:16 +02:00
Ishita Sequeira
c0f2bf55a7 feat: health check for openshift DeploymentConfig (#7114)
* feat: health check for openshift DeploymentConfig

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* Address PR comments

Signed-off-by: ishitasequeira <isequeir@redhat.com>
2021-09-03 17:26:31 +02:00
Ishita Sequeira
4b92f96034 feat: Add health checks for olm operators (#7126)
* feat: Add health checks for olm operators

Signed-off-by: ishitasequeira <isequeir@redhat.com>

* Addressed the PR comments

Signed-off-by: ishitasequeira <isequeir@redhat.com>
2021-09-03 17:25:42 +02:00
smartbit
24054820da docs: update url of External Secrets Operator (#7120)
has moved from ContainerSolutions' github account to it's own github project
2021-09-03 11:10:58 +02:00
Alexander Matyushentsev
22600228c2 fix: Correct this attempt to modify const 'store' variable (#7145)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-02 11:37:20 -07:00
renjikari
9025318adf docs: Add freee as a user (#7140)
Signed-off-by: Shunki Fujiwara <shunki-fujiwara@freee.co.jp>
2021-09-02 03:43:13 -07:00
Alexander Matyushentsev
5d9aa989f3 fix: gracefully shutdown metrics server when dex config changes (#7138)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-01 18:55:05 -07:00
Alexander Matyushentsev
9613b240fb fix: upgrade gitops engine (fix #7088) (#7137)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-01 17:45:42 -07:00
Alexander Matyushentsev
8fbcc1c7fc fix: cluster filter popping out of box (#7135)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-09-01 15:33:27 -07:00
Remington Breeze
d2ff65ae39 feat(ui): Display event timestamps in human readable format (#7132)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-09-01 15:08:40 -07:00
c1_zh
dd26a48f8a fix: Network view is confusing if same ingress is targeting two services #2338 (#7113)
Signed-off-by: cezhang <c1zhang.dev@gmail.com>
2021-09-01 14:46:40 -07:00
Chetan Banavikalmutt
8c19c7864d docs: add a section about banners (#7109)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-09-01 12:52:59 -07:00
pasha-codefresh
a9f009cb10 feat: e2e for clusters (#7118)
feat: e2e for clusters (#7118)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-31 10:32:54 -07:00
May Zhang
ce1d8031ae fix: repository name already exists when multiple helm dependencies f… (#7096)
* fix: repository name already exists when multiple helm dependencies from same private repo server

Signed-off-by: May Zhang <may_zhang@intuit.com>

* fix: add test cases

Signed-off-by: May Zhang <may_zhang@intuit.com>

* fix: clean up

Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-08-31 08:30:03 -07:00
pasha-codefresh
dd2900eaeb feat: scoped repo e2e tests (#7110)
feat: scoped repo e2e tests (#7110)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-30 10:10:32 -07:00
pasha-codefresh
c0bcd6b255 feat: repo list and repo get command + e2e tests (#7108)
feat: repo list and repo get command + e2e tests (#7108)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-30 10:08:33 -07:00
Álvaro González
6897aa4ed2 docs: add configuration guide for using Google Load Balancers with GKE (#6747)
* docs: add configuration guide for using Google Load Balancers with GKE

Signed-off-by: alvarogonzalez-packlink <alvarogonzalez@packlink.com>

* docs: fix format on notes and warnings

Signed-off-by: alvarogonzalez-packlink <alvarogonzalez@packlink.com>
2021-08-30 15:58:49 +02:00
Yi Cai
42903044f3 fix: Summary Colors don't match key and numbers don't match colors #5200 (#7042)
Signed-off-by: ciiay <yicai@redhat.com>
2021-08-27 12:41:09 -07:00
Thomas
700806f408 fix: reset token-cookie on logout (oidc) (#7092)
fix: reset token-cookie on logout (oidc) (#7092)

Signed-off-by: jimtoniq <thomasmuenzl@icloud.com>
2021-08-27 11:09:19 -07:00
pasha-codefresh
b271d6ac5c feat: Test create repository with project ( part of scoped resources e2e tests ) (#7103)
feat: Test create repository with project ( part of scoped resources e2e tests ) (#7103)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-27 10:29:31 -07:00
Jonah Back
a940cb5914 fix(ui): calculate service info correctly for networking.k8s.io/v1 ingress (#6923)
Signed-off-by: Jonah Back <jonah@jonahback.com>
2021-08-26 14:47:26 -07:00
Alexander Matyushentsev
87de4edd15 fix: document IP addresses logging (#7094)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-26 13:01:40 -07:00
Alexander Matyushentsev
abba8dddce docs: update VERSION file and CHANGELOG (#7083)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-26 11:28:51 -07:00
plakyda-codefresh
44520ea479 feat: resource name filter + filter block for resource table view (#7081)
feat: resource name filter + filter block for resource table view (#7081)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-08-26 10:32:36 -07:00
pasha-codefresh
ae803a2f1e feat: goreman option to exclude (#7080)
feat: goreman option to exclude (#7080)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-25 12:40:55 -07:00
pasha-codefresh
49a854a738 feat: Scoped clusters (#7039)
feat: Scoped clusters (#7039)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-25 09:53:58 -07:00
Benjamin Manifold
81155ccb0c feat: Cassandra Health Check. Closes #6843 (#7017)
Signed-off-by: benmanifold <benmanifold@gmail.com>
2021-08-25 11:27:07 +02:00
Josh Gavant
18057fa5ee docs: clarify new repo, port-forward flags (#6937)
The instructions for telling the CLI how to automatically use
port-forward were intertwined with the instructions for registering a
repo; this separates them.

This also moves the port-forward flags instructions to the first place
in the doc a user would need them.

Signed-off-by: Josh Gavant <joshgavant@gmail.com>
2021-08-25 11:26:44 +02:00
May Zhang
ca5003f3ba fix: password reset requirements (#7071)
* fix: password reset meet requirement

Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-08-24 23:21:03 -07:00
Alexander Matyushentsev
1d3d03f5d3 fix: Custom Styles feature is broken (#7067)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-24 15:08:12 -07:00
Remington Breeze
a894d4b128 fix(ui): Unschedulable button changed widths on click (#7030)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-24 11:29:45 -07:00
Remington Breeze
440e4dc5d9 fix(ui): Add State to props passed to Extensions (#7045)
Signed-off-by: Remington Breeze <remington@breeze.software>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-24 11:23:56 -07:00
Alexander Matyushentsev
d6973c7b8a fix: fix building remote container (#7062)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-24 09:48:14 -07:00
pasha-codefresh
34e904dd7b fix: make codegen (#7059)
fix: make codegen

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-24 09:02:44 -07:00
Omar De Donato
c7e532941f docs: added Technacy in USERS.md (#7051)
We at Technacy love using Argo CD

Signed-off-by: Omar <omar.dedonato@technacy.it>
2021-08-23 13:23:28 +02:00
Alexander Matyushentsev
613db278a7 fix: keep uid_entrypoint.sh for backward compatibility (#7047)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-23 08:38:29 +02:00
pasha-codefresh
91c883668e feat: Scoped repo unit tests (#7026)
feat: Scoped repo unit tests

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-22 18:01:36 -07:00
Yi Cai
d12eafa826 fix: Truncated synchronize check-boxes should have tooltips #4233 (#6954)
Signed-off-by: ciiay <yicai@redhat.com>
2021-08-20 12:41:25 -07:00
Alexander Matyushentsev
0dcac9a8d9 fix: reload extension when selected resource node changes (#7034)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-19 22:14:00 -07:00
Jesse Suen
0078a4d9ee docs: add @wanghong230 as a reviewer (#7029)
Signed-off-by: Jesse Suen <jessesuen@gmail.com>
2021-08-19 17:02:51 -07:00
Jesse Suen
8ceceb8b55 docs: add @rbreeze as an approver (#7028)
Signed-off-by: Jesse Suen <jessesuen@gmail.com>
2021-08-19 13:56:47 -07:00
Remington Breeze
2e3405134b fix(ui): Resource details crashed due to extensions (#7025)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-19 09:55:16 -07:00
pasha-codefresh
5b1906d2a7 feat: Cover grpc crud rbac (#7008)
feat: Cover grpc crud rbac (#7008)

Signed-off-by: Victor Plakyda <plakyda1@gmail.com>
Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-19 08:43:48 -07:00
pasha-codefresh
0093bddc39 fix(ui): user account list yaml (#7021)
fix(ui): user account list yaml (#7021)

Signed-off-by: Victor Plakyda <plakyda1@gmail.com>
2021-08-19 08:40:20 -07:00
Alexander Matyushentsev
788613cb14 feat: support loading extensions in Argo CD UI (#7019)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-19 08:39:51 -07:00
pasha-codefresh
53dd0da8c3 fix(ui): applications table view, Closes #6733 (#6995)
Co-authored-by: Victor Plakyda <plakyda1@gmail.com>
2021-08-18 12:23:34 -07:00
Guido Zockoll
8f21138d54 docs: added type:git to secret examples (fixes #6984) (#7013)
* Update declarative-setup.md

added `type: git` to the secrets

* warning about labels getting lost

when using sealed-secrets the labels will get lost and has to be readded
2021-08-18 20:18:28 +02:00
Saumeya Katyal
676a8714bf fix: Unschedulable button style (#7003)
Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2021-08-18 09:24:03 -07:00
Philipp Dallig
4ae1d876fd fix: Running on Openshift 4.x with readOnlyRootFilesystem (#6998)
Signed-off-by: Philipp Dallig <philipp.dallig@gmail.com>
2021-08-18 12:18:01 +02:00
Chris Sinjakli
efc8ec1d78 chore: Log application name for invalid application spec (#6991)
When creating an application directly through the CLI or a `kubectl
apply`, it's relatively obvious which application is invalid (provided
you aren't applying several at once) as you're there creating it
interactively.

It's less clear when applications are generated by the application set
controller. When that happens, you need to go looking in the controller
logs, where you'll find something like:

> time="2021-08-10T11:36:02Z" level=error msg="application spec is
> invalid: InvalidSpecError: application destination
> {https://kubernetes.default.svc default} is not permitted in project
> 'my-project'"

which doesn't have any connection back to the application being
generated. This is particularly tricky to track down if you're searching
your logs via some sort of aggregator rather than watching `kubectl logs
-f`.

After this change, the log produced would be:

> time="2021-08-10T11:36:02Z" level=error msg="application spec for
> guestbook is invalid: InvalidSpecError: application destination
> {https://kubernetes.default.svc default} is not permitted in project
> 'my-project'"

There's probably fancier ways this information could be presented (e.g.
if application sets were represented in the UI and knew about failures
to apply their generated applications), but this logging change seems
like a cheap way to make this situation more debuggable.

Signed-off-by: Chris Sinjakli <chris@sinjakli.co.uk>
2021-08-18 11:10:52 +02:00
Alexander Matyushentsev
e3b7a2be13 fix: resouce health filter should include node if node or node's root health matches filter (#7002)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-17 14:34:27 -07:00
Alexander Matyushentsev
44ec4e0a82 fix: upgrade argo-ui version (#7010)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-17 12:50:07 -07:00
pasha-codefresh
24ad4618c2 fix: Git errors to grpc (#7005)
fix: Git errors to grpc (#7005)

Signed-off-by: olegz-codefresh <olegz@codefresh.io>
2021-08-17 12:27:44 -07:00
Yuan Tang
d3fb6fb7db chore: Update to use NewSharedInformerFactoryWithOptions due to deprecation (#7009)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-08-17 21:23:13 +02:00
RoCha
95d9016ed4 feat: healtcheck for iam.cnrm.cloud.google.com/IAMPolicyMember (#6783)
Signed-off-by: Romain Chalumeau <rchalumeau@magicleap.com>
2021-08-17 21:20:30 +02:00
Alexander Matyushentsev
e195995790 docs: update obsolete resource customization docs (#7000)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-16 10:49:34 -07:00
Spiros Economakis
124995c275 feat: Add a metric to express connection status to each cluster (#6862)
The cluster collector includes one more metric for kubernetes cluster connection
which rely on `SyncError`.

Ticket: #6855
Signed-off-by: Spiros Economakis <spiros.oikonomakis@gmail.com>
2021-08-16 09:52:47 -07:00
pasha-codefresh
7b89c4e53c feat: Project scoped repo (#6943)
feat: Project scoped repo (#6943)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-16 09:38:37 -07:00
David Collom
1ab85de378 fix: Disable generating of CA Certificates (#6987)
Signed-off-by: David Collom <david.collom@jetstack.io>
2021-08-14 10:04:41 +02:00
Remington Breeze
eb76649ef5 chore(ui): Relocate CheckboxRow component to Filters instead of argo-ui (#6990)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-13 15:33:36 -07:00
Remington Breeze
3887289090 fix(ui): Migrate to keyhook helpers in argo-ui, update keybindings accordingly (#6953)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-13 14:26:11 -07:00
Yi Cai
d842e8333a feat: Allow collapsing of individual diff sections in diff view #3608 (#6978)
Signed-off-by: ciiay <yicai@redhat.com>
2021-08-13 08:31:37 -07:00
Alexander Matyushentsev
311926b8c9 fix: argocd core commands should not drop existing persistent flags (#6981)
* fix: argocd core commands should not drop existing persistent flags

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>

* run cli codegen

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-12 23:10:59 -07:00
Yuan Tang
63d809614c docs: Fix links to subsections in roadmap (#6986)
* docs: Fix links to completed subsections in roadmap

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

* One more link

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-08-12 22:50:15 -07:00
Yuan Tang
741329afb6 docs: Add cluster URL when creating an app to be consistent with the screenshot (#6731)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2021-08-12 22:23:00 -07:00
Nico Schottelius
d36cf3e2bb Update USERS.md - added ungleich.ch (#6979)
Signed-off-by: Nico Schottelius <nico.schottelius@ungleich.ch>

Co-authored-by: Nico Schottelius <nico@nico-notebook.schottelius.org>
2021-08-12 22:17:54 -07:00
Alexander Matyushentsev
53bbb8ecf4 docs: update roadmap and release checklist (#6980)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-12 16:59:39 -07:00
dependabot[bot]
86ca66b2d6 chore(deps): bump jszip from 3.5.0 to 3.7.1 in /ui-test (#6952)
Bumps [jszip](https://github.com/Stuk/jszip) from 3.5.0 to 3.7.1.
- [Release notes](https://github.com/Stuk/jszip/releases)
- [Changelog](https://github.com/Stuk/jszip/blob/master/CHANGES.md)
- [Commits](https://github.com/Stuk/jszip/compare/v3.5.0...v3.7.1)

---
updated-dependencies:
- dependency-name: jszip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-12 13:19:20 -07:00
pasha-codefresh
6ac9753b63 feat: support ability get cluster by name from cli, Closes #6865 (#6972)
feat: support ability get cluster by name from cli, Closes #6865 (#6972)

Support get cluster cmd by name
https://github.com/argoproj/argo-cd/issues/6865

Signed-off-by: olegz-codefresh <olegz@codefresh.io>
2021-08-12 13:18:18 -07:00
pasha-codefresh
afb1c8b210 feat(ui): add top value for large breakpoint Closes #6944 (#6975)
feat(ui): add `top` value for `large` breakpoint Closes #6944 (#6975)

Signed-off-by: andrii-codefresh <andrii@codefresh.io>
2021-08-12 12:35:20 -07:00
dependabot[bot]
117eadaceb chore(deps): bump path-parse from 1.0.6 to 1.0.7 in /ui-test (#6950)
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-12 12:33:41 -07:00
dependabot[bot]
10b4e44c42 chore(deps): bump path-parse from 1.0.6 to 1.0.7 in /ui (#6949)
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-12 12:33:18 -07:00
dependabot[bot]
8cf8a8cf81 chore(deps): bump url-parse from 1.5.1 to 1.5.3 in /ui (#6951)
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.1 to 1.5.3.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.1...1.5.3)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-12 12:33:10 -07:00
pasha-codefresh
8a29cf8fbf fix(ui): Fix checkbox style in Delete pod modal Closes #6947 (#6961)
* Fix checkbox style in Delete pod modal

Signed-off-by: Victor Plakyda <plakyda1@gmail.com>

* Fix checkbox

Signed-off-by: Victor Plakyda <plakyda1@gmail.com>

Co-authored-by: Victor Plakyda <plakyda1@gmail.com>
2021-08-12 12:05:17 -07:00
ritchiekng
4a3dd76f19 Create USERS.md (#6973)
Fixing issue where link not working
2021-08-12 12:02:30 -07:00
Jesse Suen
b91732a8eb fix: rollout v1.0 'Paused' status.phase should map to Argo CD 'Suspended' (#6967)
Signed-off-by: Jesse Suen <jessesuen@gmail.com>
2021-08-12 11:37:08 -07:00
ritchiekng
97e8c7d00d Update USERS.md - added MeDirect (#6955)
* Update USERS.md

Signed-off-by: Steve Ritchie <steve.ritchie@medirect.com.mt>

* Update USERS.md

Updating website for Medirect
2021-08-11 16:28:51 -07:00
Alexander Matyushentsev
e5ee00f4d0 fix: basehref not set correctly (#6962)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-11 15:22:33 -07:00
Alexander Matyushentsev
aab0b173d5 fix: update deprecated helm2 installation URL (#6960)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-11 12:33:59 -07:00
Alexander Matyushentsev
50993206a5 fix: make sure repo server discard cached empty response (#6948)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-10 19:25:07 -07:00
Alexander Matyushentsev
4164db88f5 fix: applications/resources filter improvement and bug fixes (#6931)
* fix: applications/resources filter improvement and bug fixes

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-10 17:10:24 -07:00
May Zhang
c5eb25ceba fix: use secure way to generate initial password (#6938)
* fix: use secure way to generate initial password

Signed-off-by: May Zhang <may_zhang@intuit.com>

* fix: use secure way to generate initial password

Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-08-09 19:22:10 -07:00
pasha-codefresh
685b07ed34 feat(ui): Retry strategy, Application + Applications, #5318 (#6864)
feat(ui): Retry strategy, Application + Applications, #5318 (#6864)

Signed-off-by: Victor Plakyda <plakyda1@gmail.com>
2021-08-09 17:26:31 -07:00
jannfis
3091bc5b6f docs: Update contributor docs (#6615)
* Sync

Signed-off-by: jannfis <jann@mistrust.net>

* docs: Update contributor docs

Signed-off-by: jannfis <jann@mistrust.net>

* New paragraph about code submission

Signed-off-by: jannfis <jann@mistrust.net>

* Update

Signed-off-by: jannfis <jann@mistrust.net>

* Update code submissions before triage paragraph

Signed-off-by: jannfis <jann@mistrust.net>
2021-08-09 12:15:21 +02:00
Saravanan Arumugam (Aswath)
810a977846 Added RightRev As the user's list. (#6929)
Added RightRev As the user's list.

Signed-off-by: Saravanan Arumugam (Aswath) <saravanan.a@rightrev.com>
2021-08-08 08:55:39 -07:00
jannfis
adade448a8 docs: Update security considerations (#6930)
* docs: Update security considerations

Signed-off-by: jannfis <jann@mistrust.net>

* docs: Update security considerations

Signed-off-by: jannfis <jann@mistrust.net>
2021-08-08 08:55:01 -07:00
jannfis
c22d8321cc docs: Update security contacts in security policy (#6928)
* docs: Update security contact

Signed-off-by: jannfis <jann@mistrust.net>

* docs: Update security contact

Signed-off-by: jannfis <jann@mistrust.net>

* docs: Update security contact

Signed-off-by: jannfis <jann@mistrust.net>
2021-08-07 17:58:21 -07:00
Daisuke Taniwaki
819225c709 fix: Set header to OIDC requests (#6869)
Signed-off-by: Daisuke Taniwaki <daisuketaniwaki@gmail.com>
2021-08-05 12:02:22 +02:00
Connor
dd50b88cd1 docs: Add documentation on using OIDC with Dex (#6904)
* docs: Add documentation on using OIDC with Dex

Signed-off-by: Connor Kelly <connor.r.kelly@gmail.com>

* docs: Add documentation on using OIDC with Dex -- fix typo

Signed-off-by: Connor Kelly <connor.r.kelly@gmail.com>

* Fix warning box for Dex OIDC group configuration knob

Signed-off-by: Connor Kelly <connor.r.kelly@gmail.com>
2021-08-05 11:57:18 +02:00
Alexander Matyushentsev
8b1c364f58 fix: application sync panel crashes if app has no sync options (#6914)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-04 16:56:08 -07:00
Yi Cai
d74ce38c8c fix: Reword Generate new token dialog (#6913)
Signed-off-by: ciiay <yicai@redhat.com>
2021-08-04 16:48:27 -07:00
Alexander Matyushentsev
826288f861 fix: assume ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS, ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS env vars have seconds (#6912)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-04 13:51:16 -07:00
Yi Cai
e86c5ea17c fix: UI 6337 cluster filter improvement for issue #6337 (#6856)
* fix: when cluster field is bge-dev1, the applications with cluster dev1 is selected #6337

Signed-off-by: ciiay <yicai@redhat.com>
2021-08-04 13:05:49 -07:00
Noam Gal
f7614e0c4e fixed max to use MaxInt64 value (#6911)
Signed-off-by: Noam Gal <noam.gal@codefresh.io>
2021-08-04 11:07:54 -07:00
Chetan Banavikalmutt
2130c8a949 fix: unset command should remove env vars when there's no error (#6908)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2021-08-04 10:54:16 -07:00
pasha-codefresh
9d6ccee305 feat: rollback should work without id passed #6825. (#6877)
feat: rollback should work without id passed #6825. (#6877)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-08-04 10:51:54 -07:00
Remington Breeze
9c0495d9a3 fix: Add https prefix to ingress URLs if hosts field is present (#6901)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-04 09:33:41 -07:00
woshicai
ef653cac57 fix: client input arguments with equal sign (#6885)
Signed-off-by: Charles Cai <charles.cai@sap.com>

Co-authored-by: Charles Cai <charles.cai@sap.com>
2021-08-04 14:20:18 +02:00
Bob Claerhout
9099d0ba83 docs: Add replace description on individual resource level (#6905)
Signed-off-by: Bob Claerhout <claerhout.bob@gmail.com>
2021-08-04 14:14:21 +02:00
May Zhang
50b0010470 fix: logout redirect URL (#6903)
Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-08-03 17:05:58 -07:00
Alexander Matyushentsev
6b0d449997 refactor: update resources install order according to helm implementation (#6902)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-03 16:53:39 -07:00
Alexander Matyushentsev
c607a3b294 fix: controller should not create orphaned resources warning by default (#6898)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-03 16:05:19 -07:00
Alexander Matyushentsev
4fef2114fe feat: Improve Replace sync option description in UI (#6899)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-03 16:05:08 -07:00
dependabot[bot]
8c216ed7a8 chore(deps): bump tar from 6.1.0 to 6.1.3 in /ui (#6900)
Bumps [tar](https://github.com/npm/node-tar) from 6.1.0 to 6.1.3.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v6.1.0...v6.1.3)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-03 13:50:29 -07:00
Joseph Michael Casey
d404f0e425 docs(users): add Capital One (#6897) 2021-08-03 10:51:49 -07:00
Yi Cai
c5ebc584d0 fix: menu for application loses text when title area buttons collapse #6474 (#6887)
Signed-off-by: ciiay <yicai@redhat.com>
2021-08-03 10:06:12 -07:00
Remington Breeze
241a6fb1ba fix(ui): Bump argo-ui to hide filter suggestions on enter and show on typing (#6891)
* fix(ui): Bump argo-ui to hide filter suggestions on enter and show on typing

Signed-off-by: Remington Breeze <remington@breeze.software>

* remove unneccessary yarn.lock changes

Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-03 09:34:07 -07:00
Remington Breeze
93e624d590 fix(ui): Add View Details option to resource actions menu (#6893)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-03 09:33:25 -07:00
Jan-Otto Kröpke
8f4e002ae4 fix: upgrade to kustomize 4.2.0 (#6861)
Signed-off-by: Jan-Otto Kröpke <joe@adorsys.de>
2021-08-03 09:24:22 -07:00
May Zhang
3abf8c6735 fix: add documentation for using argocd repocreds with --enable-coi and --type helm (#6890)
Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-08-03 10:48:20 +02:00
Jun
3ff8481694 feat: Rollback command support omit history id (#6863)
Signed-off-by: junnplus <junnplus@gmail.com>
2021-08-02 22:32:09 -07:00
Remington Breeze
0d23207c59 fix(ui): Incorrect path for non-namespaced resources (#6895)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-02 17:56:12 -07:00
balchua
fcd28b6eb1 docs: rename credit agricole to credit agricole CIB. (#6871)
* rename credit agricole to credit agricole CIB.

Signed-off-by: balchua <balchua@yahoo.com>

* fix semantic pr.

Signed-off-by: balchua <balchua@yahoo.com>
2021-08-02 12:29:54 -07:00
Remington Breeze
7e27d1072f fix(ui): Page navigation no longer visible with status bar (#6888)
Signed-off-by: Remington Breeze <remington@breeze.software>
2021-08-02 12:29:37 -07:00
Alexander Matyushentsev
1e5c763d6f fix: make sure orphaned filter checkbox is clickable (#6886)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-08-02 11:51:40 -07:00
woshicai
7fbf50493b fix: docs about custom image user #6851 (#6872)
* fix: docs about custom image user, change it from argocd to 999

Signed-off-by: Charles Cai <charles.cai@sap.com>

* update: docs for upgrading version

Signed-off-by: Charles Cai <charles.cai@sap.com>

Co-authored-by: Charles Cai <charles.cai@sap.com>
2021-08-02 11:43:01 -07:00
Geoffrey Huntley
f170d24ed1 docs(users): add gitpod (#6879)
Signed-off-by: Geoffrey Huntley <ghuntley@ghuntley.com>
2021-08-02 11:39:08 -07:00
Joe Bowbeer
bcfc112d82 docs: installation.md (#6860)
Signed-off-by: Joe Bowbeer <joe.bowbeer@gmail.com>
2021-07-30 15:57:17 -07:00
Yi Cai
66acd16bce fix: Project filter selector does not get unset upon clear filters #6750 (#6866)
Signed-off-by: ciiay <yicai@redhat.com>
2021-07-30 15:47:00 -07:00
Remington Breeze
bee20c2154 fix(ui): Prevent UI crash if app status or resources is empty (#6858) 2021-07-30 08:48:05 -07:00
Alexander Matyushentsev
17bef1c2c6 fix: util.cli.SetLogLevel should update global log level (#6852)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-07-29 13:01:38 -07:00
Alexander Matyushentsev
2abf284f81 fix: include cluster level RBAC into argocd-core manifests (#6854)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-07-29 12:49:06 -07:00
David Maciel
221d0c048d Fix #6567 Admin token now expires (#6846) 2021-07-29 11:19:53 -07:00
dependabot[bot]
cd9dcecccd chore(deps): bump glob-parent from 5.1.1 to 5.1.2 in /ui-test (#6848)
Bumps [glob-parent](https://github.com/gulpjs/glob-parent) from 5.1.1 to 5.1.2.
- [Release notes](https://github.com/gulpjs/glob-parent/releases)
- [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/glob-parent/compare/v5.1.1...v5.1.2)

---
updated-dependencies:
- dependency-name: glob-parent
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-29 11:18:57 -07:00
dependabot[bot]
52090425c6 chore(deps): bump ws from 7.4.1 to 7.5.3 in /ui-test (#6849)
Bumps [ws](https://github.com/websockets/ws) from 7.4.1 to 7.5.3.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.1...7.5.3)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-29 11:18:19 -07:00
Klaus Dorninger
228c465393 fix: #6844 multiple global projects can be configured (#6845)
Signed-off-by: Klaus Dorninger <github@dornimaug.org>
2021-07-29 11:01:52 -07:00
Keith Chong
4a69cce7b1 test: Add initial automated UI smoke tests (#4393) (#4694)
Signed-off-by: Keith Chong <kykchong@redhat.com>
2021-07-29 10:11:11 -07:00
Alexander Matyushentsev
c7738a0cae fix: core installation must include CRD definitions (#6841)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-07-28 16:30:11 -07:00
567 changed files with 27327 additions and 4487 deletions

View File

@@ -9,10 +9,18 @@ on:
pull_request:
branches:
- 'master'
- 'release-*'
env:
# Golang version to use across CI steps
GOLANG_VERSION: '1.16.5'
GOLANG_VERSION: '1.16.11'
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-docker:
@@ -30,9 +38,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Download all Go modules
@@ -48,13 +56,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Restore go build cache
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -65,16 +73,19 @@ jobs:
run: make build-local
lint-go:
permissions:
contents: read # for actions/checkout to fetch code
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
name: Lint Go code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v2
uses: golangci/golangci-lint-action@v3
with:
version: v1.38.0
args: --timeout 10m --exclude SA5011
version: v1.46.2
args: --timeout 10m --exclude SA5011 --verbose
test-go:
name: Run unit tests for Go packages
@@ -85,11 +96,11 @@ jobs:
- name: Create checkout directory
run: mkdir -p ~/go/src/github.com/argoproj
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Create symlink in GOPATH
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Install required packages
@@ -109,7 +120,7 @@ jobs:
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
- name: Restore go build cache
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -145,11 +156,11 @@ jobs:
- name: Create checkout directory
run: mkdir -p ~/go/src/github.com/argoproj
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Create symlink in GOPATH
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Install required packages
@@ -169,7 +180,7 @@ jobs:
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
- name: Restore go build cache
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -196,9 +207,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Create symlink in GOPATH
@@ -243,14 +254,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup NodeJS
uses: actions/setup-node@v1
with:
node-version: '12.18.4'
- name: Restore node dependency cache
id: cache-dependencies
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ui/node_modules
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
@@ -279,12 +290,12 @@ jobs:
sonar_secret: ${{ secrets.SONAR_TOKEN }}
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Restore node dependency cache
id: cache-dependencies
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ui/node_modules
key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }}
@@ -340,7 +351,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
k3s-version: [v1.21.2, v1.20.2, v1.19.2, v1.18.9, v1.17.11]
k3s-version: [v1.21.2, v1.20.2, v1.19.2]
needs:
- build-go
env:
@@ -355,9 +366,9 @@ jobs:
ARGOCD_SERVER: "127.0.0.1:8088"
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: GH actions workaround - Kill XSP4 process
@@ -375,7 +386,7 @@ jobs:
sudo chown runner $HOME/.kube/config
kubectl version
- name: Restore go build cache
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
@@ -398,9 +409,9 @@ jobs:
git config --global user.email "john.doe@example.com"
- name: Pull Docker image required for tests
run: |
docker pull quay.io/dexidp/dex:v2.25.0
docker pull ghcr.io/dexidp/dex:v2.35.3-distroless
docker pull argoproj/argo-cd-ci-builder:v1.0.0
docker pull redis:6.2.4-alpine
docker pull redis:6.2.7-alpine
- name: Create target directory for binaries in the build-process
run: |
mkdir -p dist

View File

@@ -6,15 +6,27 @@ on:
schedule:
- cron: '0 19 * * 0'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
CodeQL-Build:
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/autobuild to send a status report
if: github.repository == 'argoproj/argo-cd'
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
@@ -24,7 +36,7 @@ jobs:
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1

View File

@@ -16,7 +16,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: 3.x
python-version: 3.9.8
- name: build
run: |
pip install -r docs/requirements.txt

View File

@@ -6,15 +6,25 @@ on:
- master
env:
GOLANG_VERSION: '1.16.5'
GOLANG_VERSION: '1.16.11'
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
publish:
permissions:
contents: write # for git to push upgrade commit if not already deployed
if: github.repository == 'argoproj/argo-cd'
runs-on: ubuntu-latest
env:
GOPATH: /home/runner/work/argo-cd/argo-cd
steps:
- uses: actions/setup-go@v1
- uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
- uses: actions/checkout@master
@@ -46,12 +56,28 @@ jobs:
DOCKER_USERNAME: ${{ secrets.RELEASE_DOCKERHUB_USERNAME }}
DOCKER_TOKEN: ${{ secrets.RELEASE_DOCKERHUB_TOKEN }}
# sign container images
- name: Install cosign
uses: sigstore/cosign-installer@main
with:
cosign-release: 'v1.13.0'
- name: Sign Argo CD latest image
run: |
cosign sign --key env://COSIGN_PRIVATE_KEY quay.io/argoproj/argocd:latest
# Displays the public key to share.
cosign public-key --key env://COSIGN_PRIVATE_KEY
env:
COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}}
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
if: ${{ github.event_name == 'push' }}
# deploy
- run: git clone "https://$TOKEN@github.com/argoproj/argoproj-deployments"
env:
TOKEN: ${{ secrets.TOKEN }}
- run: |
docker run -v $(pwd):/src -w /src --rm -t lyft/kustomizer:v3.3.0 kustomize edit set image quay.io/argoproj/argocd=ghcr.io/argoproj/argocd:${{ steps.image.outputs.tag }}
docker run -u $(id -u):$(id -g) -v $(pwd):/src -w /src --rm -t ghcr.io/argoproj/argocd:${{ steps.image.outputs.tag }} kustomize edit set image quay.io/argoproj/argocd=ghcr.io/argoproj/argocd:${{ steps.image.outputs.tag }}
git config --global user.email 'ci@argoproj.com'
git config --global user.name 'CI'
git diff --exit-code && echo 'Already deployed' || (git commit -am 'Upgrade argocd to ${{ steps.image.outputs.tag }}' && git push)

View File

@@ -12,10 +12,15 @@ on:
- '!release-v0*'
env:
GOLANG_VERSION: '1.16.5'
GOLANG_VERSION: '1.16.11'
permissions:
contents: read
jobs:
prepare-release:
permissions:
contents: write # To push changes to release branch
name: Perform automatic release on trigger ${{ github.ref }}
runs-on: ubuntu-latest
env:
@@ -37,7 +42,7 @@ jobs:
GIT_EMAIL: argoproj@gmail.com
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
@@ -94,7 +99,7 @@ jobs:
echo "=========== BEGIN COMMIT MESSAGE ============="
git show ${SOURCE_TAG}
echo "============ END COMMIT MESSAGE =============="
# Quite dirty hack to get the release notes from the annotated tag
# into a temporary file.
RELEASE_NOTES=$(mktemp -p /tmp release-notes.XXXXXX)
@@ -141,7 +146,7 @@ jobs:
echo "RELEASE_NOTES=${RELEASE_NOTES}" >> $GITHUB_ENV
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: ${{ env.GOLANG_VERSION }}
@@ -207,12 +212,32 @@ jobs:
docker login --username "${DOCKER_USERNAME}" --password "${DOCKER_TOKEN}"
docker tag ${IMAGE_NAMESPACE}/argocd:v${TARGET_VERSION} argoproj/argocd:v${TARGET_VERSION}
docker push argoproj/argocd:v${TARGET_VERSION}
make release-cli
make checksums
chmod +x ./dist/argocd-linux-amd64
./dist/argocd-linux-amd64 version --client
if: ${{ env.DRY_RUN != 'true' }}
- name: Install cosign
uses: sigstore/cosign-installer@main
with:
cosign-release: 'v1.13.0'
- name: Sign Argo CD container images and assets
run: |
cosign sign --key env://COSIGN_PRIVATE_KEY ${IMAGE_NAMESPACE}/argocd:v${TARGET_VERSION}
cosign sign-blob --key env://COSIGN_PRIVATE_KEY ./dist/argocd-${TARGET_VERSION}-checksums.txt > ./dist/argocd-${TARGET_VERSION}-checksums.sig
# Retrieves the public key to release as an asset
cosign public-key --key env://COSIGN_PRIVATE_KEY > ./dist/argocd-cosign.pub
env:
COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}}
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
if: ${{ env.DRY_RUN != 'true' }}
- name: Read release notes file
id: release-notes
uses: juliangruber/read-file-action@v1
with:
with:
path: ${{ env.RELEASE_NOTES }}
- name: Push changes to release branch
@@ -221,7 +246,7 @@ jobs:
git push origin ${TARGET_BRANCH}
git push origin ${RELEASE_TAG}
- name: Create GitHub release
- name: Dry run GitHub release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -232,38 +257,61 @@ jobs:
draft: ${{ env.DRAFT_RELEASE }}
prerelease: ${{ env.PRE_RELEASE }}
body: ${{ steps.release-notes.outputs.content }}
if: ${{ env.DRY_RUN == 'true' }}
- name: Upload argocd-linux-amd64 binary to release assets
uses: actions/upload-release-asset@v1
- name: Generate SBOM (spdx)
id: spdx-builder
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dist/argocd-linux-amd64
asset_name: argocd-linux-amd64
asset_content_type: application/octet-stream
# defines the spdx/spdx-sbom-generator version to use.
SPDX_GEN_VERSION: v0.0.13
# defines the sigs.k8s.io/bom version to use.
SIGS_BOM_VERSION: v0.2.1
# comma delimited list of project relative folders to inspect for package
# managers (gomod, yarn, npm).
PROJECT_FOLDERS: ".,./ui"
# full qualified name of the docker image to be inspected
DOCKER_IMAGE: ${{env.IMAGE_NAMESPACE}}/argocd:v${{env.TARGET_VERSION}}
run: |
yarn install --cwd ./ui
go install github.com/spdx/spdx-sbom-generator/cmd/generator@$SPDX_GEN_VERSION
go install sigs.k8s.io/bom/cmd/bom@$SIGS_BOM_VERSION
# Generate SPDX for project dependencies analyzing package managers
for folder in $(echo $PROJECT_FOLDERS | sed "s/,/ /g")
do
generator -p $folder -o /tmp
done
# Generate SPDX for binaries analyzing the docker image
if [[ ! -z $DOCKER_IMAGE ]]; then
bom generate -o /tmp/bom-docker-image.spdx -i $DOCKER_IMAGE
fi
cd /tmp && tar -zcf sbom.tar.gz *.spdx
if: ${{ env.DRY_RUN != 'true' }}
- name: Upload argocd-darwin-amd64 binary to release assets
uses: actions/upload-release-asset@v1
- name: Sign sbom
run: |
cosign sign-blob --key env://COSIGN_PRIVATE_KEY /tmp/sbom.tar.gz > /tmp/sbom.tar.gz.sig
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dist/argocd-darwin-amd64
asset_name: argocd-darwin-amd64
asset_content_type: application/octet-stream
COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}}
COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
if: ${{ env.DRY_RUN != 'true' }}
- name: Upload argocd-windows-amd64 binary to release assets
uses: actions/upload-release-asset@v1
- name: Create GitHub release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dist/argocd-windows-amd64.exe
asset_name: argocd-windows-amd64.exe
asset_content_type: application/octet-stream
name: ${{ env.RELEASE_TAG }}
tag_name: ${{ env.RELEASE_TAG }}
draft: ${{ env.DRAFT_RELEASE }}
prerelease: ${{ env.PRE_RELEASE }}
body: ${{ steps.release-notes.outputs.content }}
files: |
dist/argocd-*
/tmp/sbom.tar.gz
/tmp/sbom.tar.gz.sig
if: ${{ env.DRY_RUN != 'true' }}
- name: Update homebrew formula
@@ -280,3 +328,4 @@ jobs:
set -ue
git push --delete origin ${SOURCE_TAG}
if: ${{ always() }}

View File

@@ -1,22 +0,0 @@
run:
timeout: 2m
skip-files:
- ".*\\.pb\\.go"
skip-dirs:
- pkg/client/
- vendor/
linters:
enable:
- vet
- deadcode
- goimports
- varcheck
- structcheck
- ineffassign
- unconvert
- unparam
linters-settings:
goimports:
local-prefixes: github.com/argoproj/argo-cd
service:
golangci-lint-version: 1.21.0

View File

@@ -1,6 +1,15 @@
# Changelog
## v2.1.0 (Unreleased)
## v2.1.1 (2021-08-25)
### Bug Fixes
- fix: password reset requirements (#7071)
- fix: Custom Styles feature is broken (#7067)
- fix(ui): Add State to props passed to Extensions (#7045)
- fix: keep uid_entrypoint.sh for backward compatibility (#7047)
## v2.1.0 (2021-08-20)
> [Upgrade instructions](./docs/operator-manual/upgrading/2.0-2.1.md)

View File

@@ -1,10 +1,10 @@
ARG BASE_IMAGE=docker.io/library/ubuntu:21.04
ARG BASE_IMAGE=docker.io/library/ubuntu:22.04
####################################################################################################
# Builder image
# 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.16.5 as builder
FROM docker.io/library/golang:1.16.11 as builder
RUN echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list
@@ -101,7 +101,7 @@ RUN NODE_ENV='production' NODE_ONLINE_ENV='online' yarn build
####################################################################################################
# Argo CD Build stage which performs the actual build of Argo CD binaries
####################################################################################################
FROM golang:1.16.5 as argocd-build
FROM docker.io/library/golang:1.16.11 as argocd-build
WORKDIR /go/src/github.com/argoproj/argo-cd
@@ -130,6 +130,7 @@ COPY --from=argocd-build /go/src/github.com/argoproj/argo-cd/dist/argocd* /usr/l
USER root
RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server
RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-repo-server
RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-cmp-server
RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-application-controller
RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-dex

View File

@@ -23,7 +23,7 @@ DOCKER_WORKDIR?=/go/src/github.com/argoproj/argo-cd
ARGOCD_PROCFILE?=Procfile
# Strict mode has been disabled in latest versions of mkdocs-material.
# Strict mode has been disabled in latest versions of mkdocs-material.
# Thus pointing to the older image of mkdocs-material matching the version used by argo-cd.
MKDOCS_DOCKER_IMAGE?=squidfunk/mkdocs-material:4.1.1
MKDOCS_RUN_ARGS?=
@@ -111,7 +111,7 @@ define run-in-test-client
bash -c "$(1)"
endef
#
#
define exec-in-test-server
docker exec -it -u $(shell id -u):$(shell id -g) -e ARGOCD_E2E_K3S=$(ARGOCD_E2E_K3S) argocd-test-server $(1)
endef
@@ -193,7 +193,7 @@ clientgen: ensure-gopath
.PHONY: clidocsgen
clidocsgen: ensure-gopath
go run tools/cmd-docs/main.go
go run tools/cmd-docs/main.go
.PHONY: codegen-local
codegen-local: ensure-gopath mod-vendor-local gogen protogen clientgen openapigen clidocsgen manifests-local
@@ -266,6 +266,7 @@ image:
ln -sfn ${DIST_DIR}/argocd ${DIST_DIR}/argocd-server
ln -sfn ${DIST_DIR}/argocd ${DIST_DIR}/argocd-application-controller
ln -sfn ${DIST_DIR}/argocd ${DIST_DIR}/argocd-repo-server
ln -sfn ${DIST_DIR}/argocd ${DIST_DIR}/argocd-cmp-server
ln -sfn ${DIST_DIR}/argocd ${DIST_DIR}/argocd-dex
cp Dockerfile.dev dist
docker build -t $(IMAGE_PREFIX)argocd:$(IMAGE_TAG) -f dist/Dockerfile.dev dist
@@ -409,12 +410,14 @@ start-e2e-local:
if test -d /tmp/argo-e2e/app/config/gpg; then rm -rf /tmp/argo-e2e/app/config/gpg/*; fi
mkdir -p /tmp/argo-e2e/app/config/gpg/keys && chmod 0700 /tmp/argo-e2e/app/config/gpg/keys
mkdir -p /tmp/argo-e2e/app/config/gpg/source && chmod 0700 /tmp/argo-e2e/app/config/gpg/source
mkdir -p /tmp/argo-e2e/app/config/plugin && chmod 0700 /tmp/argo-e2e/app/config/plugin
# set paths for locally managed ssh known hosts and tls certs data
ARGOCD_SSH_DATA_PATH=/tmp/argo-e2e/app/config/ssh \
ARGOCD_TLS_DATA_PATH=/tmp/argo-e2e/app/config/tls \
ARGOCD_GPG_DATA_PATH=/tmp/argo-e2e/app/config/gpg/source \
ARGOCD_GNUPGHOME=/tmp/argo-e2e/app/config/gpg/keys \
ARGOCD_GPG_ENABLED=$(ARGOCD_GPG_ENABLED) \
ARGOCD_PLUGINCONFIGFILEPATH=/tmp/argo-e2e/app/config/plugin \
ARGOCD_E2E_DISABLE_AUTH=false \
ARGOCD_ZJWT_FEATURE_FLAG=always \
ARGOCD_IN_CI=$(ARGOCD_IN_CI) \
@@ -451,6 +454,12 @@ start-local: mod-vendor-local dep-ui-local
ARGOCD_E2E_TEST=false \
goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START}
# Run goreman start with exclude option , provide exclude env variable with list of services
.PHONY: run
run:
bash ./hack/goreman-start.sh
# Runs pre-commit validation with the virtualized toolchain
.PHONY: pre-commit
pre-commit: codegen build lint test
@@ -533,3 +542,6 @@ dep-ui-local:
start-test-k8s:
go run ./hack/k8s
checksums:
sha256sum ./dist/$(BIN_NAME)-* | awk -F './dist/' '{print $$1 $$2}' > ./dist/$(BIN_NAME)-$(TARGET_VERSION)-checksums.txt

3
OWNERS
View File

@@ -9,6 +9,7 @@ approvers:
- jessesuen
- jgwest
- mayzhang2000
- rbreeze
reviewers:
- dthomson25
@@ -18,3 +19,5 @@ reviewers:
- reginapizza
- hblixt
- chetan-rns
- wanghong230
- pasha-codefresh

View File

@@ -1,8 +1,8 @@
controller: 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 go run ./cmd/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
api-server: 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-server go run ./cmd/main.go --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} "
dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/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.27.0 serve /dex.yaml"
redis: bash -c "if [ $ARGOCD_REDIS_LOCAL == 'true' ]; then redis-server --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; else docker run --rm --name argocd-redis -i -p ${ARGOCD_E2E_REDIS_PORT:-6379}:${ARGOCD_E2E_REDIS_PORT:-6379} redis:6.2.4-alpine --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi"
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} 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-repo-server go run ./cmd/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/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.30.2 dex serve /dex.yaml"
redis: bash -c "if [ \"$ARGOCD_REDIS_LOCAL\" == 'true' ]; then redis-server --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; else docker run --rm --name argocd-redis -i -p ${ARGOCD_E2E_REDIS_PORT:-6379}:${ARGOCD_E2E_REDIS_PORT:-6379} redis:6.2.7-alpine --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi"
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-/tmp/argo-e2e/app/config/plugin} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} 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-repo-server ARGOCD_GPG_ENABLED=${ARGOCD_GPG_ENABLED:-false} go run ./cmd/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
ui: sh -c 'cd ui && ${ARGOCD_E2E_YARN_CMD:-yarn} start'
git-server: test/fixture/testrepos/start-git.sh
helm-registry: test/fixture/testrepos/start-helm-registry.sh

View File

@@ -45,6 +45,8 @@ Participation in the Argo CD project is governed by the [CNCF Code of Conduct](h
### Blogs and Presentations
1. [Awesome-Argo: A Curated List of Awesome Projects and Resources Related to Argo](https://github.com/terrytangyuan/awesome-argo)
1. [GitOps Without Pipelines With ArgoCD Image Updater](https://youtu.be/avPUQin9kzU)
1. [Combining Argo CD (GitOps), Crossplane (Control Plane), And KubeVela (OAM)](https://youtu.be/eEcgn_gU3SM)
1. [How to Apply GitOps to Everything - Combining Argo CD and Crossplane](https://youtu.be/yrj4lmScKHQ)
1. [Couchbase - How To Run a Database Cluster in Kubernetes Using Argo CD](https://youtu.be/nkPoPaVzExY)
@@ -69,3 +71,4 @@ Participation in the Argo CD project is governed by the [CNCF Code of Conduct](h
1. [Applied GitOps with Argo CD](https://thenewstack.io/applied-gitops-with-argocd/)
1. [Solving configuration drift using GitOps with Argo CD](https://www.cncf.io/blog/2020/12/17/solving-configuration-drift-using-gitops-with-argo-cd/)
1. [Decentralized GitOps over environments](https://blogs.sap.com/2021/05/06/decentralized-gitops-over-environments/)
1. [How GitOps and Operators mark the rise of Infrastructure-As-Software](https://paytmlabs.com/blog/2021/10/how-to-improve-operational-work-with-operators-and-gitops/)

View File

@@ -1,6 +1,6 @@
# Security Policy for Argo CD
Version: **v1.1 (2020-06-29)**
Version: **v1.2 (2020-08-07)**
## Preface
@@ -56,13 +56,11 @@ We will do our best to react quickly on your inquiry, and to coordinate a fix
and disclosure with you. Sometimes, it might take a little longer for us to
react (e.g. out of office conditions), so please bear with us in these cases.
We will publish security advisiories using the Git Hub SA feature to keep our
community well informed, and will credit you for your findings (unless you
prefer to stay anonymous, of course).
We will publish security advisiories using the
[Git Hub Security Advisories](https://github.com/argoproj/argo-cd/security/advisories)
feature to keep our community well informed, and will credit you for your
findings (unless you prefer to stay anonymous, of course).
Please report vulnerabilities by e-mail to all of the following people:
Please report vulnerabilities by e-mail to the following address:
* jfischer@redhat.com
* Jesse_Suen@intuit.com
* Alexander_Matyushentsev@intuit.com
* Edward_Lee@intuit.com
* cncf-argo-security@lists.cncf.io

View File

@@ -9,6 +9,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [7shifts](https://www.7shifts.com/)
1. [Adevinta](https://www.adevinta.com/)
1. [Adventure](https://jp.adventurekk.com/)
1. [Akuity](https://akuity.io/)
1. [Alibaba Group](https://www.alibabagroup.com/)
1. [Ambassador Labs](https://www.getambassador.io/)
1. [Ant Group](https://www.antgroup.com/)
@@ -22,15 +23,17 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Beat](https://thebeat.co/en/)
1. [Beez Innovation Labs](https://www.beezlabs.com/)
1. [BioBox Analytics](https://biobox.io)
1. [BigPanda](https://bigpanda.io)
1. [BMW Group](https://www.bmwgroup.com/)
1. [Camptocamp](https://camptocamp.com)
1. [Capital One](https://www.capitalone.com)
1. [CARFAX](https://www.carfax.com)
1. [Celonis](https://www.celonis.com/)
1. [Chime](https://www.chime.com)
1. [Codefresh](https://www.codefresh.io/)
1. [Codility](https://www.codility.com/)
1. [Commonbond](https://commonbond.co/)
1. [Crédit Agricole](https://www.ca-cib.com)
1. [Crédit Agricole CIB](https://www.ca-cib.com)
1. [CROZ d.o.o.](https://croz.net/)
1. [CyberAgent](https://www.cyberagent.co.jp/en/)
1. [Cybozu](https://cybozu-global.com)
@@ -48,6 +51,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Garner](https://www.garnercorp.com)
1. [G DATA CyberDefense AG](https://www.gdata-software.com/)
1. [Generali Deutschland AG](https://www.generali.de/)
1. [Gitpod](https://www.gitpod.io)
1. [Glovo](https://www.glovoapp.com)
1. [GMETRI](https://gmetri.com/)
1. [Gojek](https://www.gojek.io/)
@@ -58,12 +62,14 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Hiya](https://hiya.com)
1. [Honestbank](https://honestbank.com)
1. [IBM](https://www.ibm.com/)
1. [IITS-Consulting](https://iits-consulting.de)
1. [Index Exchange](https://www.indexexchange.com/)
1. [InsideBoard](https://www.insideboard.com)
1. [Intuit](https://www.intuit.com/)
1. [Joblift](https://joblift.com/)
1. [JovianX](https://www.jovianx.com/)
1. [Karrot](https://www.daangn.com/)
1. [KarrotPay](https://www.daangnpay.com/)
1. [Kasa](https://kasa.co.kr/)
1. [Keptn](https://keptn.sh)
1. [Kinguin](https://www.kinguin.net/)
@@ -74,9 +80,11 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Lytt](https://www.lytt.co/)
1. [Major League Baseball](https://mlb.com)
1. [Mambu](https://www.mambu.com/)
1. [Mattermost](https://www.mattermost.com)
1. [Max Kelsen](https://www.maxkelsen.com/)
1. [MindSpore](https://mindspore.cn)
1. [Mirantis](https://mirantis.com/)
1. [mixi Group](https://mixi.co.jp/)
1. [Moengage](https://www.moengage.com/)
1. [Money Forward](https://corp.moneyforward.com/en/)
1. [MOO Print](https://www.moo.com/)
@@ -93,6 +101,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Opensurvey](https://www.opensurvey.co.kr/)
1. [Optoro](https://www.optoro.com/)
1. [Orbital Insight](https://orbitalinsight.com/)
1. [Packlink](https://www.packlink.com/)
1. [PayPay](https://paypay.ne.jp/)
1. [Peloton Interactive](https://www.onepeloton.com/)
1. [Pipefy](https://www.pipefy.com/)
@@ -110,9 +119,11 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Saildrone](https://www.saildrone.com/)
1. [Saloodo! GmbH](https://www.saloodo.com)
1. [Schwarz IT](https://jobs.schwarz/it-mission)
1. [Snyk](https://snyk.io/)
1. [Speee](https://speee.jp/)
1. [Spendesk](https://spendesk.com/)
1. [Sumo Logic](https://sumologic.com/)
1. [Sutpc](http://www.sutpc.com/)
1. [Swisscom](https://www.swisscom.ch)
1. [Swissquote](https://github.com/swissquote)
1. [Syncier](https://syncier.com/)
@@ -122,10 +133,12 @@ Currently, the following organizations are **officially** using Argo CD:
1. [ThousandEyes](https://www.thousandeyes.com/)
1. [Ticketmaster](https://ticketmaster.com)
1. [Tiger Analytics](https://www.tigeranalytics.com/)
1. [Tigera](https://www.tigera.io/)
1. [Toss](https://toss.im/en)
1. [tru.ID](https://tru.id)
1. [Twilio SendGrid](https://sendgrid.com)
1. [tZERO](https://www.tzero.com/)
1. [ungleich.ch](https://ungleich.ch/)
1. [UBIO](https://ub.io/)
1. [UFirstGroup](https://www.ufirstgroup.com/en/)
1. [Universidad Mesoamericana](https://www.umes.edu.gt/)
@@ -135,6 +148,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Volvo Cars](https://www.volvocars.com/)
1. [VSHN - The DevOps Company](https://vshn.ch/)
1. [Walkbase](https://www.walkbase.com/)
1. [Wehkamp](https://www.wehkamp.nl/)
1. [WeMo Scooter](https://www.wemoscooter.com/)
1. [Webstores](https://www.webstores.nl)
1. [Whitehat Berlin](https://whitehat.berlin) by Guido Maria Serra +Fenaroli
@@ -154,4 +168,13 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Beleza Na Web](https://www.belezanaweb.com.br/)
1. [MariaDB](https://mariadb.com)
1. [Lightricks](https://www.lightricks.com/)
1. [Snapp](https://snapp.ir/)
1. [RightRev](https://rightrev.com/)
1. [MeDirect](https://medirect.com.mt/)
1. [Snapp](https://snapp.ir/)
1. [Technacy](https://www.technacy.it/)
1. [freee](https://corp.freee.co.jp/en/company/)
1. [Youverify](https://youverify.co/)
1. [Keeeb](https://www.keeeb.com/)
1. [p3r](https://www.p3r.one/)
1. [Faro](https://www.faro.com/)
1. [Rise](https://www.risecard.eu/)

View File

@@ -1 +1 @@
2.1.12
2.2.16

View File

@@ -11,4 +11,4 @@ g = _, _
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
[matchers]
m = g(r.sub, p.sub) && globMatch(r.res, p.res) && globMatch(r.act, p.act) && globMatch(r.obj, p.obj)
m = g(r.sub, p.sub) && globOrRegexMatch(r.res, p.res) && globOrRegexMatch(r.act, p.act) && globOrRegexMatch(r.obj, p.obj)

View File

@@ -753,6 +753,11 @@
"type": "string",
"name": "resourceName",
"in": "query"
},
{
"type": "boolean",
"name": "previous",
"in": "query"
}
],
"responses": {
@@ -932,6 +937,11 @@
"type": "string",
"name": "resourceName",
"in": "query"
},
{
"type": "boolean",
"name": "previous",
"in": "query"
}
],
"responses": {
@@ -2081,6 +2091,37 @@
}
}
},
"/api/v1/projects/{name}/detailed": {
"get": {
"tags": [
"ProjectService"
],
"summary": "GetDetailedProject returns a project that include project, global project and scoped resources by name",
"operationId": "ProjectService_GetDetailedProject",
"parameters": [
{
"type": "string",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/projectDetailedProjectsResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/runtimeError"
}
}
}
}
},
"/api/v1/projects/{name}/events": {
"get": {
"tags": [
@@ -2873,6 +2914,12 @@
"description": "HTTP/HTTPS proxy to access the repository.",
"name": "proxy",
"in": "query"
},
{
"type": "string",
"description": "Reference between project and repository that allow you automatically to be added as item inside SourceRepos project entity.",
"name": "project",
"in": "query"
}
],
"responses": {
@@ -3633,9 +3680,18 @@
"statusBadgeEnabled": {
"type": "boolean"
},
"trackingMethod": {
"type": "string"
},
"uiBannerContent": {
"type": "string"
},
"uiBannerPermanent": {
"type": "boolean"
},
"uiBannerPosition": {
"type": "string"
},
"uiBannerURL": {
"type": "string"
},
@@ -3687,6 +3743,32 @@
}
}
},
"projectDetailedProjectsResponse": {
"type": "object",
"properties": {
"clusters": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1Cluster"
}
},
"globalProjects": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1AppProject"
}
},
"project": {
"$ref": "#/definitions/v1alpha1AppProject"
},
"repositories": {
"type": "array",
"items": {
"$ref": "#/definitions/v1alpha1Repository"
}
}
}
},
"projectEmptyResponse": {
"type": "object"
},
@@ -4299,6 +4381,10 @@
"description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created.\nThe only valid values for this field are 'Apply' and 'Update'.",
"type": "string"
},
"subresource": {
"description": "Subresource is the name of the subresource used to update that object, or\nempty string if the object was updated through the main resource. The\nvalue of this field is used to distinguish between managers, even if they\nshare the same name. For example, a status update will be distinct from a\nregular update using the same manager name.\nNote that the APIVersion field is not related to the Subresource field and\nit always corresponds to the version of the main resource.",
"type": "string"
},
"time": {
"$ref": "#/definitions/v1Time"
}
@@ -4453,7 +4539,7 @@
},
"v1ObjectReference": {
"type": "object",
"title": "ObjectReference contains enough information to let you inspect or modify the referred object.\n---\nNew uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.\n 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.\n 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular\n restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\".\n Those cannot be well described when embedded.\n 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.\n 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity\n during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple\n and the version of the actual struct is irrelevant.\n 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type\n will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.\nInstead of using this type, create a locally provided and used type that is well-focused on your reference.\nFor example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object",
"title": "ObjectReference contains enough information to let you inspect or modify the referred object.\n---\nNew uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.\n 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.\n 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular\n restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\".\n Those cannot be well described when embedded.\n 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.\n 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity\n during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple\n and the version of the actual struct is irrelevant.\n 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type\n will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.\nInstead of using this type, create a locally provided and used type that is well-focused on your reference.\nFor example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\n+structType=atomic",
"properties": {
"apiVersion": {
"type": "string",
@@ -4486,8 +4572,8 @@
}
},
"v1OwnerReference": {
"description": "OwnerReference contains enough information to let you identify an owning\nobject. An owning object must be in the same namespace as the dependent, or\nbe cluster-scoped, so there is no namespace field.",
"type": "object",
"title": "OwnerReference contains enough information to let you identify an owning\nobject. An owning object must be in the same namespace as the dependent, or\nbe cluster-scoped, so there is no namespace field.\n+structType=atomic",
"properties": {
"apiVersion": {
"description": "API version of the referent.",
@@ -4826,6 +4912,10 @@
"$ref": "#/definitions/v1alpha1HelmParameter"
}
},
"passCredentials": {
"type": "boolean",
"title": "PassCredentials pass credentials to all domains (Helm's --pass-credentials)"
},
"releaseName": {
"type": "string",
"title": "ReleaseName is the Helm release name to use. If omitted it will use the application name"
@@ -5122,6 +5212,13 @@
"type": "object",
"title": "Cluster is the definition of a cluster resource",
"properties": {
"annotations": {
"type": "object",
"title": "Annotations for cluster secret metadata",
"additionalProperties": {
"type": "string"
}
},
"clusterResources": {
"description": "Indicates if cluster level resources should be managed. This setting is used only if cluster is connected in a namespaced mode.",
"type": "boolean"
@@ -5135,6 +5232,13 @@
"info": {
"$ref": "#/definitions/v1alpha1ClusterInfo"
},
"labels": {
"type": "object",
"title": "Labels for cluster secret metadata",
"additionalProperties": {
"type": "string"
}
},
"name": {
"type": "string",
"title": "Name of the cluster. If omitted, will use the server address"
@@ -5146,6 +5250,10 @@
"type": "string"
}
},
"project": {
"type": "string",
"title": "Reference between project and cluster that allow you automatically to be added as item inside Destinations project entity"
},
"refreshRequestedAt": {
"$ref": "#/definitions/v1Time"
},
@@ -5292,6 +5400,9 @@
"init": {
"$ref": "#/definitions/v1alpha1Command"
},
"lockRepo": {
"type": "boolean"
},
"name": {
"type": "string"
}
@@ -5862,6 +5973,10 @@
"type": "string",
"title": "Password contains the password or PAT used for authenticating at the remote repository"
},
"project": {
"type": "string",
"title": "Reference between project and repository that allow you automatically to be added as item inside SourceRepos project entity"
},
"proxy": {
"type": "string",
"title": "Proxy specifies the HTTP/HTTPS proxy used to access the repo"
@@ -6550,6 +6665,10 @@
"schedule": {
"type": "string",
"title": "Schedule is the time the window will begin, specified in cron format"
},
"timeZone": {
"type": "string",
"title": "TimeZone of the sync that will be applied to the schedule"
}
}
},

View File

@@ -49,6 +49,7 @@ func NewCommand() *cobra.Command {
glogLevel int
metricsPort int
metricsCacheExpiration time.Duration
metricsAplicationLabels []string
kubectlParallelismLimit int64
cacheSrc func() (*appstatecache.Cache, error)
redisClient *redis.Client
@@ -110,10 +111,14 @@ func NewCommand() *cobra.Command {
errors.CheckError(err)
cache.Cache.SetClient(cacheutil.NewTwoLevelClient(cache.Cache.GetClient(), 10*time.Minute))
settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace)
var appController *controller.ApplicationController
settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace, settings.WithRepoOrClusterChangedHandler(func() {
appController.InvalidateProjectsCache()
}))
kubectl := kubeutil.NewKubectl()
clusterFilter := getClusterFilter()
appController, err := controller.NewApplicationController(
appController, err = controller.NewApplicationController(
namespace,
settingsMgr,
kubeClient,
@@ -125,6 +130,7 @@ func NewCommand() *cobra.Command {
time.Duration(selfHealTimeoutSeconds)*time.Second,
metricsPort,
metricsCacheExpiration,
metricsAplicationLabels,
kubectlParallelismLimit,
clusterFilter)
errors.CheckError(err)
@@ -158,6 +164,7 @@ func NewCommand() *cobra.Command {
command.Flags().Int64Var(&kubectlParallelismLimit, "kubectl-parallelism-limit", 20, "Number of allowed concurrent kubectl fork/execs. Any value less the 1 means no limit.")
command.Flags().BoolVar(&repoServerPlaintext, "repo-server-plaintext", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT", false), "Disable TLS on connections to repo server")
command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server")
command.Flags().StringSliceVar(&metricsAplicationLabels, "metrics-application-labels", []string{}, "List of Application labels that will be added to the argocd_application_labels metric")
cacheSrc = appstatecache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {
redisClient = client
})

View File

@@ -0,0 +1,58 @@
package commands
import (
"time"
"github.com/argoproj/pkg/stats"
"github.com/spf13/cobra"
cmdutil "github.com/argoproj/argo-cd/v2/cmd/util"
"github.com/argoproj/argo-cd/v2/cmpserver"
"github.com/argoproj/argo-cd/v2/cmpserver/plugin"
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/errors"
)
const (
// CLIName is the name of the CLI
cliName = "argocd-cmp-server"
)
func NewCommand() *cobra.Command {
var (
configFilePath string
)
var command = cobra.Command{
Use: cliName,
Short: "Run ArgoCD ConfigManagementPlugin Server",
Long: "ArgoCD ConfigManagementPlugin Server is an internal service which runs as sidecar container in reposerver deployment. It can be configured by following options.",
DisableAutoGenTag: true,
RunE: func(c *cobra.Command, args []string) error {
cli.SetLogFormat(cmdutil.LogFormat)
cli.SetLogLevel(cmdutil.LogLevel)
config, err := plugin.ReadPluginConfig(configFilePath)
errors.CheckError(err)
server, err := cmpserver.NewServer(plugin.CMPServerInitConstants{
PluginConfig: *config,
})
errors.CheckError(err)
// register dumper
stats.RegisterStackDumper()
stats.StartStatsTicker(10 * time.Minute)
stats.RegisterHeapDumper("memprofile")
// run argocd-cmp-server server
server.Run()
return nil
},
}
command.Flags().StringVar(&cmdutil.LogFormat, "logformat", "text", "Set the logging format. One of: text|json")
command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
command.Flags().StringVar(&configFilePath, "config-dir-path", common.DefaultPluginConfigFilePath, "Config management plugin configuration file location, Default is '/home/argocd/cmp-server/config/'")
return &command
}

View File

@@ -13,6 +13,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"google.golang.org/grpc/health/grpc_health_v1"
"k8s.io/apimachinery/pkg/api/resource"
cmdutil "github.com/argoproj/argo-cd/v2/cmd/util"
"github.com/argoproj/argo-cd/v2/common"
@@ -63,14 +64,15 @@ func getPauseGenerationOnFailureForRequests() int {
func NewCommand() *cobra.Command {
var (
parallelismLimit int64
listenPort int
metricsPort int
cacheSrc func() (*reposervercache.Cache, error)
tlsConfigCustomizer tls.ConfigCustomizer
tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error)
redisClient *redis.Client
disableTLS bool
parallelismLimit int64
listenPort int
metricsPort int
cacheSrc func() (*reposervercache.Cache, error)
tlsConfigCustomizer tls.ConfigCustomizer
tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error)
redisClient *redis.Client
disableTLS bool
maxCombinedDirectoryManifestsSize string
)
var command = cobra.Command{
Use: cliName,
@@ -90,13 +92,17 @@ func NewCommand() *cobra.Command {
cache, err := cacheSrc()
errors.CheckError(err)
maxCombinedDirectoryManifestsQuantity, err := resource.ParseQuantity(maxCombinedDirectoryManifestsSize)
errors.CheckError(err)
metricsServer := metrics.NewMetricsServer()
cacheutil.CollectMetrics(redisClient, metricsServer)
server, err := reposerver.NewServer(metricsServer, cache, tlsConfigCustomizer, repository.RepoServerInitConstants{
ParallelismLimit: parallelismLimit,
ParallelismLimit: parallelismLimit,
PauseGenerationAfterFailedGenerationAttempts: getPauseGenerationAfterFailedGenerationAttempts(),
PauseGenerationOnFailureForMinutes: getPauseGenerationOnFailureForMinutes(),
PauseGenerationOnFailureForRequests: getPauseGenerationOnFailureForRequests(),
MaxCombinedDirectoryManifestsSize: maxCombinedDirectoryManifestsQuantity,
})
errors.CheckError(err)
@@ -160,6 +166,7 @@ func NewCommand() *cobra.Command {
command.Flags().IntVar(&listenPort, "port", common.DefaultPortRepoServer, "Listen on given port for incoming connections")
command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortRepoServerMetrics, "Start metrics server on given port")
command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_TLS", false), "Disable TLS on the gRPC endpoint")
command.Flags().StringVar(&maxCombinedDirectoryManifestsSize, "max-combined-directory-manifests-size", env.StringFromEnv("ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE", "10M"), "Max combined size of manifest files in a directory-type Application")
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {

View File

@@ -54,7 +54,19 @@ func NewAccountUpdatePasswordCommand(clientOpts *argocdclient.ClientOptions) *co
)
var command = &cobra.Command{
Use: "update-password",
Short: "Update password",
Short: "Update an account's password",
Long: `
This command can be used to update the password of the currently logged on
user, or an arbitrary local user account when the currently logged on user
has appropriate RBAC permissions to change other accounts.
`,
Example: `
# Update the current user's password
argocd account update-password
# Update the password for user foobar
argocd account update-password --account foobar
`,
Run: func(c *cobra.Command, args []string) {
if len(args) != 0 {
c.HelpFunc()(c, args)
@@ -67,16 +79,20 @@ func NewAccountUpdatePasswordCommand(clientOpts *argocdclient.ClientOptions) *co
userInfo := getCurrentAccount(acdClient)
if userInfo.Iss == sessionutil.SessionManagerClaimsIssuer && currentPassword == "" {
fmt.Print("*** Enter current password: ")
fmt.Printf("*** Enter password of currently logged in user (%s): ", userInfo.Username)
password, err := term.ReadPassword(int(os.Stdin.Fd()))
errors.CheckError(err)
currentPassword = string(password)
fmt.Print("\n")
}
if account == "" {
account = userInfo.Username
}
if newPassword == "" {
var err error
newPassword, err = cli.ReadAndConfirmPassword()
newPassword, err = cli.ReadAndConfirmPassword(account)
errors.CheckError(err)
}
@@ -111,7 +127,7 @@ func NewAccountUpdatePasswordCommand(clientOpts *argocdclient.ClientOptions) *co
},
}
command.Flags().StringVar(&currentPassword, "current-password", "", "current password you wish to change")
command.Flags().StringVar(&currentPassword, "current-password", "", "password of the currently logged on user")
command.Flags().StringVar(&newPassword, "new-password", "", "new password you want to update to")
command.Flags().StringVar(&account, "account", "", "an account name that should be updated. Defaults to current user account")
return command

View File

@@ -10,6 +10,8 @@ import (
"sort"
"time"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/ghodss/yaml"
"github.com/spf13/cobra"
apiv1 "k8s.io/api/core/v1"
@@ -88,9 +90,12 @@ func NewGenAppSpecCommand() *cobra.Command {
argocd admin app generate-spec ksane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane
`,
Run: func(c *cobra.Command, args []string) {
app, err := cmdutil.ConstructApp(fileURL, appName, labels, annotations, args, appOpts, c.Flags())
apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags())
errors.CheckError(err)
if len(apps) > 1 {
errors.CheckError(fmt.Errorf("failed to generate spec, more than one application is not supported"))
}
app := apps[0]
if app.Name == "" {
c.HelpFunc()(c, args)
os.Exit(1)
@@ -329,11 +334,11 @@ func reconcileApplications(
settingsMgr := settings.NewSettingsManager(context.Background(), kubeClientset, namespace)
argoDB := db.NewDB(namespace, settingsMgr, kubeClientset)
appInformerFactory := appinformers.NewFilteredSharedInformerFactory(
appInformerFactory := appinformers.NewSharedInformerFactoryWithOptions(
appClientset,
1*time.Hour,
namespace,
func(options *v1.ListOptions) {},
appinformers.WithNamespace(namespace),
appinformers.WithTweakListOptions(func(options *v1.ListOptions) {}),
)
appInformer := appInformerFactory.Argoproj().V1alpha1().Applications().Informer()
@@ -350,7 +355,7 @@ func reconcileApplications(
return true
}, func(r *http.Request) error {
return nil
})
}, []string{})
if err != nil {
return nil, err
@@ -366,7 +371,7 @@ func reconcileApplications(
)
appStateManager := controller.NewAppStateManager(
argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second)
argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking())
appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(context.Background(), v1.ListOptions{LabelSelector: selector})
if err != nil {
@@ -408,5 +413,5 @@ func reconcileApplications(
}
func newLiveStateCache(argoDB db.ArgoDB, appInformer kubecache.SharedIndexInformer, settingsMgr *settings.SettingsManager, server *metrics.MetricsServer) cache.LiveStateCache {
return cache.NewLiveStateCache(argoDB, appInformer, settingsMgr, kubeutil.NewKubectl(), server, func(managedByApp map[string]bool, ref apiv1.ObjectReference) {}, nil)
return cache.NewLiveStateCache(argoDB, appInformer, settingsMgr, kubeutil.NewKubectl(), server, func(managedByApp map[string]bool, ref apiv1.ObjectReference) {}, nil, argo.NewResourceTracking())
}

View File

@@ -35,6 +35,7 @@ import (
"github.com/argoproj/argo-cd/v2/util/glob"
kubeutil "github.com/argoproj/argo-cd/v2/util/kube"
"github.com/argoproj/argo-cd/v2/util/settings"
"github.com/argoproj/argo-cd/v2/util/text/label"
)
func NewClusterCommand(pathOpts *clientcmd.PathOptions) *cobra.Command {
@@ -508,6 +509,8 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command
bearerToken string
generateToken bool
outputFormat string
labels []string
annotations []string
)
var command = &cobra.Command{
Use: "generate-spec CONTEXT",
@@ -561,7 +564,13 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command
if clusterOpts.Name != "" {
contextName = clusterOpts.Name
}
clst := cmdutil.NewCluster(contextName, clusterOpts.Namespaces, clusterOpts.ClusterResources, conf, bearerToken, awsAuthConf, execProviderConf)
labelsMap, err := label.Parse(labels)
errors.CheckError(err)
annotationsMap, err := label.Parse(annotations)
errors.CheckError(err)
clst := cmdutil.NewCluster(contextName, clusterOpts.Namespaces, clusterOpts.ClusterResources, conf, bearerToken, awsAuthConf, execProviderConf, labelsMap, annotationsMap)
if clusterOpts.InCluster {
clst.Server = argoappv1.KubernetesInternalAPIServerAddr
}
@@ -590,6 +599,8 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command
command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "argocd-manager", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default \"%s\" SA will be used", clusterauth.ArgoCDManagerServiceAccount))
command.Flags().StringVar(&clusterOpts.SystemNamespace, "system-namespace", common.DefaultSystemNamespace, "Use different system namespace")
command.Flags().StringVarP(&outputFormat, "output", "o", "yaml", "Output format. One of: json|yaml")
command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)")
command.Flags().StringArrayVar(&annotations, "annotation", nil, "Set metadata annotations (e.g. --annotation key=value)")
cmdutil.AddClusterFlags(command, &clusterOpts)
return command
}
@@ -598,7 +609,7 @@ func GenerateToken(clusterOpts cmdutil.ClusterOptions, conf *rest.Config) (strin
clientset, err := kubernetes.NewForConfig(conf)
errors.CheckError(err)
bearerToken, err := clusterauth.GetServiceAccountBearerToken(clientset, clusterOpts.SystemNamespace, clusterOpts.ServiceAccount)
bearerToken, err := clusterauth.GetServiceAccountBearerToken(clientset, clusterOpts.SystemNamespace, clusterOpts.ServiceAccount, common.BearerTokenTimeout)
if err != nil {
return "", err
}

View File

@@ -2,6 +2,7 @@ package admin
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
@@ -63,7 +64,10 @@ func NewProjectAllowListGenCommand() *cobra.Command {
}()
}
globalProj := generateProjectAllowList(clientConfig, clusterRoleFileName, projName)
resourceList, err := getResourceList(clientConfig)
errors.CheckError(err)
globalProj, err := generateProjectAllowList(resourceList, clusterRoleFileName, projName)
errors.CheckError(err)
yamlBytes, err := yaml.Marshal(globalProj)
errors.CheckError(err)
@@ -78,23 +82,38 @@ func NewProjectAllowListGenCommand() *cobra.Command {
return command
}
func generateProjectAllowList(clientConfig clientcmd.ClientConfig, clusterRoleFileName string, projName string) v1alpha1.AppProject {
func getResourceList(clientConfig clientcmd.ClientConfig) ([]*metav1.APIResourceList, error) {
config, err := clientConfig.ClientConfig()
if err != nil {
return nil, fmt.Errorf("error while creating client config: %s", err)
}
disco, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
return nil, fmt.Errorf("error while creating discovery client: %s", err)
}
serverResources, err := disco.ServerPreferredResources()
if err != nil {
return nil, fmt.Errorf("error while getting server resources: %s", err)
}
return serverResources, nil
}
func generateProjectAllowList(serverResources []*metav1.APIResourceList, clusterRoleFileName string, projName string) (*v1alpha1.AppProject, error) {
yamlBytes, err := ioutil.ReadFile(clusterRoleFileName)
errors.CheckError(err)
if err != nil {
return nil, fmt.Errorf("error reading cluster role file: %s", err)
}
var obj unstructured.Unstructured
err = yaml.Unmarshal(yamlBytes, &obj)
errors.CheckError(err)
if err != nil {
return nil, fmt.Errorf("error unmarshalling cluster role file yaml: %s", err)
}
clusterRole := &rbacv1.ClusterRole{}
err = scheme.Scheme.Convert(&obj, clusterRole, nil)
errors.CheckError(err)
config, err := clientConfig.ClientConfig()
errors.CheckError(err)
disco, err := discovery.NewDiscoveryClientForConfig(config)
errors.CheckError(err)
serverResources, err := disco.ServerPreferredResources()
errors.CheckError(err)
if err != nil {
return nil, fmt.Errorf("error converting cluster role yaml into ClusterRole struct: %s", err)
}
resourceList := make([]metav1.GroupKind, 0)
for _, rule := range clusterRole.Rules {
@@ -140,5 +159,5 @@ func generateProjectAllowList(clientConfig clientcmd.ClientConfig, clusterRoleFi
Spec: v1alpha1.AppProjectSpec{},
}
globalProj.Spec.NamespaceResourceWhitelist = resourceList
return globalProj
return &globalProj, nil
}

View File

@@ -1,57 +1,20 @@
package admin
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/undefinedlabs/go-mpatch"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/discovery"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
func TestProjectAllowListGen(t *testing.T) {
useMock := true
rules := clientcmd.NewDefaultClientConfigLoadingRules()
overrides := &clientcmd.ConfigOverrides{}
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides)
if useMock {
var patchClientConfig *mpatch.Patch
patchClientConfig, err := mpatch.PatchInstanceMethodByName(reflect.TypeOf(clientConfig), "ClientConfig", func(*clientcmd.DeferredLoadingClientConfig) (*restclient.Config, error) {
return nil, nil
})
assert.NoError(t, err)
patch, err := mpatch.PatchMethod(discovery.NewDiscoveryClientForConfig, func(c *restclient.Config) (*discovery.DiscoveryClient, error) {
return &discovery.DiscoveryClient{LegacyPrefix: "/api"}, nil
})
assert.NoError(t, err)
var patchSeverPreferredResources *mpatch.Patch
discoClient := &discovery.DiscoveryClient{}
patchSeverPreferredResources, err = mpatch.PatchInstanceMethodByName(reflect.TypeOf(discoClient), "ServerPreferredResources", func(*discovery.DiscoveryClient) ([]*metav1.APIResourceList, error) {
res := metav1.APIResource{
Name: "services",
Kind: "Service",
}
resourceList := []*metav1.APIResourceList{{APIResources: []metav1.APIResource{res}}}
return resourceList, nil
})
assert.NoError(t, err)
defer func() {
err = patchClientConfig.Unpatch()
assert.NoError(t, err)
err = patch.Unpatch()
assert.NoError(t, err)
err = patchSeverPreferredResources.Unpatch()
err = patch.Unpatch()
}()
res := metav1.APIResource{
Name: "services",
Kind: "Service",
}
resourceList := []*metav1.APIResourceList{{APIResources: []metav1.APIResource{res}}}
globalProj := generateProjectAllowList(clientConfig, "testdata/test_clusterrole.yaml", "testproj")
globalProj, err := generateProjectAllowList(resourceList, "testdata/test_clusterrole.yaml", "testproj")
assert.NoError(t, err)
assert.True(t, len(globalProj.Spec.NamespaceResourceWhitelist) > 0)
}

View File

@@ -401,7 +401,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo
executeResourceOverrideCommand(cmdCtx, args, func(res unstructured.Unstructured, override v1alpha1.ResourceOverride, overrides map[string]v1alpha1.ResourceOverride) {
gvk := res.GroupVersionKind()
if len(override.IgnoreDifferences.JSONPointers) == 0 {
if len(override.IgnoreDifferences.JSONPointers) == 0 && len(override.IgnoreDifferences.JQPathExpressions) == 0 {
_, _ = fmt.Printf("Ignore differences are not configured for '%s/%s'\n", gvk.Group, gvk.Kind)
return
}

View File

@@ -14,6 +14,8 @@ import (
"time"
"unicode/utf8"
"github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/argoproj/gitops-engine/pkg/diff"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/sync/hook"
@@ -25,6 +27,7 @@ import (
"github.com/spf13/cobra"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
@@ -48,7 +51,6 @@ import (
"github.com/argoproj/argo-cd/v2/util/errors"
"github.com/argoproj/argo-cd/v2/util/git"
argoio "github.com/argoproj/argo-cd/v2/util/io"
argokube "github.com/argoproj/argo-cd/v2/util/kube"
"github.com/argoproj/argo-cd/v2/util/templates"
"github.com/argoproj/argo-cd/v2/util/text/label"
)
@@ -92,6 +94,7 @@ func NewApplicationCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman
command.AddCommand(NewApplicationEditCommand(clientOpts))
command.AddCommand(NewApplicationPatchCommand(clientOpts))
command.AddCommand(NewApplicationPatchResourceCommand(clientOpts))
command.AddCommand(NewApplicationDeleteResourceCommand(clientOpts))
command.AddCommand(NewApplicationResourceActionsCommand(clientOpts))
command.AddCommand(NewApplicationListResourcesCommand(clientOpts))
command.AddCommand(NewApplicationLogsCommand(clientOpts))
@@ -133,24 +136,27 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.
Run: func(c *cobra.Command, args []string) {
argocdClient := argocdclient.NewClientOrDie(clientOpts)
app, err := cmdutil.ConstructApp(fileURL, appName, labels, annotations, args, appOpts, c.Flags())
apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags())
errors.CheckError(err)
if app.Name == "" {
c.HelpFunc()(c, args)
os.Exit(1)
for _, app := range apps {
if app.Name == "" {
c.HelpFunc()(c, args)
os.Exit(1)
}
conn, appIf := argocdClient.NewApplicationClientOrDie()
defer argoio.Close(conn)
appCreateRequest := applicationpkg.ApplicationCreateRequest{
Application: *app,
Upsert: &upsert,
Validate: &appOpts.Validate,
}
created, err := appIf.Create(context.Background(), &appCreateRequest)
errors.CheckError(err)
fmt.Printf("application '%s' created\n", created.ObjectMeta.Name)
}
conn, appIf := argocdClient.NewApplicationClientOrDie()
defer argoio.Close(conn)
appCreateRequest := applicationpkg.ApplicationCreateRequest{
Application: *app,
Upsert: &upsert,
Validate: &appOpts.Validate,
}
created, err := appIf.Create(context.Background(), &appCreateRequest)
errors.CheckError(err)
fmt.Printf("application '%s' created\n", created.ObjectMeta.Name)
},
}
command.Flags().StringVar(&appName, "name", "", "A name for the app, ignored if a file is set (DEPRECATED)")
@@ -666,6 +672,10 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C
}
}
}
if app.Spec.Source.Helm.PassCredentials {
app.Spec.Source.Helm.PassCredentials = false
updated = true
}
}
if app.Spec.Source.Plugin != nil {
@@ -732,8 +742,8 @@ func liveObjects(resources []*argoappv1.ResourceDiff) ([]*unstructured.Unstructu
}
func getLocalObjects(app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, kustomizeOptions *argoappv1.KustomizeOptions,
configManagementPlugins []*argoappv1.ConfigManagementPlugin) []*unstructured.Unstructured {
manifestStrings := getLocalObjectsString(app, local, localRepoRoot, appLabelKey, kubeVersion, kustomizeOptions, configManagementPlugins)
configManagementPlugins []*argoappv1.ConfigManagementPlugin, trackingMethod string) []*unstructured.Unstructured {
manifestStrings := getLocalObjectsString(app, local, localRepoRoot, appLabelKey, kubeVersion, kustomizeOptions, configManagementPlugins, trackingMethod)
objs := make([]*unstructured.Unstructured, len(manifestStrings))
for i := range manifestStrings {
obj := unstructured.Unstructured{}
@@ -745,7 +755,7 @@ func getLocalObjects(app *argoappv1.Application, local, localRepoRoot, appLabelK
}
func getLocalObjectsString(app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, kustomizeOptions *argoappv1.KustomizeOptions,
configManagementPlugins []*argoappv1.ConfigManagementPlugin) []string {
configManagementPlugins []*argoappv1.ConfigManagementPlugin, trackingMethod string) []string {
res, err := repository.GenerateManifests(local, localRepoRoot, app.Spec.Source.TargetRevision, &repoapiclient.ManifestRequest{
Repo: &argoappv1.Repository{Repo: app.Spec.Source.RepoURL},
@@ -756,7 +766,8 @@ func getLocalObjectsString(app *argoappv1.Application, local, localRepoRoot, app
KustomizeOptions: kustomizeOptions,
KubeVersion: kubeVersion,
Plugins: configManagementPlugins,
}, true)
TrackingMethod: trackingMethod,
}, true, resource.MustParse("0"))
errors.CheckError(err)
return res.Manifests
@@ -841,7 +852,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
defer argoio.Close(conn)
cluster, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server})
errors.CheckError(err)
localObjs := groupObjsByKey(getLocalObjects(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins), liveObjs, app.Spec.Destination.Namespace)
localObjs := groupObjsByKey(getLocalObjects(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod), liveObjs, app.Spec.Destination.Namespace)
items = groupObjsForDiff(resources, localObjs, items, argoSettings, appName)
} else if revision != "" {
var unstructureds []*unstructured.Unstructured
@@ -923,6 +934,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
}
func groupObjsForDiff(resources *application.ManagedResourcesResponse, objs map[kube.ResourceKey]*unstructured.Unstructured, items []objKeyLiveTarget, argoSettings *settings.Settings, appName string) []objKeyLiveTarget {
resourceTracking := argo.NewResourceTracking()
for _, res := range resources.Items {
var live = &unstructured.Unstructured{}
err := json.Unmarshal([]byte(res.NormalizedLiveState), &live)
@@ -936,7 +948,7 @@ func groupObjsForDiff(resources *application.ManagedResourcesResponse, objs map[
}
if local, ok := objs[key]; ok || live != nil {
if local != nil && !kube.IsCRD(local) {
err = argokube.SetAppInstanceLabel(local, argoSettings.AppLabelKey, appName)
err = resourceTracking.SetAppInstance(local, argoSettings.AppLabelKey, appName, "", argoappv1.TrackingMethod(argoSettings.GetTrackingMethod()))
errors.CheckError(err)
}
@@ -1269,6 +1281,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
timeout uint
strategy string
force bool
replace bool
async bool
retryLimit int64
retryBackoffDuration time.Duration
@@ -1376,18 +1389,35 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
cluster, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server})
errors.CheckError(err)
argoio.Close(conn)
localObjsStrings = getLocalObjectsString(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins)
localObjsStrings = getLocalObjectsString(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod)
}
syncOptionsFactory := func() *applicationpkg.SyncOptions {
syncOptions := applicationpkg.SyncOptions{}
items := make([]string, 0)
if replace {
items = append(items, common.SyncOptionReplace)
}
if len(items) == 0 {
// for prevent send even empty array if not need
return nil
}
syncOptions.Items = items
return &syncOptions
}
syncReq := applicationpkg.ApplicationSyncRequest{
Name: &appName,
DryRun: dryRun,
Revision: revision,
Resources: selectedResources,
Prune: prune,
Manifests: localObjsStrings,
Infos: getInfos(infos),
Name: &appName,
DryRun: dryRun,
Revision: revision,
Resources: selectedResources,
Prune: prune,
Manifests: localObjsStrings,
Infos: getInfos(infos),
SyncOptions: syncOptionsFactory(),
}
switch strategy {
case "apply":
syncReq.Strategy = &argoappv1.SyncStrategy{Apply: &argoappv1.SyncStrategyApply{}}
@@ -1444,6 +1474,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
command.Flags().Int64Var(&retryBackoffFactor, "retry-backoff-factor", argoappv1.DefaultSyncRetryFactor, "Factor multiplies the base duration after each failed retry")
command.Flags().StringVar(&strategy, "strategy", "", "Sync strategy (one of: apply|hook)")
command.Flags().BoolVar(&force, "force", false, "Use a force apply")
command.Flags().BoolVar(&replace, "replace", false, "Use a kubectl create/replace instead apply")
command.Flags().BoolVar(&async, "async", false, "Do not wait for application to sync before continuing")
command.Flags().StringVar(&local, "local", "", "Path to a local directory. When this flag is present no git queries will be made")
command.Flags().StringVar(&localRepoRoot, "local-repo-root", "/", "Path to the repository root. Used together with --local allows setting the repository root")
@@ -2202,3 +2233,59 @@ func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions)
return command
}
func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var resourceName string
var namespace string
var kind string
var group string
var force bool
var orphan bool
var all bool
command := &cobra.Command{
Use: "delete-resource APPNAME",
Short: "Delete resource in an application",
}
command.Flags().StringVar(&resourceName, "resource-name", "", "Name of resource")
command.Flags().StringVar(&kind, "kind", "", "Kind")
err := command.MarkFlagRequired("kind")
errors.CheckError(err)
command.Flags().StringVar(&group, "group", "", "Group")
command.Flags().StringVar(&namespace, "namespace", "", "Namespace")
command.Flags().BoolVar(&force, "force", false, "Indicates whether to orphan the dependents of the deleted resource")
command.Flags().BoolVar(&orphan, "orphan", false, "Indicates whether to force delete the resource")
command.Flags().BoolVar(&all, "all", false, "Indicates whether to patch multiple matching of resources")
command.Run = func(c *cobra.Command, args []string) {
if len(args) != 1 {
c.HelpFunc()(c, args)
os.Exit(1)
}
appName := args[0]
conn, appIf := argocdclient.NewClientOrDie(clientOpts).NewApplicationClientOrDie()
defer argoio.Close(conn)
ctx := context.Background()
resources, err := appIf.ManagedResources(ctx, &applicationpkg.ResourcesQuery{ApplicationName: &appName})
errors.CheckError(err)
objectsToDelete := filterResources(command, resources.Items, group, kind, namespace, resourceName, all)
for i := range objectsToDelete {
obj := objectsToDelete[i]
gvk := obj.GroupVersionKind()
_, err = appIf.DeleteResource(ctx, &applicationpkg.ApplicationResourceDeleteRequest{
Name: &appName,
Namespace: obj.GetNamespace(),
ResourceName: obj.GetName(),
Version: gvk.Version,
Group: gvk.Group,
Kind: gvk.Kind,
Force: &force,
Orphan: &orphan,
})
errors.CheckError(err)
log.Infof("Resource '%s' deleted", obj.GetName())
}
}
return command
}

View File

@@ -4,13 +4,18 @@ import (
"context"
"fmt"
"os"
"regexp"
"strings"
"text/tabwriter"
"github.com/mattn/go-isatty"
"k8s.io/client-go/kubernetes"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/text/label"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
cmdutil "github.com/argoproj/argo-cd/v2/cmd/util"
@@ -18,7 +23,6 @@ import (
argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient"
clusterpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/clusterauth"
"github.com/argoproj/argo-cd/v2/util/errors"
"github.com/argoproj/argo-cd/v2/util/io"
@@ -60,6 +64,8 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
var (
clusterOpts cmdutil.ClusterOptions
skipConfirmation bool
labels []string
annotations []string
)
var command = &cobra.Command{
Use: "add CONTEXT",
@@ -116,24 +122,41 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
clientset, err := kubernetes.NewForConfig(conf)
errors.CheckError(err)
if clusterOpts.ServiceAccount != "" {
managerBearerToken, err = clusterauth.GetServiceAccountBearerToken(clientset, clusterOpts.SystemNamespace, clusterOpts.ServiceAccount)
managerBearerToken, err = clusterauth.GetServiceAccountBearerToken(clientset, clusterOpts.SystemNamespace, clusterOpts.ServiceAccount, common.BearerTokenTimeout)
} else {
managerBearerToken, err = clusterauth.InstallClusterManagerRBAC(clientset, clusterOpts.SystemNamespace, clusterOpts.Namespaces)
isTerminal := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd())
if isTerminal && !skipConfirmation {
message := fmt.Sprintf("WARNING: This will create a service account `argocd-manager` on the cluster referenced by context `%s` with full cluster level admin privileges. Do you want to continue [y/N]? ", contextName)
if !cli.AskToProceed(message) {
os.Exit(1)
}
}
managerBearerToken, err = clusterauth.InstallClusterManagerRBAC(clientset, clusterOpts.SystemNamespace, clusterOpts.Namespaces, common.BearerTokenTimeout)
}
errors.CheckError(err)
}
labelsMap, err := label.Parse(labels)
errors.CheckError(err)
annotationsMap, err := label.Parse(annotations)
errors.CheckError(err)
conn, clusterIf := argocdclient.NewClientOrDie(clientOpts).NewClusterClientOrDie()
defer io.Close(conn)
if clusterOpts.Name != "" {
contextName = clusterOpts.Name
}
clst := cmdutil.NewCluster(contextName, clusterOpts.Namespaces, clusterOpts.ClusterResources, conf, managerBearerToken, awsAuthConf, execProviderConf)
clst := cmdutil.NewCluster(contextName, clusterOpts.Namespaces, clusterOpts.ClusterResources, conf, managerBearerToken, awsAuthConf, execProviderConf, labelsMap, annotationsMap)
if clusterOpts.InCluster {
clst.Server = argoappv1.KubernetesInternalAPIServerAddr
}
if clusterOpts.Shard >= 0 {
clst.Shard = &clusterOpts.Shard
}
if clusterOpts.Project != "" {
clst.Project = clusterOpts.Project
}
clstCreateReq := clusterpkg.ClusterCreateRequest{
Cluster: clst,
Upsert: clusterOpts.Upsert,
@@ -148,6 +171,8 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default \"%s\" SA will be created", clusterauth.ArgoCDManagerServiceAccount))
command.Flags().StringVar(&clusterOpts.SystemNamespace, "system-namespace", common.DefaultSystemNamespace, "Use different system namespace")
command.Flags().BoolVarP(&skipConfirmation, "yes", "y", false, "Skip explicit confirmation")
command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)")
command.Flags().StringArrayVar(&annotations, "annotation", nil, "Set metadata annotations (e.g. --annotation key=value)")
cmdutil.AddClusterFlags(command, &clusterOpts)
return command
}
@@ -158,9 +183,10 @@ func NewClusterGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
output string
)
var command = &cobra.Command{
Use: "get SERVER",
Short: "Get cluster information",
Example: `argocd cluster get https://12.34.567.89`,
Use: "get SERVER/NAME",
Short: "Get cluster information",
Example: `argocd cluster get https://12.34.567.89
argocd cluster get in-cluster`,
Run: func(c *cobra.Command, args []string) {
if len(args) == 0 {
c.HelpFunc()(c, args)
@@ -169,8 +195,8 @@ func NewClusterGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
conn, clusterIf := argocdclient.NewClientOrDie(clientOpts).NewClusterClientOrDie()
defer io.Close(conn)
clusters := make([]argoappv1.Cluster, 0)
for _, clusterName := range args {
clst, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Server: clusterName})
for _, clusterSelector := range args {
clst, err := clusterIf.Get(context.Background(), getQueryBySelector(clusterSelector))
errors.CheckError(err)
clusters = append(clusters, *clst)
}
@@ -257,17 +283,29 @@ func NewClusterRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm
// Print table of cluster information
func printClusterTable(clusters []argoappv1.Cluster) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
_, _ = fmt.Fprintf(w, "SERVER\tNAME\tVERSION\tSTATUS\tMESSAGE\n")
_, _ = fmt.Fprintf(w, "SERVER\tNAME\tVERSION\tSTATUS\tMESSAGE\tPROJECT\n")
for _, c := range clusters {
server := c.Server
if len(c.Namespaces) > 0 {
server = fmt.Sprintf("%s (%d namespaces)", c.Server, len(c.Namespaces))
}
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", server, c.Name, c.ServerVersion, c.ConnectionState.Status, c.ConnectionState.Message)
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", server, c.Name, c.ServerVersion, c.ConnectionState.Status, c.ConnectionState.Message, c.Project)
}
_ = w.Flush()
}
// Returns cluster query for getting cluster depending on the cluster selector
func getQueryBySelector(clusterSelector string) *clusterpkg.ClusterQuery {
var query clusterpkg.ClusterQuery
isServer, err := regexp.MatchString(`^https?://`, clusterSelector)
if isServer || err != nil {
query.Server = clusterSelector
} else {
query.Name = clusterSelector
}
return &query
}
// Print list of cluster servers
func printClusterServers(clusters []argoappv1.Cluster) {
for _, c := range clusters {

View File

@@ -6,8 +6,24 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/stretchr/testify/assert"
)
func Test_getQueryBySelector(t *testing.T) {
query := getQueryBySelector("my-cluster")
assert.Equal(t, query.Name, "my-cluster")
assert.Equal(t, query.Server, "")
query = getQueryBySelector("http://my-server")
assert.Equal(t, query.Name, "")
assert.Equal(t, query.Server, "http://my-server")
query = getQueryBySelector("https://my-server")
assert.Equal(t, query.Name, "")
assert.Equal(t, query.Server, "https://my-server")
}
func Test_printClusterTable(t *testing.T) {
printClusterTable([]v1alpha1.Cluster{
{

View File

@@ -18,6 +18,7 @@ import (
type forwardCacheClient struct {
namespace string
context string
init sync.Once
client cache.CacheClient
err error
@@ -25,7 +26,9 @@ type forwardCacheClient struct {
func (c *forwardCacheClient) doLazy(action func(client cache.CacheClient) error) error {
c.init.Do(func() {
overrides := clientcmd.ConfigOverrides{}
overrides := clientcmd.ConfigOverrides{
CurrentContext: c.context,
}
redisPort, err := kubeutil.PortForward(6379, c.namespace, &overrides,
"app.kubernetes.io/name=argocd-redis-ha-haproxy", "app.kubernetes.io/name=argocd-redis")
if err != nil {
@@ -74,6 +77,7 @@ func (c *forwardCacheClient) NotifyUpdated(key string) error {
type forwardRepoClientset struct {
namespace string
context string
init sync.Once
repoClientset repoapiclient.Clientset
err error
@@ -81,7 +85,9 @@ type forwardRepoClientset struct {
func (c *forwardRepoClientset) NewRepoServerClient() (io.Closer, repoapiclient.RepoServerServiceClient, error) {
c.init.Do(func() {
overrides := clientcmd.ConfigOverrides{}
overrides := clientcmd.ConfigOverrides{
CurrentContext: c.context,
}
repoServerPort, err := kubeutil.PortForward(8081, c.namespace, &overrides, "app.kubernetes.io/name=argocd-repo-server")
if err != nil {
c.err = err

View File

@@ -12,10 +12,10 @@ import (
"github.com/golang/protobuf/ptypes/empty"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
argoapi "github.com/argoproj/argo-cd/v2/pkg/apiclient"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
@@ -27,6 +27,8 @@ import (
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/io"
"github.com/argoproj/argo-cd/v2/util/localconfig"
flag "github.com/spf13/pflag"
)
func testAPI(clientOpts *argoapi.ClientOptions) error {
@@ -43,21 +45,27 @@ func testAPI(clientOpts *argoapi.ClientOptions) error {
return err
}
func addKubectlFlagsToCmd(cmd *cobra.Command) clientcmd.ClientConfig {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig
overrides := clientcmd.ConfigOverrides{}
kflags := clientcmd.RecommendedConfigOverrideFlags("")
cmd.Flags().StringVar(&loadingRules.ExplicitPath, "kubeconfig", "", "Path to a kube config. Only required if out-of-cluster")
clientcmd.BindOverrideFlags(&overrides, cmd.Flags(), kflags)
return clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, &overrides, os.Stdin)
func retrieveContextIfChanged(contextFlag *flag.Flag) string {
if contextFlag != nil && contextFlag.Changed {
return contextFlag.Value.String()
}
return ""
}
// InitCommand 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 InitCommand(cmd *cobra.Command, clientOpts *argoapi.ClientOptions, port *int) *cobra.Command {
ctx, cancel := context.WithCancel(context.Background())
clientConfig := addKubectlFlagsToCmd(cmd)
flags := pflag.NewFlagSet("tmp", pflag.ContinueOnError)
clientConfig := cli.AddKubectlFlagsToSet(flags)
// copy k8s persistent flags into argocd command flags
flags.VisitAll(func(flag *pflag.Flag) {
// skip Kubernetes server flags since argocd has it's own server flag
if flag.Name == "server" {
return
}
cmd.Flags().AddFlag(flag)
})
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
startInProcessAPI := clientOpts.Core
if !startInProcessAPI {
@@ -109,12 +117,14 @@ func InitCommand(cmd *cobra.Command, clientOpts *argoapi.ClientOptions, port *in
return err
}
context := retrieveContextIfChanged(cmd.Flag("context"))
mr, err := miniredis.Run()
if err != nil {
return err
}
appstateCache := appstatecache.NewCache(cacheutil.NewCache(&forwardCacheClient{namespace: namespace}), time.Hour)
appstateCache := appstatecache.NewCache(cacheutil.NewCache(&forwardCacheClient{namespace: namespace, context: context}), time.Hour)
srv := server.NewServer(ctx, server.ArgoCDServerOpts{
EnableGZip: false,
Namespace: namespace,
@@ -126,7 +136,7 @@ func InitCommand(cmd *cobra.Command, clientOpts *argoapi.ClientOptions, port *in
KubeClientset: kubeClientset,
Insecure: true,
ListenHost: "localhost",
RepoClientset: &forwardRepoClientset{namespace: namespace},
RepoClientset: &forwardRepoClientset{namespace: namespace, context: context},
})
go srv.Run(ctx, *port, 0)

View File

@@ -0,0 +1,80 @@
package headless
import (
"testing"
flag "github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
)
type StringFlag struct {
// The exact value provided on the flag
value string
}
func (f StringFlag) String() string {
return f.value
}
func (f *StringFlag) Set(value string) error {
f.value = value
return nil
}
func (f *StringFlag) Type() string {
return "string"
}
func Test_FlagContextNotChanged(t *testing.T) {
res := retrieveContextIfChanged(&flag.Flag{
Name: "",
Shorthand: "",
Usage: "",
Value: &StringFlag{value: "test"},
DefValue: "",
Changed: false,
NoOptDefVal: "",
Deprecated: "",
Hidden: false,
ShorthandDeprecated: "",
Annotations: nil,
})
assert.Equal(t, "", res)
}
func Test_FlagContextChanged(t *testing.T) {
res := retrieveContextIfChanged(&flag.Flag{
Name: "",
Shorthand: "",
Usage: "",
Value: &StringFlag{value: "test"},
DefValue: "",
Changed: true,
NoOptDefVal: "",
Deprecated: "",
Hidden: false,
ShorthandDeprecated: "",
Annotations: nil,
})
assert.Equal(t, "test", res)
}
func Test_FlagContextNil(t *testing.T) {
res := retrieveContextIfChanged(&flag.Flag{
Name: "",
Shorthand: "",
Usage: "",
Value: nil,
DefValue: "",
Changed: false,
NoOptDefVal: "",
Deprecated: "",
Hidden: false,
ShorthandDeprecated: "",
Annotations: nil,
})
assert.Equal(t, "", res)
}

View File

@@ -90,6 +90,8 @@ argocd login cd.argoproj.io --core`,
ServerAddr: server,
Insecure: globalClientOpts.Insecure,
PlainText: globalClientOpts.PlainText,
ClientCertFile: globalClientOpts.ClientCertFile,
ClientCertKeyFile: globalClientOpts.ClientCertKeyFile,
GRPCWeb: globalClientOpts.GRPCWeb,
GRPCWebRootPath: globalClientOpts.GRPCWebRootPath,
PortForward: globalClientOpts.PortForward,
@@ -200,7 +202,10 @@ func oauth2Login(ctx context.Context, port int, oidcSettings *settingspkg.OIDCCo
// completionChan is to signal flow completed. Non-empty string indicates error
completionChan := make(chan string)
// stateNonce is an OAuth2 state nonce
stateNonce := rand.RandString(10)
// According to the spec (https://www.rfc-editor.org/rfc/rfc6749#section-10.10), this must be guessable with
// probability <= 2^(-128). The following call generates one of 52^24 random strings, ~= 2^136 possibilities.
stateNonce, err := rand.String(24)
errors.CheckError(err)
var tokenString string
var refreshToken string
@@ -210,7 +215,8 @@ func oauth2Login(ctx context.Context, port int, oidcSettings *settingspkg.OIDCCo
}
// PKCE implementation of https://tools.ietf.org/html/rfc7636
codeVerifier := rand.RandStringCharset(43, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~")
codeVerifier, err := rand.StringFromCharset(43, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~")
errors.CheckError(err)
codeChallengeHash := sha256.Sum256([]byte(codeVerifier))
codeChallenge := base64.RawURLEncoding.EncodeToString(codeChallengeHash[:])
@@ -294,7 +300,8 @@ func oauth2Login(ctx context.Context, port int, oidcSettings *settingspkg.OIDCCo
opts = append(opts, oauth2.SetAuthURLParam("code_challenge_method", "S256"))
url = oauth2conf.AuthCodeURL(stateNonce, opts...)
case oidcutil.GrantTypeImplicit:
url = oidcutil.ImplicitFlowURL(oauth2conf, stateNonce, opts...)
url, err = oidcutil.ImplicitFlowURL(oauth2conf, stateNonce, opts...)
errors.CheckError(err)
default:
log.Fatalf("Unsupported grant type: %v", grantType)
}

View File

@@ -219,8 +219,17 @@ func NewProjectRemoveSignatureKeyCommand(clientOpts *argocdclient.ClientOptions)
// NewProjectAddDestinationCommand returns a new instance of an `argocd proj add-destination` command
func NewProjectAddDestinationCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var nameInsteadServer bool
buildApplicationDestination := func(destination string, namespace string, nameInsteadServer bool) v1alpha1.ApplicationDestination {
if nameInsteadServer {
return v1alpha1.ApplicationDestination{Name: destination, Namespace: namespace}
}
return v1alpha1.ApplicationDestination{Server: destination, Namespace: namespace}
}
var command = &cobra.Command{
Use: "add-destination PROJECT SERVER NAMESPACE",
Use: "add-destination PROJECT SERVER/NAME NAMESPACE",
Short: "Add project destination",
Run: func(c *cobra.Command, args []string) {
if len(args) != 3 {
@@ -228,8 +237,8 @@ func NewProjectAddDestinationCommand(clientOpts *argocdclient.ClientOptions) *co
os.Exit(1)
}
projName := args[0]
server := args[1]
namespace := args[2]
destination := buildApplicationDestination(args[1], namespace, nameInsteadServer)
conn, projIf := argocdclient.NewClientOrDie(clientOpts).NewProjectClientOrDie()
defer argoio.Close(conn)
@@ -237,15 +246,18 @@ func NewProjectAddDestinationCommand(clientOpts *argocdclient.ClientOptions) *co
errors.CheckError(err)
for _, dest := range proj.Spec.Destinations {
if dest.Namespace == namespace && dest.Server == server {
dstServerExist := destination.Server != "" && dest.Server == destination.Server
dstNameExist := destination.Name != "" && dest.Name == destination.Name
if dest.Namespace == namespace && (dstServerExist || dstNameExist) {
log.Fatal("Specified destination is already defined in project")
}
}
proj.Spec.Destinations = append(proj.Spec.Destinations, v1alpha1.ApplicationDestination{Server: server, Namespace: namespace})
proj.Spec.Destinations = append(proj.Spec.Destinations, destination)
_, err = projIf.Update(context.Background(), &projectpkg.ProjectUpdateRequest{Project: proj})
errors.CheckError(err)
},
}
command.Flags().BoolVar(&nameInsteadServer, "name", false, "Use name as destination instead server")
return command
}

View File

@@ -116,6 +116,7 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) *
namespaces []string
clusters []string
manualSync bool
timeZone string
)
var command = &cobra.Command{
Use: "add PROJECT",
@@ -132,7 +133,7 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) *
proj, err := projIf.Get(context.Background(), &projectpkg.ProjectQuery{Name: projName})
errors.CheckError(err)
err = proj.Spec.AddWindow(kind, schedule, duration, applications, namespaces, clusters, manualSync)
err = proj.Spec.AddWindow(kind, schedule, duration, applications, namespaces, clusters, manualSync, timeZone)
errors.CheckError(err)
_, err = projIf.Update(context.Background(), &projectpkg.ProjectUpdateRequest{Project: proj})
@@ -146,6 +147,7 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) *
command.Flags().StringSliceVar(&namespaces, "namespaces", []string{}, "Namespaces that the schedule will be applied to. Comma separated, wildcards supported (e.g. --namespaces default,\\*-prod)")
command.Flags().StringSliceVar(&clusters, "clusters", []string{}, "Clusters that the schedule will be applied to. Comma separated, wildcards supported (e.g. --clusters prod,staging)")
command.Flags().BoolVar(&manualSync, "manual-sync", false, "Allow manual syncs for both deny and allow windows")
command.Flags().StringVar(&timeZone, "time-zone", "UTC", "Time zone of the sync window")
return command
}
@@ -189,6 +191,7 @@ func NewProjectWindowsUpdateCommand(clientOpts *argocdclient.ClientOptions) *cob
applications []string
namespaces []string
clusters []string
timeZone string
)
var command = &cobra.Command{
Use: "update PROJECT ID",
@@ -212,7 +215,7 @@ func NewProjectWindowsUpdateCommand(clientOpts *argocdclient.ClientOptions) *cob
for i, window := range proj.Spec.SyncWindows {
if id == i {
err := window.Update(schedule, duration, applications, namespaces, clusters)
err := window.Update(schedule, duration, applications, namespaces, clusters, timeZone)
if err != nil {
errors.CheckError(err)
}
@@ -228,6 +231,7 @@ func NewProjectWindowsUpdateCommand(clientOpts *argocdclient.ClientOptions) *cob
command.Flags().StringSliceVar(&applications, "applications", []string{}, "Applications that the schedule will be applied to. Comma separated, wildcards supported (e.g. --applications prod-\\*,website)")
command.Flags().StringSliceVar(&namespaces, "namespaces", []string{}, "Namespaces that the schedule will be applied to. Comma separated, wildcards supported (e.g. --namespaces default,\\*-prod)")
command.Flags().StringSliceVar(&clusters, "clusters", []string{}, "Clusters that the schedule will be applied to. Comma separated, wildcards supported (e.g. --clusters prod,staging)")
command.Flags().StringVar(&timeZone, "time-zone", "UTC", "Time zone of the sync window. (e.g. --time-zone \"America/New_York\")")
return command
}

View File

@@ -43,13 +43,15 @@ func NewReloginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Comm
var tokenString string
var refreshToken string
clientOpts := argocdclient.ClientOptions{
ConfigPath: "",
ServerAddr: configCtx.Server.Server,
Insecure: configCtx.Server.Insecure,
GRPCWeb: globalClientOpts.GRPCWeb,
GRPCWebRootPath: globalClientOpts.GRPCWebRootPath,
PlainText: configCtx.Server.PlainText,
Headers: globalClientOpts.Headers,
ConfigPath: "",
ServerAddr: configCtx.Server.Server,
Insecure: configCtx.Server.Insecure,
ClientCertFile: globalClientOpts.ClientCertFile,
ClientCertKeyFile: globalClientOpts.ClientCertKeyFile,
GRPCWeb: globalClientOpts.GRPCWeb,
GRPCWebRootPath: globalClientOpts.GRPCWebRootPath,
PlainText: configCtx.Server.PlainText,
Headers: globalClientOpts.Headers,
}
acdClient := argocdclient.NewClientOrDie(&clientOpts)
claims, err := configCtx.User.Claims()

View File

@@ -182,6 +182,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
GithubAppInstallationID: repoOpts.Repo.GithubAppInstallationId,
GithubAppEnterpriseBaseUrl: repoOpts.Repo.GitHubAppEnterpriseBaseURL,
Proxy: repoOpts.Proxy,
Project: repoOpts.Repo.Project,
}
_, err := repoIf.ValidateAccess(context.Background(), &repoAccessReq)
errors.CheckError(err)
@@ -226,7 +227,7 @@ func NewRepoRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
// Print table of repo info
func printRepoTable(repos appsv1.Repositories) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
_, _ = fmt.Fprintf(w, "TYPE\tNAME\tREPO\tINSECURE\tOCI\tLFS\tCREDS\tSTATUS\tMESSAGE\n")
_, _ = fmt.Fprintf(w, "TYPE\tNAME\tREPO\tINSECURE\tOCI\tLFS\tCREDS\tSTATUS\tMESSAGE\tPROJECT\n")
for _, r := range repos {
var hasCreds string
if !r.HasCredentials() {
@@ -238,7 +239,7 @@ func printRepoTable(repos appsv1.Repositories) {
hasCreds = "true"
}
}
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%v\t%v\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)
_, _ = 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

@@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"
appcontroller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands"
cmpserver "github.com/argoproj/argo-cd/v2/cmd/argocd-cmp-server/commands"
dex "github.com/argoproj/argo-cd/v2/cmd/argocd-dex/commands"
reposerver "github.com/argoproj/argo-cd/v2/cmd/argocd-repo-server/commands"
apiserver "github.com/argoproj/argo-cd/v2/cmd/argocd-server/commands"
@@ -34,6 +35,8 @@ func main() {
command = appcontroller.NewCommand()
case "argocd-repo-server":
command = reposerver.NewCommand()
case "argocd-cmp-server":
command = cmpserver.NewCommand()
case "argocd-dex":
command = dex.NewCommand()
default:

View File

@@ -9,6 +9,8 @@ import (
"strings"
"time"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@@ -40,6 +42,7 @@ type AppOptions struct {
helmSetStrings []string
helmSetFiles []string
helmVersion string
helmPassCredentials bool
project string
syncPolicy string
syncOptions []string
@@ -86,6 +89,7 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) {
command.Flags().StringVar(&opts.values, "values-literal-file", "", "Filename or URL to import as a literal Helm values block")
command.Flags().StringVar(&opts.releaseName, "release-name", "", "Helm release-name")
command.Flags().StringVar(&opts.helmVersion, "helm-version", "", "Helm version")
command.Flags().BoolVar(&opts.helmPassCredentials, "helm-pass-credentials", false, "Pass credentials to all domain")
command.Flags().StringArrayVar(&opts.helmSets, "helm-set", []string{}, "Helm set values on the command line (can be repeated to set several values: --helm-set key1=val1 --helm-set key2=val2)")
command.Flags().StringArrayVar(&opts.helmSetStrings, "helm-set-string", []string{}, "Helm set STRING values on the command line (can be repeated to set several values: --helm-set-string key1=val1 --helm-set-string key2=val2)")
command.Flags().StringArrayVar(&opts.helmSetFiles, "helm-set-file", []string{}, "Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2)")
@@ -122,6 +126,9 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) {
func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions) int {
visited := 0
if flags == nil {
return visited
}
flags.Visit(func(f *pflag.Flag) {
visited++
switch f.Name {
@@ -156,6 +163,8 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap
setHelmOpt(&spec.Source, helmOpts{releaseName: appOpts.releaseName})
case "helm-version":
setHelmOpt(&spec.Source, helmOpts{version: appOpts.helmVersion})
case "helm-pass-credentials":
setHelmOpt(&spec.Source, helmOpts{passCredentials: appOpts.helmPassCredentials})
case "helm-set":
setHelmOpt(&spec.Source, helmOpts{helmSets: appOpts.helmSets})
case "helm-set-string":
@@ -372,13 +381,14 @@ func setPluginOptEnvs(src *argoappv1.ApplicationSource, envs []string) {
}
type helmOpts struct {
valueFiles []string
values string
releaseName string
version string
helmSets []string
helmSetStrings []string
helmSetFiles []string
valueFiles []string
values string
releaseName string
version string
helmSets []string
helmSetStrings []string
helmSetFiles []string
passCredentials bool
}
func setHelmOpt(src *argoappv1.ApplicationSource, opts helmOpts) {
@@ -397,6 +407,9 @@ func setHelmOpt(src *argoappv1.ApplicationSource, opts helmOpts) {
if opts.version != "" {
src.Helm.Version = opts.version
}
if opts.passCredentials {
src.Helm.PassCredentials = opts.passCredentials
}
for _, text := range opts.helmSets {
p, err := argoappv1.NewHelmParameter(text, false)
if err != nil {
@@ -518,39 +531,99 @@ func SetParameterOverrides(app *argoappv1.Application, parameters []string) {
}
}
func readAppFromStdin(app *argoappv1.Application) error {
func readApps(yml []byte, apps *[]*argoappv1.Application) error {
yamls, _ := kube.SplitYAMLToString(yml)
var err error
for _, yml := range yamls {
var app argoappv1.Application
err = config.Unmarshal([]byte(yml), &app)
*apps = append(*apps, &app)
if err != nil {
return err
}
}
return err
}
func readAppsFromStdin(apps *[]*argoappv1.Application) error {
reader := bufio.NewReader(os.Stdin)
err := config.UnmarshalReader(reader, &app)
data, err := ioutil.ReadAll(reader)
if err != nil {
return err
}
err = readApps(data, apps)
if err != nil {
return fmt.Errorf("unable to read manifest from stdin: %v", err)
}
return nil
}
func readAppFromURI(fileURL string, app *argoappv1.Application) error {
parsedURL, err := url.ParseRequestURI(fileURL)
if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") {
err = config.UnmarshalLocalFile(fileURL, &app)
} else {
err = config.UnmarshalRemoteFile(fileURL, &app)
func readAppsFromURI(fileURL string, apps *[]*argoappv1.Application) error {
readFilePayload := func() ([]byte, error) {
parsedURL, err := url.ParseRequestURI(fileURL)
if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") {
return ioutil.ReadFile(fileURL)
}
return config.ReadRemoteFile(fileURL)
}
return err
yml, err := readFilePayload()
if err != nil {
return err
}
return readApps(yml, apps)
}
func ConstructApp(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) (*argoappv1.Application, error) {
var app argoappv1.Application
if fileURL == "-" {
// read stdin
err := readAppFromStdin(&app)
if err != nil {
return nil, err
}
} else if fileURL != "" {
// read uri
err := readAppFromURI(fileURL, &app)
if err != nil {
return nil, err
func constructAppsFromStdin() ([]*argoappv1.Application, error) {
apps := make([]*argoappv1.Application, 0)
// read stdin
err := readAppsFromStdin(&apps)
if err != nil {
return nil, err
}
return apps, nil
}
func constructAppsBaseOnName(appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) {
var app *argoappv1.Application
// read arguments
if len(args) == 1 {
if appName != "" && appName != args[0] {
return nil, fmt.Errorf("--name argument '%s' does not match app name %s", appName, args[0])
}
appName = args[0]
}
app = &argoappv1.Application{
TypeMeta: v1.TypeMeta{
Kind: application.ApplicationKind,
APIVersion: application.Group + "/v1alpha1",
},
ObjectMeta: v1.ObjectMeta{
Name: appName,
},
}
SetAppSpecOptions(flags, &app.Spec, &appOpts)
SetParameterOverrides(app, appOpts.Parameters)
mergeLabels(app, labels)
setAnnotations(app, annotations)
return []*argoappv1.Application{
app,
}, nil
}
func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) {
apps := make([]*argoappv1.Application, 0)
// read uri
err := readAppsFromURI(fileURL, &apps)
if err != nil {
return nil, err
}
for _, app := range apps {
if len(args) == 1 && args[0] != app.Name {
return nil, fmt.Errorf("app name '%s' does not match app spec metadata.name '%s'", args[0], app.Name)
}
@@ -561,32 +634,20 @@ func ConstructApp(fileURL, appName string, labels, annotations, args []string, a
return nil, fmt.Errorf("app.Name is empty. --name argument can be used to provide app.Name")
}
SetAppSpecOptions(flags, &app.Spec, &appOpts)
SetParameterOverrides(&app, appOpts.Parameters)
mergeLabels(&app, labels)
setAnnotations(&app, annotations)
} else {
// read arguments
if len(args) == 1 {
if appName != "" && appName != args[0] {
return nil, fmt.Errorf("--name argument '%s' does not match app name %s", appName, args[0])
}
appName = args[0]
}
app = argoappv1.Application{
TypeMeta: v1.TypeMeta{
Kind: application.ApplicationKind,
APIVersion: application.Group + "/v1alpha1",
},
ObjectMeta: v1.ObjectMeta{
Name: appName,
},
}
SetAppSpecOptions(flags, &app.Spec, &appOpts)
SetParameterOverrides(&app, appOpts.Parameters)
mergeLabels(&app, labels)
setAnnotations(&app, annotations)
SetParameterOverrides(app, appOpts.Parameters)
mergeLabels(app, labels)
setAnnotations(app, annotations)
}
return &app, nil
return apps, nil
}
func ConstructApps(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) {
if fileURL == "-" {
return constructAppsFromStdin()
} else if fileURL != "" {
return constructAppsFromFileUrl(fileURL, appName, labels, annotations, args, appOpts, flags)
}
return constructAppsBaseOnName(appName, labels, annotations, args, appOpts, flags)
}
func mergeLabels(app *argoappv1.Application, labels []string) {

View File

@@ -1,12 +1,16 @@
package util
import (
"io/ioutil"
"os"
"testing"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
)
func Test_setHelmOpt(t *testing.T) {
@@ -45,6 +49,11 @@ func Test_setHelmOpt(t *testing.T) {
setHelmOpt(&src, helmOpts{version: "v3"})
assert.Equal(t, "v3", src.Helm.Version)
})
t.Run("HelmPassCredentials", func(t *testing.T) {
src := v1alpha1.ApplicationSource{}
setHelmOpt(&src, helmOpts{passCredentials: true})
assert.Equal(t, true, src.Helm.PassCredentials)
})
}
func Test_setKustomizeOpt(t *testing.T) {
@@ -190,3 +199,106 @@ func Test_setAnnotations(t *testing.T) {
assert.Equal(t, map[string]string{"hoge": ""}, app.Annotations)
})
}
const appsYaml = `---
# Source: apps/templates/helm.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: sth1
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
namespace: sth
server: 'https://kubernetes.default.svc'
project: default
source:
repoURL: 'https://github.com/pasha-codefresh/argocd-example-apps'
targetRevision: HEAD
path: apps
helm:
valueFiles:
- values.yaml
---
# Source: apps/templates/helm.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: sth2
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
namespace: sth
server: 'https://kubernetes.default.svc'
project: default
source:
repoURL: 'https://github.com/pasha-codefresh/argocd-example-apps'
targetRevision: HEAD
path: apps
helm:
valueFiles:
- values.yaml`
func TestReadAppsFromURI(t *testing.T) {
file, err := ioutil.TempFile(os.TempDir(), "")
if err != nil {
panic(err)
}
defer func() {
_ = os.Remove(file.Name())
}()
_, _ = file.WriteString(appsYaml)
_ = file.Sync()
apps := make([]*argoappv1.Application, 0)
err = readAppsFromURI(file.Name(), &apps)
assert.NoError(t, err)
assert.Equal(t, 2, len(apps))
assert.Equal(t, "sth1", apps[0].Name)
assert.Equal(t, "sth2", apps[1].Name)
}
func TestConstructAppFromStdin(t *testing.T) {
file, err := ioutil.TempFile(os.TempDir(), "")
if err != nil {
panic(err)
}
defer func() {
_ = os.Remove(file.Name())
}()
_, _ = file.WriteString(appsYaml)
_ = file.Sync()
if _, err := file.Seek(0, 0); err != nil {
log.Fatal(err)
}
os.Stdin = file
apps, err := ConstructApps("-", "test", []string{}, []string{}, []string{}, AppOptions{}, nil)
if err := file.Close(); err != nil {
log.Fatal(err)
}
assert.NoError(t, err)
assert.Equal(t, 2, len(apps))
assert.Equal(t, "sth1", apps[0].Name)
assert.Equal(t, "sth2", apps[1].Name)
}
func TestConstructBasedOnName(t *testing.T) {
apps, err := ConstructApps("", "test", []string{}, []string{}, []string{}, AppOptions{}, nil)
assert.NoError(t, err)
assert.Equal(t, 1, len(apps))
assert.Equal(t, "test", apps[0].Name)
}

View File

@@ -55,7 +55,7 @@ func PrintKubeContexts(ca clientcmd.ConfigAccess) {
}
}
func NewCluster(name string, namespaces []string, clusterResources bool, conf *rest.Config, managerBearerToken string, awsAuthConf *argoappv1.AWSAuthConfig, execProviderConf *argoappv1.ExecProviderConfig) *argoappv1.Cluster {
func NewCluster(name string, namespaces []string, clusterResources bool, conf *rest.Config, managerBearerToken string, awsAuthConf *argoappv1.AWSAuthConfig, execProviderConf *argoappv1.ExecProviderConfig, labels, annotations map[string]string) *argoappv1.Cluster {
tlsClientConfig := argoappv1.TLSClientConfig{
Insecure: conf.TLSClientConfig.Insecure,
ServerName: conf.TLSClientConfig.ServerName,
@@ -89,6 +89,8 @@ func NewCluster(name string, namespaces []string, clusterResources bool, conf *r
AWSAuthConfig: awsAuthConf,
ExecProviderConfig: execProviderConf,
},
Labels: labels,
Annotations: annotations,
}
// Bearer token will preferentially be used for auth if present,
@@ -111,6 +113,7 @@ type ClusterOptions struct {
Namespaces []string
ClusterResources bool
Name string
Project string
Shard int64
ExecProviderCommand string
ExecProviderArgs []string
@@ -126,6 +129,7 @@ func AddClusterFlags(command *cobra.Command, opts *ClusterOptions) {
command.Flags().StringArrayVar(&opts.Namespaces, "namespace", nil, "List of namespaces which are allowed to manage")
command.Flags().BoolVar(&opts.ClusterResources, "cluster-resources", false, "Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty.")
command.Flags().StringVar(&opts.Name, "name", "", "Overwrite the cluster name")
command.Flags().StringVar(&opts.Project, "project", "", "project of the cluster")
command.Flags().Int64Var(&opts.Shard, "shard", -1, "Cluster shard number; inferred from hostname if not set")
command.Flags().StringVar(&opts.ExecProviderCommand, "exec-command", "", "Command to run to provide client credentials to the cluster. You may need to build a custom ArgoCD image to ensure the command is available at runtime.")
command.Flags().StringArrayVar(&opts.ExecProviderArgs, "exec-command-args", nil, "Arguments to supply to the --exec-command executable")

View File

@@ -11,6 +11,8 @@ import (
)
func Test_newCluster(t *testing.T) {
labels := map[string]string{"key1": "val1"}
annotations := map[string]string{"key2": "val2"}
clusterWithData := NewCluster("test-cluster", []string{"test-namespace"}, false, &rest.Config{
TLSClientConfig: rest.TLSClientConfig{
Insecure: false,
@@ -23,11 +25,13 @@ func Test_newCluster(t *testing.T) {
},
"test-bearer-token",
&v1alpha1.AWSAuthConfig{},
&v1alpha1.ExecProviderConfig{})
&v1alpha1.ExecProviderConfig{}, labels, annotations)
assert.Equal(t, "test-cert-data", string(clusterWithData.Config.CertData))
assert.Equal(t, "test-key-data", string(clusterWithData.Config.KeyData))
assert.Equal(t, "", clusterWithData.Config.BearerToken)
assert.Equal(t, labels, clusterWithData.Labels)
assert.Equal(t, annotations, clusterWithData.Annotations)
clusterWithFiles := NewCluster("test-cluster", []string{"test-namespace"}, false, &rest.Config{
TLSClientConfig: rest.TLSClientConfig{
@@ -41,11 +45,13 @@ func Test_newCluster(t *testing.T) {
},
"test-bearer-token",
&v1alpha1.AWSAuthConfig{},
&v1alpha1.ExecProviderConfig{})
&v1alpha1.ExecProviderConfig{}, labels, nil)
assert.True(t, strings.Contains(string(clusterWithFiles.Config.CertData), "test-cert-data"))
assert.True(t, strings.Contains(string(clusterWithFiles.Config.KeyData), "test-key-data"))
assert.Equal(t, "", clusterWithFiles.Config.BearerToken)
assert.Equal(t, labels, clusterWithFiles.Labels)
assert.Nil(t, clusterWithFiles.Annotations)
clusterWithBearerToken := NewCluster("test-cluster", []string{"test-namespace"}, false, &rest.Config{
TLSClientConfig: rest.TLSClientConfig{
@@ -57,7 +63,9 @@ func Test_newCluster(t *testing.T) {
},
"test-bearer-token",
&v1alpha1.AWSAuthConfig{},
&v1alpha1.ExecProviderConfig{})
&v1alpha1.ExecProviderConfig{}, nil, nil)
assert.Equal(t, "test-bearer-token", clusterWithBearerToken.Config.BearerToken)
assert.Nil(t, clusterWithBearerToken.Labels)
assert.Nil(t, clusterWithBearerToken.Annotations)
}

View File

@@ -27,6 +27,7 @@ type RepoOptions struct {
func AddRepoFlags(command *cobra.Command, opts *RepoOptions) {
command.Flags().StringVar(&opts.Repo.Type, "type", common.DefaultRepoType, "type of the repository, \"git\" or \"helm\"")
command.Flags().StringVar(&opts.Repo.Name, "name", "", "name of the repository, mandatory for repositories of type helm")
command.Flags().StringVar(&opts.Repo.Project, "project", "", "project of the repository")
command.Flags().StringVar(&opts.Repo.Username, "username", "", "username to the repository")
command.Flags().StringVar(&opts.Repo.Password, "password", "", "password to the repository")
command.Flags().StringVar(&opts.SshPrivateKeyPath, "ssh-private-key-path", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)")

View File

@@ -0,0 +1,66 @@
package apiclient
import (
"context"
"time"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
grpc_util "github.com/argoproj/argo-cd/v2/util/grpc"
"github.com/argoproj/argo-cd/v2/util/io"
)
const (
// MaxGRPCMessageSize contains max grpc message size
MaxGRPCMessageSize = 100 * 1024 * 1024
)
// Clientset represents config management plugin server api clients
type Clientset interface {
NewConfigManagementPluginClient() (io.Closer, ConfigManagementPluginServiceClient, error)
}
type clientSet struct {
address string
timeoutSeconds int
}
func (c *clientSet) NewConfigManagementPluginClient() (io.Closer, ConfigManagementPluginServiceClient, error) {
conn, err := NewConnection(c.address, c.timeoutSeconds)
if err != nil {
return nil, nil, err
}
return conn, NewConfigManagementPluginServiceClient(conn), nil
}
func NewConnection(address string, timeoutSeconds int) (*grpc.ClientConn, error) {
retryOpts := []grpc_retry.CallOption{
grpc_retry.WithMax(3),
grpc_retry.WithBackoff(grpc_retry.BackoffLinear(1000 * time.Millisecond)),
}
unaryInterceptors := []grpc.UnaryClientInterceptor{grpc_retry.UnaryClientInterceptor(retryOpts...)}
if timeoutSeconds > 0 {
unaryInterceptors = append(unaryInterceptors, grpc_util.WithTimeout(time.Duration(timeoutSeconds)*time.Second))
}
dialOpts := []grpc.DialOption{
grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...)),
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(unaryInterceptors...)),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)),
}
dialOpts = append(dialOpts, grpc.WithInsecure())
conn, err := grpc_util.BlockingDial(context.Background(), "unix", address, nil, dialOpts...)
if err != nil {
log.Errorf("Unable to connect to config management plugin service with address %s", address)
return nil, err
}
return conn, nil
}
// NewCMPServerClientset creates new instance of config management plugin server Clientset
func NewConfigManagementPluginClientSet(address string, timeoutSeconds int) Clientset {
return &clientSet{address: address, timeoutSeconds: timeoutSeconds}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
package plugin
import (
"fmt"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/argoproj/argo-cd/v2/common"
configUtil "github.com/argoproj/argo-cd/v2/util/config"
)
const (
ConfigManagementPluginKind string = "ConfigManagementPlugin"
)
type PluginConfig struct {
metav1.TypeMeta `json:",inline"`
Metadata metav1.ObjectMeta `json:"metadata"`
Spec PluginConfigSpec `json:"spec"`
}
type PluginConfigSpec struct {
Version string `json:"version"`
Init Command `json:"init,omitempty"`
Generate Command `json:"generate"`
Discover Discover `json:"discover"`
AllowConcurrency bool `json:"allowConcurrency"`
LockRepo bool `json:"lockRepo"`
}
//Discover holds find and fileName
type Discover struct {
Find Find `json:"find"`
FileName string `json:"fileName"`
}
// Command holds binary path and arguments list
type Command struct {
Command []string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
}
// Find holds find command or glob pattern
type Find struct {
Command
Glob string `json:"glob"`
}
func ReadPluginConfig(filePath string) (*PluginConfig, error) {
path := fmt.Sprintf("%s/%s", strings.TrimRight(filePath, "/"), common.PluginConfigFileName)
var config PluginConfig
err := configUtil.UnmarshalLocalFile(path, &config)
if err != nil {
return nil, err
}
if err = ValidatePluginConfig(config); err != nil {
return nil, err
}
return &config, nil
}
func ValidatePluginConfig(config PluginConfig) error {
if config.Metadata.Name == "" {
return fmt.Errorf("invalid plugin configuration file. metadata.name should be non-empty.")
}
if config.TypeMeta.Kind != ConfigManagementPluginKind {
return fmt.Errorf("invalid plugin configuration file. kind should be %s, found %s", ConfigManagementPluginKind, config.TypeMeta.Kind)
}
if len(config.Spec.Generate.Command) == 0 {
return fmt.Errorf("invalid plugin configuration file. spec.generate command should be non-empty")
}
if config.Spec.Discover.Find.Glob == "" && len(config.Spec.Discover.Find.Command.Command) == 0 && config.Spec.Discover.FileName == "" {
return fmt.Errorf("invalid plugin configuration file. atleast one of discover.find.command or discover.find.glob or discover.fineName should be non-empty")
}
return nil
}
func (cfg *PluginConfig) Address() string {
var address string
pluginSockFilePath := common.GetPluginSockFilePath()
if cfg.Spec.Version != "" {
address = fmt.Sprintf("%s/%s-%s.sock", pluginSockFilePath, cfg.Metadata.Name, cfg.Spec.Version)
} else {
address = fmt.Sprintf("%s/%s.sock", pluginSockFilePath, cfg.Metadata.Name)
}
return address
}

137
cmpserver/plugin/plugin.go Normal file
View File

@@ -0,0 +1,137 @@
package plugin
import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/mattn/go-zglob"
log "github.com/sirupsen/logrus"
"github.com/argoproj/argo-cd/v2/cmpserver/apiclient"
executil "github.com/argoproj/argo-cd/v2/util/exec"
)
// Service implements ConfigManagementPluginService interface
type Service struct {
initConstants CMPServerInitConstants
}
type CMPServerInitConstants struct {
PluginConfig PluginConfig
}
// NewService returns a new instance of the ConfigManagementPluginService
func NewService(initConstants CMPServerInitConstants) *Service {
return &Service{
initConstants: initConstants,
}
}
func runCommand(command Command, path string, env []string) (string, error) {
if len(command.Command) == 0 {
return "", fmt.Errorf("Command is empty")
}
cmd := exec.Command(command.Command[0], append(command.Command[1:], command.Args...)...)
cmd.Env = env
cmd.Dir = path
return executil.Run(cmd)
}
// Environ returns a list of environment variables in name=value format from a list of variables
func environ(envVars []*apiclient.EnvEntry) []string {
var environ []string
for _, item := range envVars {
if item != nil && item.Name != "" && item.Value != "" {
environ = append(environ, fmt.Sprintf("%s=%s", item.Name, item.Value))
}
}
return environ
}
// GenerateManifest runs generate command from plugin config file and returns generated manifest files
func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestRequest) (*apiclient.ManifestResponse, error) {
config := s.initConstants.PluginConfig
env := append(os.Environ(), environ(q.Env)...)
if len(config.Spec.Init.Command) > 0 {
_, err := runCommand(config.Spec.Init, q.AppPath, env)
if err != nil {
return &apiclient.ManifestResponse{}, err
}
}
out, err := runCommand(config.Spec.Generate, q.AppPath, env)
if err != nil {
return &apiclient.ManifestResponse{}, err
}
manifests, err := kube.SplitYAMLToString([]byte(out))
if err != nil {
return &apiclient.ManifestResponse{}, err
}
return &apiclient.ManifestResponse{
Manifests: manifests,
}, err
}
// MatchRepository checks whether the application repository type is supported by config management plugin server
func (s *Service) MatchRepository(ctx context.Context, q *apiclient.RepositoryRequest) (*apiclient.RepositoryResponse, error) {
var repoResponse apiclient.RepositoryResponse
config := s.initConstants.PluginConfig
if config.Spec.Discover.FileName != "" {
log.Debugf("config.Spec.Discover.FileName is provided")
pattern := strings.TrimSuffix(q.Path, "/") + "/" + strings.TrimPrefix(config.Spec.Discover.FileName, "/")
matches, err := filepath.Glob(pattern)
if err != nil || len(matches) == 0 {
log.Debugf("Could not find match for pattern %s. Error is %v.", pattern, err)
return &repoResponse, err
} else if len(matches) > 0 {
repoResponse.IsSupported = true
return &repoResponse, nil
}
}
if config.Spec.Discover.Find.Glob != "" {
log.Debugf("config.Spec.Discover.Find.Glob is provided")
pattern := strings.TrimSuffix(q.Path, "/") + "/" + strings.TrimPrefix(config.Spec.Discover.Find.Glob, "/")
// filepath.Glob doesn't have '**' support hence selecting third-party lib
// https://github.com/golang/go/issues/11862
matches, err := zglob.Glob(pattern)
if err != nil || len(matches) == 0 {
log.Debugf("Could not find match for pattern %s. Error is %v.", pattern, err)
return &repoResponse, err
} else if len(matches) > 0 {
repoResponse.IsSupported = true
return &repoResponse, nil
}
}
log.Debugf("Going to try runCommand.")
find, err := runCommand(config.Spec.Discover.Find.Command, q.Path, os.Environ())
if err != nil {
return &repoResponse, err
}
var isSupported bool
if find != "" {
isSupported = true
}
return &apiclient.RepositoryResponse{
IsSupported: isSupported,
}, nil
}
// GetPluginConfig returns plugin config
func (s *Service) GetPluginConfig(ctx context.Context, q *apiclient.ConfigRequest) (*apiclient.ConfigResponse, error) {
config := s.initConstants.PluginConfig
return &apiclient.ConfigResponse{
AllowConcurrency: config.Spec.AllowConcurrency,
LockRepo: config.Spec.LockRepo,
}, nil
}

View File

@@ -0,0 +1,61 @@
syntax = "proto3";
option go_package = "github.com/argoproj/argo-cd/v2/cmpserver/apiclient";
package plugin;
import "k8s.io/api/core/v1/generated.proto";
// ManifestRequest is a query for manifest generation.
message ManifestRequest {
// Name of the application for which the request is triggered
string appName = 1;
string appPath = 2;
string repoPath = 3;
bool noCache = 4;
repeated EnvEntry env = 5;
}
// EnvEntry represents an entry in the application's environment
message EnvEntry {
// Name is the name of the variable, usually expressed in uppercase
string name = 1;
// Value is the value of the variable
string value = 2;
}
message ManifestResponse {
repeated string manifests = 1;
string sourceType = 2;
}
message RepositoryRequest {
string path = 1;
repeated EnvEntry env = 2;
}
message RepositoryResponse {
bool isSupported = 1;
}
message ConfigRequest {
}
message ConfigResponse {
bool allowConcurrency = 1;
bool lockRepo = 2;
}
// ConfigManagementPlugin Service
service ConfigManagementPluginService {
// GenerateManifest generates manifest for application in specified repo name and revision
rpc GenerateManifest(ManifestRequest) returns (ManifestResponse) {
}
// MatchRepository returns whether or not the given path is supported by the plugin
rpc MatchRepository(RepositoryRequest) returns (RepositoryResponse) {
}
// Get configuration of the plugin
rpc GetPluginConfig(ConfigRequest) returns (ConfigResponse) {
}
}

View File

@@ -0,0 +1,65 @@
package plugin
import (
"context"
"os"
"testing"
"github.com/stretchr/testify/require"
"github.com/argoproj/argo-cd/v2/cmpserver/apiclient"
)
func newService(configFilePath string) (*Service, error) {
config, err := ReadPluginConfig(configFilePath)
if err != nil {
return nil, err
}
initConstants := CMPServerInitConstants{
PluginConfig: *config,
}
service := &Service{
initConstants: initConstants,
}
return service, nil
}
func TestMatchRepository(t *testing.T) {
configFilePath := "./testdata/ksonnet/config"
service, err := newService(configFilePath)
require.NoError(t, err)
q := apiclient.RepositoryRequest{}
path, err := os.Getwd()
require.NoError(t, err)
q.Path = path
res1, err := service.MatchRepository(context.Background(), &q)
require.NoError(t, err)
require.True(t, res1.IsSupported)
}
func Test_Negative_ConfigFile_DoesnotExist(t *testing.T) {
configFilePath := "./testdata/kustomize-neg/config"
service, err := newService(configFilePath)
require.Error(t, err)
require.Nil(t, service)
}
func TestGenerateManifest(t *testing.T) {
configFilePath := "./testdata/kustomize/config"
service, err := newService(configFilePath)
require.NoError(t, err)
q := apiclient.ManifestRequest{}
res1, err := service.GenerateManifest(context.Background(), &q)
require.NoError(t, err)
require.NotNil(t, res1)
expectedOutput := "{\"apiVersion\":\"v1\",\"data\":{\"foo\":\"bar\"},\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"
if res1 != nil {
require.Equal(t, expectedOutput, res1.Manifests[0])
}
}

View File

@@ -0,0 +1,15 @@
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: ksonnet
spec:
version: v1.0
init:
command: [ks, version]
generate:
command: [sh, -c, "ks show $ARGOCD_APP_ENV"]
discover:
find:
glob: "**/*/main.jsonnet"
allowConcurrency: false
lockRepo: false

View File

View File

@@ -0,0 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: kustomize
spec:
version: v1.0
init:
command: [kustomize, version]
generate:
command: [sh, -c, "cd testdata/kustomize && kustomize build"]
discover:
find:
command: [sh, -c, find . -name kustomization.yaml]
glob: "**/*/kustomization.yaml"
allowConcurrency: true
lockRepo: false

View File

@@ -0,0 +1,6 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: my-map
data:
foo: bar

View File

@@ -0,0 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: kustomize
spec:
version: v1.0
init:
command: [kustomize, version]
generate:
command: [sh, -c, "cd testdata/kustomize && kustomize build"]
discover:
find:
command: [sh, -c, find . -name kustomization.yaml]
glob: "**/*/kustomization.yaml"
allowConcurrency: true
lockRepo: false

View File

@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./cm.yaml

107
cmpserver/server.go Normal file
View File

@@ -0,0 +1,107 @@
package cmpserver
import (
"net"
"os"
"os/signal"
"syscall"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection"
"github.com/argoproj/argo-cd/v2/cmpserver/apiclient"
"github.com/argoproj/argo-cd/v2/cmpserver/plugin"
"github.com/argoproj/argo-cd/v2/common"
versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version"
"github.com/argoproj/argo-cd/v2/server/version"
"github.com/argoproj/argo-cd/v2/util/errors"
grpc_util "github.com/argoproj/argo-cd/v2/util/grpc"
)
// ArgoCDCMPServer is the config management plugin server implementation
type ArgoCDCMPServer struct {
log *log.Entry
opts []grpc.ServerOption
initConstants plugin.CMPServerInitConstants
stopCh chan os.Signal
doneCh chan interface{}
sig os.Signal
}
// NewServer returns a new instance of the Argo CD config management plugin server
func NewServer(initConstants plugin.CMPServerInitConstants) (*ArgoCDCMPServer, error) {
if os.Getenv(common.EnvEnableGRPCTimeHistogramEnv) == "true" {
grpc_prometheus.EnableHandlingTimeHistogram()
}
serverLog := log.NewEntry(log.StandardLogger())
streamInterceptors := []grpc.StreamServerInterceptor{grpc_logrus.StreamServerInterceptor(serverLog), grpc_prometheus.StreamServerInterceptor, grpc_util.PanicLoggerStreamServerInterceptor(serverLog)}
unaryInterceptors := []grpc.UnaryServerInterceptor{grpc_logrus.UnaryServerInterceptor(serverLog), grpc_prometheus.UnaryServerInterceptor, grpc_util.PanicLoggerUnaryServerInterceptor(serverLog)}
serverOpts := []grpc.ServerOption{
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(unaryInterceptors...)),
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(streamInterceptors...)),
grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize),
grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize),
}
return &ArgoCDCMPServer{
log: serverLog,
opts: serverOpts,
stopCh: make(chan os.Signal),
doneCh: make(chan interface{}),
initConstants: initConstants,
}, nil
}
func (a *ArgoCDCMPServer) Run() {
config := a.initConstants.PluginConfig
// Listen on the socket address
_ = os.Remove(config.Address())
listener, err := net.Listen("unix", config.Address())
errors.CheckError(err)
log.Infof("argocd-cmp-server %s serving on %s", common.GetVersion(), listener.Addr())
signal.Notify(a.stopCh, syscall.SIGINT, syscall.SIGTERM)
go a.Shutdown(config.Address())
grpcServer := a.CreateGRPC()
err = grpcServer.Serve(listener)
errors.CheckError(err)
if a.sig != nil {
<-a.doneCh
}
}
// CreateGRPC creates new configured grpc server
func (a *ArgoCDCMPServer) CreateGRPC() *grpc.Server {
server := grpc.NewServer(a.opts...)
versionpkg.RegisterVersionServiceServer(server, version.NewServer(nil, func() (bool, error) {
return true, nil
}))
pluginService := plugin.NewService(a.initConstants)
apiclient.RegisterConfigManagementPluginServiceServer(server, pluginService)
healthService := health.NewServer()
grpc_health_v1.RegisterHealthServer(server, healthService)
// Register reflection service on gRPC server.
reflection.Register(server)
return server
}
func (a *ArgoCDCMPServer) Shutdown(address string) {
defer signal.Stop(a.stopCh)
a.sig = <-a.stopCh
_ = os.Remove(address)
close(a.doneCh)
}

View File

@@ -54,6 +54,12 @@ const (
DefaultGnuPgHomePath = "/app/config/gpg/keys"
// Default path to repo server TLS endpoint config
DefaultAppConfigPath = "/app/config"
// Default path to cmp server plugin socket file
DefaultPluginSockFilePath = "/home/argocd/cmp-server/plugins"
// Default path to cmp server plugin configuration file
DefaultPluginConfigFilePath = "/home/argocd/cmp-server/config"
// Plugin Config File is a ConfigManagementPlugin manifest located inside the plugin container
PluginConfigFileName = "plugin.yaml"
)
// Argo CD application related constants
@@ -113,6 +119,9 @@ const (
// LabelValueSecretTypeRepoCreds indicates a secret type of repository credentials
LabelValueSecretTypeRepoCreds = "repo-creds"
// The Argo CD application name is used as the instance name
AnnotationKeyAppInstance = "argocd.argoproj.io/tracking-id"
// AnnotationCompareOptions is a comma-separated list of options for comparison
AnnotationCompareOptions = "argocd.argoproj.io/compare-options"
@@ -144,6 +153,12 @@ const (
EnvVarTLSDataPath = "ARGOCD_TLS_DATA_PATH"
// Specifies number of git remote operations attempts count
EnvGitAttemptsCount = "ARGOCD_GIT_ATTEMPTS_COUNT"
// Specifices max duration of git remote operation retry
EnvGitRetryMaxDuration = "ARGOCD_GIT_RETRY_MAX_DURATION"
// Specifies duration of git remote operation retry
EnvGitRetryDuration = "ARGOCD_GIT_RETRY_DURATION"
// Specifies fator of git remote operation retry
EnvGitRetryFactor = "ARGOCD_GIT_RETRY_FACTOR"
// Overrides git submodule support, true by default
EnvGitSubmoduleEnabled = "ARGOCD_GIT_MODULES_ENABLED"
// EnvGnuPGHome is the path to ArgoCD's GnuPG keyring for signature verification
@@ -172,6 +187,10 @@ const (
EnvLogFormat = "ARGOCD_LOG_FORMAT"
// EnvLogLevel log level that is defined by `--loglevel` option
EnvLogLevel = "ARGOCD_LOG_LEVEL"
// EnvMaxCookieNumber max number of chunks a cookie can be broken into
EnvMaxCookieNumber = "ARGOCD_MAX_COOKIE_NUMBER"
// EnvPluginSockFilePath allows to override the pluginSockFilePath for repo server and cmp server
EnvPluginSockFilePath = "ARGOCD_PLUGINSOCKFILEPATH"
)
const (
@@ -184,6 +203,18 @@ const (
CacheVersion = "1.8.3"
)
// Constants used by util/clusterauth package
const (
ClusterAuthRequestTimeout = 10 * time.Second
BearerTokenTimeout = 30 * time.Second
)
const (
DefaultGitRetryMaxDuration time.Duration = time.Second * 5 // 5s
DefaultGitRetryDuration time.Duration = time.Millisecond * 250 // 0.25s
DefaultGitRetryFactor = int64(2)
)
// GetGnuPGHomePath retrieves the path to use for GnuPG home directory, which is either taken from GNUPGHOME environment or a default value
func GetGnuPGHomePath() string {
if gnuPgHome := os.Getenv(EnvGnuPGHome); gnuPgHome == "" {
@@ -192,3 +223,12 @@ func GetGnuPGHomePath() string {
return gnuPgHome
}
}
// GetPluginSockFilePath retrieves the path of plugin sock file, which is either taken from PluginSockFilePath environment or a default value
func GetPluginSockFilePath() string {
if pluginSockFilePath := os.Getenv(EnvPluginSockFilePath); pluginSockFilePath == "" {
return DefaultPluginSockFilePath
} else {
return pluginSockFilePath
}
}

View File

@@ -28,6 +28,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
apiruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
@@ -112,6 +113,7 @@ type ApplicationController struct {
metricsServer *metrics.MetricsServer
kubectlSemaphore *semaphore.Weighted
clusterFilter func(cluster *appv1.Cluster) bool
projByNameCache sync.Map
}
// NewApplicationController creates new instance of ApplicationController.
@@ -127,6 +129,7 @@ func NewApplicationController(
selfHealTimeout time.Duration,
metricsPort int,
metricsCacheExpiration time.Duration,
metricsApplicationLabels []string,
kubectlParallelismLimit int64,
clusterFilter func(cluster *appv1.Cluster) bool,
) (*ApplicationController, error) {
@@ -151,6 +154,7 @@ func NewApplicationController(
settingsMgr: settingsMgr,
selfHealTimeout: selfHealTimeout,
clusterFilter: clusterFilter,
projByNameCache: sync.Map{},
}
if kubectlParallelismLimit > 0 {
ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit)
@@ -163,16 +167,26 @@ func NewApplicationController(
AddFunc: func(obj interface{}) {
if key, err := cache.MetaNamespaceKeyFunc(obj); err == nil {
ctrl.projectRefreshQueue.Add(key)
if projMeta, ok := obj.(metav1.Object); ok {
ctrl.InvalidateProjectsCache(projMeta.GetName())
}
}
},
UpdateFunc: func(old, new interface{}) {
if key, err := cache.MetaNamespaceKeyFunc(new); err == nil {
ctrl.projectRefreshQueue.Add(key)
if projMeta, ok := new.(metav1.Object); ok {
ctrl.InvalidateProjectsCache(projMeta.GetName())
}
}
},
DeleteFunc: func(obj interface{}) {
if key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj); err == nil {
ctrl.projectRefreshQueue.Add(key)
if projMeta, ok := obj.(metav1.Object); ok {
ctrl.InvalidateProjectsCache(projMeta.GetName())
}
}
},
})
@@ -180,7 +194,7 @@ func NewApplicationController(
var err error
ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, func(r *http.Request) error {
return nil
})
}, metricsApplicationLabels)
if err != nil {
return nil, err
}
@@ -190,8 +204,8 @@ func NewApplicationController(
return nil, err
}
}
stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterFilter)
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout)
stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterFilter, argo.NewResourceTracking())
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking())
ctrl.appInformer = appInformer
ctrl.appLister = appLister
ctrl.projInformer = projInformer
@@ -201,6 +215,19 @@ func NewApplicationController(
return &ctrl, nil
}
func (ctrl *ApplicationController) InvalidateProjectsCache(names ...string) {
if len(names) > 0 {
for _, name := range names {
ctrl.projByNameCache.Delete(name)
}
} else {
ctrl.projByNameCache.Range(func(key, _ interface{}) bool {
ctrl.projByNameCache.Delete(key)
return true
})
}
}
func (ctrl *ApplicationController) GetMetricsServer() *metrics.MetricsServer {
return ctrl.metricsServer
}
@@ -230,8 +257,35 @@ func isSelfReferencedApp(app *appv1.Application, ref v1.ObjectReference) bool {
gvk.Kind == application.ApplicationKind
}
func (ctrl *ApplicationController) newAppProjCache(name string) *appProjCache {
return &appProjCache{name: name, ctrl: ctrl}
}
type appProjCache struct {
name string
ctrl *ApplicationController
lock sync.Mutex
appProj *appv1.AppProject
}
func (projCache *appProjCache) GetAppProject(ctx context.Context) (*appv1.AppProject, error) {
projCache.lock.Lock()
defer projCache.lock.Unlock()
if projCache.appProj != nil {
return projCache.appProj, nil
}
proj, err := argo.GetAppProjectByName(projCache.name, applisters.NewAppProjectLister(projCache.ctrl.projInformer.GetIndexer()), projCache.ctrl.namespace, projCache.ctrl.settingsMgr, projCache.ctrl.db, ctx)
if err != nil {
return nil, err
}
projCache.appProj = proj
return projCache.appProj, nil
}
func (ctrl *ApplicationController) getAppProj(app *appv1.Application) (*appv1.AppProject, error) {
return argo.GetAppProject(&app.Spec, applisters.NewAppProjectLister(ctrl.projInformer.GetIndexer()), ctrl.namespace, ctrl.settingsMgr)
projCache, _ := ctrl.projByNameCache.LoadOrStore(app.Spec.GetProject(), ctrl.newAppProjCache(app.Spec.GetProject()))
return projCache.(*appProjCache).GetAppProject(context.TODO())
}
func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]bool, ref v1.ObjectReference) {
@@ -244,12 +298,8 @@ func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]b
if !ok {
continue
}
// exclude resource unless it is permitted in the app project. If project is not permitted then it is not controlled by the user and there is no point showing the warning.
if proj, err := ctrl.getAppProj(app); err == nil && proj.IsGroupKindPermitted(ref.GroupVersionKind().GroupKind(), true) &&
!isKnownOrphanedResourceExclusion(kube.NewResourceKey(ref.GroupVersionKind().Group, ref.GroupVersionKind().Kind, ref.Namespace, ref.Name), proj) {
managedByApp[app.Name] = false
}
managedByApp[app.Name] = true
}
}
}
@@ -276,17 +326,21 @@ func (ctrl *ApplicationController) handleObjectUpdated(managedByApp map[string]b
func (ctrl *ApplicationController) setAppManagedResources(a *appv1.Application, comparisonResult *comparisonResult) (*appv1.ApplicationTree, error) {
managedResources, err := ctrl.managedResources(comparisonResult)
if err != nil {
return nil, err
return nil, fmt.Errorf("error getting managed resources: %s", err)
}
tree, err := ctrl.getResourceTree(a, managedResources)
if err != nil {
return nil, err
return nil, fmt.Errorf("error getting resource tree: %s", err)
}
err = ctrl.cache.SetAppResourcesTree(a.Name, tree)
if err != nil {
return nil, err
return nil, fmt.Errorf("error setting app resource tree: %s", err)
}
return tree, ctrl.cache.SetAppManagedResources(a.Name, managedResources)
err = ctrl.cache.SetAppManagedResources(a.Name, managedResources)
if err != nil {
return nil, fmt.Errorf("error setting app managed resources: %s", err)
}
return tree, nil
}
// returns true of given resources exist in the namespace by default and not managed by the user
@@ -316,7 +370,7 @@ func isKnownOrphanedResourceExclusion(key kube.ResourceKey, proj *appv1.AppProje
func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managedResources []*appv1.ResourceDiff) (*appv1.ApplicationTree, error) {
nodes := make([]appv1.ResourceNode, 0)
proj, err := argo.GetAppProject(&a.Spec, applisters.NewAppProjectLister(ctrl.projInformer.GetIndexer()), ctrl.namespace, ctrl.settingsMgr)
proj, err := ctrl.getAppProj(a)
if err != nil {
return nil, err
}
@@ -355,8 +409,12 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed
},
})
} else {
err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, kube.GetResourceKey(live), func(child appv1.ResourceNode, appName string) {
err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, kube.GetResourceKey(live), func(child appv1.ResourceNode, appName string) bool {
if !proj.IsResourcePermitted(schema.GroupKind{Group: child.ResourceRef.Group, Kind: child.ResourceRef.Kind}, child.Namespace, a.Spec.Destination) {
return false
}
nodes = append(nodes, child)
return true
})
if err != nil {
return nil, err
@@ -366,16 +424,18 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed
orphanedNodes := make([]appv1.ResourceNode, 0)
for k := range orphanedNodesMap {
if k.Namespace != "" && proj.IsGroupKindPermitted(k.GroupKind(), true) && !isKnownOrphanedResourceExclusion(k, proj) {
err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, k, func(child appv1.ResourceNode, appName string) {
err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, k, func(child appv1.ResourceNode, appName string) bool {
belongToAnotherApp := false
if appName != "" {
if _, exists, err := ctrl.appInformer.GetIndexer().GetByKey(ctrl.namespace + "/" + appName); exists && err == nil {
belongToAnotherApp = true
}
}
if !belongToAnotherApp {
orphanedNodes = append(orphanedNodes, child)
if belongToAnotherApp || !proj.IsResourcePermitted(schema.GroupKind{Group: child.ResourceRef.Group, Kind: child.ResourceRef.Kind}, child.Namespace, a.Spec.Destination) {
return false
}
orphanedNodes = append(orphanedNodes, child)
return true
})
if err != nil {
return nil, err
@@ -510,18 +570,18 @@ func (ctrl *ApplicationController) managedResources(comparisonResult *comparison
var err error
target, live, err = diff.HideSecretData(res.Target, res.Live)
if err != nil {
return nil, err
return nil, fmt.Errorf("error hiding secret data: %s", err)
}
compareOptions, err := ctrl.settingsMgr.GetResourceCompareOptions()
if err != nil {
return nil, err
return nil, fmt.Errorf("error getting resource compare options: %s", err)
}
resDiffPtr, err := diff.Diff(target, live,
diff.WithNormalizer(comparisonResult.diffNormalizer),
diff.WithLogr(logutils.NewLogrusLogger(logutils.NewWithCurrentConfig())),
diff.IgnoreAggregatedRoles(compareOptions.IgnoreAggregatedRoles))
if err != nil {
return nil, err
return nil, fmt.Errorf("error applying diff: %s", err)
}
resDiff = *resDiffPtr
}
@@ -529,7 +589,7 @@ func (ctrl *ApplicationController) managedResources(comparisonResult *comparison
if live != nil {
data, err := json.Marshal(live)
if err != nil {
return nil, err
return nil, fmt.Errorf("error marshaling live json: %s", err)
}
item.LiveState = string(data)
} else {
@@ -539,7 +599,7 @@ func (ctrl *ApplicationController) managedResources(comparisonResult *comparison
if target != nil {
data, err := json.Marshal(target)
if err != nil {
return nil, err
return nil, fmt.Errorf("error marshaling target json: %s", err)
}
item.TargetState = string(data)
} else {
@@ -801,7 +861,7 @@ func (ctrl *ApplicationController) getPermittedAppLiveObjects(app *appv1.Applica
}
// Don't delete live resources which are not permitted in the app project
for k, v := range objsMap {
if !proj.IsLiveResourcePermitted(v, app.Spec.Destination.Server) {
if !proj.IsLiveResourcePermitted(v, app.Spec.Destination.Server, app.Spec.Destination.Name) {
delete(objsMap, k)
}
}
@@ -1205,6 +1265,13 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
app.Status.Sync.Status = appv1.SyncStatusCodeUnknown
app.Status.Health.Status = health.HealthStatusUnknown
ctrl.persistAppStatus(origApp, &app.Status)
if err := ctrl.cache.SetAppResourcesTree(app.Name, &appv1.ApplicationTree{}); err != nil {
log.Warnf("failed to set app resource tree: %v", err)
}
if err := ctrl.cache.SetAppManagedResources(app.Name, nil); err != nil {
log.Warnf("failed to set app managed resources tree: %v", err)
}
return
}
@@ -1594,7 +1661,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar
return nil, nil
}
proj, err := ctrl.getAppProj(app)
proj, err := applisters.NewAppProjectLister(ctrl.projInformer.GetIndexer()).AppProjects(ctrl.namespace).Get(app.Spec.GetProject())
if err != nil {
return nil, nil
}

View File

@@ -106,6 +106,7 @@ func newFakeController(data *fakeData) *ApplicationController {
time.Minute,
common.DefaultPortArgoCDMetrics,
data.metricsCacheExpiration,
[]string{},
0,
nil,
)
@@ -135,12 +136,12 @@ func newFakeController(data *fakeData) *ApplicationController {
mockStateCache.On("GetClusterCache", mock.Anything).Return(&clusterCacheMock, nil)
mockStateCache.On("IterateHierarchy", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
key := args[1].(kube.ResourceKey)
action := args[2].(func(child argoappv1.ResourceNode, appName string))
action := args[2].(func(child argoappv1.ResourceNode, appName string) bool)
appName := ""
if res, ok := data.namespacedResources[key]; ok {
appName = res.AppName
}
action(argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Kind: key.Kind, Group: key.Group, Namespace: key.Namespace, Name: key.Name}}, appName)
_ = action(argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Kind: key.Kind, Group: key.Group, Namespace: key.Namespace, Name: key.Name}}, appName)
}).Return(nil)
return ctrl
}
@@ -784,11 +785,11 @@ func TestHandleOrphanedResourceUpdated(t *testing.T) {
isRequested, level := ctrl.isRefreshRequested(app1.Name)
assert.True(t, isRequested)
assert.Equal(t, ComparisonWithNothing, level)
assert.Equal(t, CompareWithRecent, level)
isRequested, level = ctrl.isRefreshRequested(app2.Name)
assert.True(t, isRequested)
assert.Equal(t, ComparisonWithNothing, level)
assert.Equal(t, CompareWithRecent, level)
}
func TestGetResourceTree_HasOrphanedResources(t *testing.T) {

View File

@@ -3,7 +3,7 @@ package cache
import (
"context"
"fmt"
"os"
"math"
"reflect"
"sync"
"time"
@@ -24,6 +24,7 @@ import (
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/env"
logutils "github.com/argoproj/argo-cd/v2/util/log"
"github.com/argoproj/argo-cd/v2/util/lua"
"github.com/argoproj/argo-cd/v2/util/settings"
@@ -32,31 +33,53 @@ import (
const (
// EnvClusterCacheResyncDuration is the env variable that holds cluster cache re-sync duration
EnvClusterCacheResyncDuration = "ARGOCD_CLUSTER_CACHE_RESYNC_DURATION"
// EnvClusterCacheWatchResyncDuration is the env variable that holds cluster cache watch re-sync duration
EnvClusterCacheWatchResyncDuration = "ARGOCD_CLUSTER_CACHE_WATCH_RESYNC_DURATION"
// EnvClusterCacheListPageSize is the env variable to control size of the list page size when making K8s queries
EnvClusterCacheListPageSize = "ARGOCD_CLUSTER_CACHE_LIST_PAGE_SIZE"
// EnvClusterCacheListSemaphore is the env variable to control size of the list semaphore
// This is used to limit the number of concurrent memory consuming operations on the
// k8s list queries results across all clusters to avoid memory spikes during cache initialization.
EnvClusterCacheListSemaphore = "ARGOCD_CLUSTER_CACHE_LIST_SEMAPHORE"
)
// GitOps engine cluster cache tuning options
var (
// K8SClusterResyncDuration controls the duration of cluster cache refresh
K8SClusterResyncDuration = 12 * time.Hour
// clusterCacheResyncDuration controls the duration of cluster cache refresh.
// NOTE: this differs from gitops-engine default of 24h
clusterCacheResyncDuration = 12 * time.Hour
// clusterCacheWatchResyncDuration controls the maximum duration that group/kind watches are allowed to run
// for before relisting & restarting the watch
clusterCacheWatchResyncDuration = 10 * time.Minute
// The default limit of 50 is chosen based on experiments.
clusterCacheListSemaphoreSize int64 = 50
// clusterCacheListPageSize is the page size when performing K8s list requests.
// 500 is equal to kubectl's size
clusterCacheListPageSize int64 = 500
)
func init() {
if clusterResyncDurationStr := os.Getenv(EnvClusterCacheResyncDuration); clusterResyncDurationStr != "" {
if duration, err := time.ParseDuration(clusterResyncDurationStr); err == nil {
K8SClusterResyncDuration = duration
}
}
clusterCacheResyncDuration = env.ParseDurationFromEnv(EnvClusterCacheResyncDuration, clusterCacheResyncDuration, 0, math.MaxInt64)
clusterCacheWatchResyncDuration = env.ParseDurationFromEnv(EnvClusterCacheWatchResyncDuration, clusterCacheWatchResyncDuration, 0, math.MaxInt64)
clusterCacheListPageSize = env.ParseInt64FromEnv(EnvClusterCacheListPageSize, clusterCacheListPageSize, 0, math.MaxInt64)
clusterCacheListSemaphoreSize = env.ParseInt64FromEnv(EnvClusterCacheListSemaphore, clusterCacheListSemaphoreSize, 0, math.MaxInt64)
}
type LiveStateCache interface {
// Returns k8s server version
GetVersionsInfo(serverURL string) (string, []metav1.APIGroup, error)
GetVersionsInfo(serverURL string) (string, []kube.APIResourceInfo, error)
// Returns true of given group kind is a namespaced resource
IsNamespaced(server string, gk schema.GroupKind) (bool, error)
// Returns synced cluster cache
GetClusterCache(server string) (clustercache.ClusterCache, error)
// Executes give callback against resource specified by the key and all its children
IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string)) error
IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error
// Returns state of live nodes which correspond for target nodes of specified application.
GetManagedLiveObjs(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error)
// IterateResources iterates all resource stored in cache
@@ -105,19 +128,19 @@ func NewLiveStateCache(
kubectl kube.Kubectl,
metricsServer *metrics.MetricsServer,
onObjectUpdated ObjectUpdatedHandler,
clusterFilter func(cluster *appv1.Cluster) bool) LiveStateCache {
clusterFilter func(cluster *appv1.Cluster) bool,
resourceTracking argo.ResourceTracking) LiveStateCache {
return &liveStateCache{
appInformer: appInformer,
db: db,
clusters: make(map[string]clustercache.ClusterCache),
onObjectUpdated: onObjectUpdated,
kubectl: kubectl,
settingsMgr: settingsMgr,
metricsServer: metricsServer,
// The default limit of 50 is chosen based on experiments.
listSemaphore: semaphore.NewWeighted(50),
clusterFilter: clusterFilter,
appInformer: appInformer,
db: db,
clusters: make(map[string]clustercache.ClusterCache),
onObjectUpdated: onObjectUpdated,
kubectl: kubectl,
settingsMgr: settingsMgr,
metricsServer: metricsServer,
clusterFilter: clusterFilter,
resourceTracking: resourceTracking,
}
}
@@ -127,17 +150,14 @@ type cacheSettings struct {
}
type liveStateCache struct {
db db.ArgoDB
appInformer cache.SharedIndexInformer
onObjectUpdated ObjectUpdatedHandler
kubectl kube.Kubectl
settingsMgr *settings.SettingsManager
metricsServer *metrics.MetricsServer
clusterFilter func(cluster *appv1.Cluster) bool
// listSemaphore is used to limit the number of concurrent memory consuming operations on the
// k8s list queries results across all clusters to avoid memory spikes during cache initialization.
listSemaphore *semaphore.Weighted
db db.ArgoDB
appInformer cache.SharedIndexInformer
onObjectUpdated ObjectUpdatedHandler
kubectl kube.Kubectl
settingsMgr *settings.SettingsManager
metricsServer *metrics.MetricsServer
clusterFilter func(cluster *appv1.Cluster) bool
resourceTracking argo.ResourceTracking
clusters map[string]clustercache.ClusterCache
cacheSettings cacheSettings
@@ -285,9 +305,12 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
return nil, fmt.Errorf("controller is configured to ignore cluster %s", cluster.Server)
}
clusterCache = clustercache.NewClusterCache(cluster.RESTConfig(),
clustercache.SetListSemaphore(c.listSemaphore),
clustercache.SetResyncTimeout(K8SClusterResyncDuration),
trackingMethod := argo.GetTrackingMethod(c.settingsMgr)
clusterCacheOpts := []clustercache.UpdateSettingsFunc{
clustercache.SetListSemaphore(semaphore.NewWeighted(clusterCacheListSemaphoreSize)),
clustercache.SetListPageSize(clusterCacheListPageSize),
clustercache.SetWatchResyncTimeout(clusterCacheWatchResyncDuration),
clustercache.SetResyncTimeout(clusterCacheResyncDuration),
clustercache.SetSettings(cacheSettings.clusterSettings),
clustercache.SetNamespaces(cluster.Namespaces),
clustercache.SetClusterResources(cluster.ClusterResources),
@@ -295,7 +318,8 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
res := &ResourceInfo{}
populateNodeInfo(un, res)
res.Health, _ = health.GetResourceHealth(un, cacheSettings.clusterSettings.ResourceHealthOverride)
appName := kube.GetAppInstanceLabel(un, cacheSettings.appInstanceLabelKey)
appName := c.resourceTracking.GetAppName(un, cacheSettings.appInstanceLabelKey, trackingMethod)
if isRoot && appName != "" {
res.AppName = appName
}
@@ -306,7 +330,9 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
return res, res.AppName != "" || gvk.Kind == kube.CustomResourceDefinitionKind
}),
clustercache.SetLogr(logutils.NewLogrusLogger(log.WithField("server", cluster.Server))),
)
}
clusterCache = clustercache.NewClusterCache(cluster.RESTConfig(), clusterCacheOpts...)
_ = clusterCache.OnResourceUpdated(func(newRes *clustercache.Resource, oldRes *clustercache.Resource, namespaceResources map[kube.ResourceKey]*clustercache.Resource) {
toNotify := make(map[string]bool)
@@ -371,13 +397,13 @@ func (c *liveStateCache) IsNamespaced(server string, gk schema.GroupKind) (bool,
return clusterInfo.IsNamespaced(gk)
}
func (c *liveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string)) error {
func (c *liveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(child appv1.ResourceNode, appName string) bool) error {
clusterInfo, err := c.getSyncedCluster(server)
if err != nil {
return err
}
clusterInfo.IterateHierarchy(key, func(resource *clustercache.Resource, namespaceResources map[kube.ResourceKey]*clustercache.Resource) {
action(asResourceNode(resource), getApp(resource, namespaceResources))
clusterInfo.IterateHierarchy(key, func(resource *clustercache.Resource, namespaceResources map[kube.ResourceKey]*clustercache.Resource) bool {
return action(asResourceNode(resource), getApp(resource, namespaceResources))
})
return nil
}
@@ -419,12 +445,12 @@ func (c *liveStateCache) GetManagedLiveObjs(a *appv1.Application, targetObjs []*
})
}
func (c *liveStateCache) GetVersionsInfo(serverURL string) (string, []metav1.APIGroup, error) {
func (c *liveStateCache) GetVersionsInfo(serverURL string) (string, []kube.APIResourceInfo, error) {
clusterInfo, err := c.getSyncedCluster(serverURL)
if err != nil {
return "", nil, err
}
return clusterInfo.GetServerVersion(), clusterInfo.GetAPIGroups(), nil
return clusterInfo.GetServerVersion(), clusterInfo.GetAPIResources(), nil
}
func (c *liveStateCache) isClusterHasApps(apps []interface{}, cluster *appv1.Cluster) bool {

View File

@@ -1,9 +1,12 @@
package cache
import (
"errors"
"fmt"
"strings"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/text"
v1 "k8s.io/api/core/v1"
@@ -86,16 +89,36 @@ func populateServiceInfo(un *unstructured.Unstructured, res *ResourceInfo) {
res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetLabels: targetLabels, Ingress: ingress}
}
func getServiceName(backend map[string]interface{}, gvk schema.GroupVersionKind) (string, error) {
switch gvk.Group {
case "extensions":
return fmt.Sprintf("%s", backend["serviceName"]), nil
case "networking.k8s.io":
switch gvk.Version {
case "v1beta1":
return fmt.Sprintf("%s", backend["serviceName"]), nil
case "v1":
if service, ok, err := unstructured.NestedMap(backend, "service"); ok && err == nil {
return fmt.Sprintf("%s", service["name"]), nil
}
}
}
return "", errors.New("unable to resolve string")
}
func populateIngressInfo(un *unstructured.Unstructured, res *ResourceInfo) {
ingress := getIngress(un)
targetsMap := make(map[v1alpha1.ResourceRef]bool)
gvk := un.GroupVersionKind()
if backend, ok, err := unstructured.NestedMap(un.Object, "spec", "backend"); ok && err == nil {
targetsMap[v1alpha1.ResourceRef{
Group: "",
Kind: kube.ServiceKind,
Namespace: un.GetNamespace(),
Name: fmt.Sprintf("%s", backend["serviceName"]),
}] = true
if serviceName, err := getServiceName(backend, gvk); err == nil {
targetsMap[v1alpha1.ResourceRef{
Group: "",
Kind: kube.ServiceKind,
Namespace: un.GetNamespace(),
Name: serviceName,
}] = true
}
}
urlsSet := make(map[string]bool)
if rules, ok, err := unstructured.NestedSlice(un.Object, "spec", "rules"); ok && err == nil {
@@ -123,13 +146,15 @@ func populateIngressInfo(un *unstructured.Unstructured, res *ResourceInfo) {
continue
}
if serviceName, ok, err := unstructured.NestedString(path, "backend", "serviceName"); ok && err == nil {
targetsMap[v1alpha1.ResourceRef{
Group: "",
Kind: kube.ServiceKind,
Namespace: un.GetNamespace(),
Name: serviceName,
}] = true
if backend, ok, err := unstructured.NestedMap(path, "backend"); ok && err == nil {
if serviceName, err := getServiceName(backend, gvk); err == nil {
targetsMap[v1alpha1.ResourceRef{
Group: "",
Kind: kube.ServiceKind,
Namespace: un.GetNamespace(),
Name: serviceName,
}] = true
}
}
if host == nil || host == "" {

View File

@@ -133,6 +133,43 @@ var (
ingress:
- ip: 107.178.210.11`)
testIngressNetworkingV1 = strToUnstructured(`
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: helm-guestbook
namespace: default
uid: "4"
spec:
backend:
service:
name: not-found-service
port:
number: 443
rules:
- host: helm-guestbook.com
http:
paths:
- backend:
service:
name: helm-guestbook
port:
number: 443
path: /
- backend:
service:
name: helm-guestbook
port:
name: https
path: /
tls:
- host: helm-guestbook.com
secretName: my-tls-secret
status:
loadBalancer:
ingress:
- ip: 107.178.210.11`)
testIstioVirtualService = strToUnstructured(`
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
@@ -255,27 +292,35 @@ func TestGetIstioVirtualServiceInfo(t *testing.T) {
}
func TestGetIngressInfo(t *testing.T) {
info := &ResourceInfo{}
populateNodeInfo(testIngress, info)
assert.Equal(t, 0, len(info.Info))
sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
})
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
TargetRefs: []v1alpha1.ResourceRef{{
Namespace: "default",
Group: "",
Kind: kube.ServiceKind,
Name: "not-found-service",
}, {
Namespace: "default",
Group: "",
Kind: kube.ServiceKind,
Name: "helm-guestbook",
}},
ExternalURLs: []string{"https://helm-guestbook.com/"},
}, info.NetworkingInfo)
var tests = []struct {
Ingress *unstructured.Unstructured
}{
{testIngress},
{testIngressNetworkingV1},
}
for _, tc := range tests {
info := &ResourceInfo{}
populateNodeInfo(tc.Ingress, info)
assert.Equal(t, 0, len(info.Info))
sort.Slice(info.NetworkingInfo.TargetRefs, func(i, j int) bool {
return strings.Compare(info.NetworkingInfo.TargetRefs[j].Name, info.NetworkingInfo.TargetRefs[i].Name) < 0
})
assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{
Ingress: []v1.LoadBalancerIngress{{IP: "107.178.210.11"}},
TargetRefs: []v1alpha1.ResourceRef{{
Namespace: "default",
Group: "",
Kind: kube.ServiceKind,
Name: "not-found-service",
}, {
Namespace: "default",
Group: "",
Kind: kube.ServiceKind,
Name: "helm-guestbook",
}},
ExternalURLs: []string{"https://helm-guestbook.com/"},
}, info.NetworkingInfo)
}
}
func TestGetIngressInfoWildCardPath(t *testing.T) {
@@ -396,7 +441,7 @@ func TestGetIngressInfoNoHost(t *testing.T) {
}
func TestExternalUrlWithSubPath(t *testing.T) {
ingress := strToUnstructured(`
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: helm-guestbook
@@ -424,7 +469,7 @@ func TestExternalUrlWithSubPath(t *testing.T) {
}
func TestExternalUrlWithMultipleSubPaths(t *testing.T) {
ingress := strToUnstructured(`
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: helm-guestbook
@@ -463,7 +508,7 @@ func TestExternalUrlWithMultipleSubPaths(t *testing.T) {
}
func TestExternalUrlWithNoSubPath(t *testing.T) {
ingress := strToUnstructured(`
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: helm-guestbook

View File

@@ -17,8 +17,6 @@ import (
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
)
@@ -113,7 +111,7 @@ func (_m *LiveStateCache) GetNamespaceTopLevelResources(server string, namespace
}
// GetVersionsInfo provides a mock function with given fields: serverURL
func (_m *LiveStateCache) GetVersionsInfo(serverURL string) (string, []v1.APIGroup, error) {
func (_m *LiveStateCache) GetVersionsInfo(serverURL string) (string, []kube.APIResourceInfo, error) {
ret := _m.Called(serverURL)
var r0 string
@@ -123,12 +121,12 @@ func (_m *LiveStateCache) GetVersionsInfo(serverURL string) (string, []v1.APIGro
r0 = ret.Get(0).(string)
}
var r1 []v1.APIGroup
if rf, ok := ret.Get(1).(func(string) []v1.APIGroup); ok {
var r1 []kube.APIResourceInfo
if rf, ok := ret.Get(1).(func(string) []kube.APIResourceInfo); ok {
r1 = rf(serverURL)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).([]v1.APIGroup)
r1 = ret.Get(1).([]kube.APIResourceInfo)
}
}
@@ -178,11 +176,11 @@ func (_m *LiveStateCache) IsNamespaced(server string, gk schema.GroupKind) (bool
}
// IterateHierarchy provides a mock function with given fields: server, key, action
func (_m *LiveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(v1alpha1.ResourceNode, string)) error {
func (_m *LiveStateCache) IterateHierarchy(server string, key kube.ResourceKey, action func(v1alpha1.ResourceNode, string) bool) error {
ret := _m.Called(server, key, action)
var r0 error
if rf, ok := ret.Get(0).(func(string, kube.ResourceKey, func(v1alpha1.ResourceNode, string)) error); ok {
if rf, ok := ret.Get(0).(func(string, kube.ResourceKey, func(v1alpha1.ResourceNode, string) bool) error); ok {
r0 = rf(server, key, action)
} else {
r0 = ret.Error(0)

View File

@@ -106,7 +106,7 @@ func (c *clusterInfoUpdater) updateClusterInfo(cluster appv1.Cluster, info *cach
}
if info != nil {
clusterInfo.ServerVersion = info.K8SVersion
clusterInfo.APIVersions = argo.APIGroupsToVersions(info.APIGroups)
clusterInfo.APIVersions = argo.APIResourcesToStrings(info.APIResources, false)
if info.LastCacheSyncTime == nil {
clusterInfo.ConnectionState.Status = appv1.ConnectionStatusUnknown
} else if info.SyncError == nil {

View File

@@ -41,6 +41,12 @@ var (
descClusterDefaultLabels,
nil,
)
descClusterConnectionStatus = prometheus.NewDesc(
"argocd_cluster_connection_status",
"The k8s cluster current connection status.",
append(descClusterDefaultLabels, "k8s_version"),
nil,
)
)
type HasClustersInfo interface {
@@ -77,9 +83,11 @@ func (c *clusterCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- descClusterCacheResources
ch <- descClusterAPIs
ch <- descClusterCacheAgeSeconds
ch <- descClusterConnectionStatus
}
func (c *clusterCollector) Collect(ch chan<- prometheus.Metric) {
now := time.Now()
for _, c := range c.info {
defaultValues := []string{c.Server}
@@ -91,5 +99,6 @@ func (c *clusterCollector) Collect(ch chan<- prometheus.Metric) {
cacheAgeSeconds = int(now.Sub(*c.LastCacheSyncTime).Seconds())
}
ch <- prometheus.MustNewConstMetric(descClusterCacheAgeSeconds, prometheus.GaugeValue, float64(cacheAgeSeconds), defaultValues...)
ch <- prometheus.MustNewConstMetric(descClusterConnectionStatus, prometheus.GaugeValue, boolFloat64(c.SyncError == nil), append(defaultValues, c.K8SVersion)...)
}
}

View File

@@ -0,0 +1,104 @@
package metrics
import (
"errors"
"testing"
gitopsCache "github.com/argoproj/gitops-engine/pkg/cache"
)
func TestMetricClusterConnectivity(t *testing.T) {
type testCases struct {
testCombination
skip bool
description string
metricLabels []string
clustersInfo []gitopsCache.ClusterInfo
}
cases := []testCases{
{
description: "metric will have value 1 if connected with the cluster",
skip: false,
metricLabels: []string{"non-existing"},
testCombination: testCombination{
applications: []string{fakeApp},
responseContains: `
# TYPE argocd_cluster_connection_status gauge
argocd_cluster_connection_status{k8s_version="1.21",server="server1"} 1
`,
},
clustersInfo: []gitopsCache.ClusterInfo{
{
Server: "server1",
K8SVersion: "1.21",
SyncError: nil,
},
},
},
{
description: "metric will have value 0 if not connected with the cluster",
skip: false,
metricLabels: []string{"non-existing"},
testCombination: testCombination{
applications: []string{fakeApp},
responseContains: `
# TYPE argocd_cluster_connection_status gauge
argocd_cluster_connection_status{k8s_version="1.21",server="server1"} 0
`,
},
clustersInfo: []gitopsCache.ClusterInfo{
{
Server: "server1",
K8SVersion: "1.21",
SyncError: errors.New("error connecting with cluster"),
},
},
},
{
description: "will have one metric per cluster",
skip: false,
metricLabels: []string{"non-existing"},
testCombination: testCombination{
applications: []string{fakeApp},
responseContains: `
# TYPE argocd_cluster_connection_status gauge
argocd_cluster_connection_status{k8s_version="1.21",server="server1"} 1
argocd_cluster_connection_status{k8s_version="1.21",server="server2"} 1
argocd_cluster_connection_status{k8s_version="1.21",server="server3"} 1
`,
},
clustersInfo: []gitopsCache.ClusterInfo{
{
Server: "server1",
K8SVersion: "1.21",
SyncError: nil,
},
{
Server: "server2",
K8SVersion: "1.21",
SyncError: nil,
},
{
Server: "server3",
K8SVersion: "1.21",
SyncError: nil,
},
},
},
}
for _, c := range cases {
c := c
t.Run(c.description, func(t *testing.T) {
if !c.skip {
cfg := TestMetricServerConfig{
FakeAppYAMLs: c.applications,
ExpectedResponse: c.responseContains,
AppLabels: c.metricLabels,
ClustersInfo: c.clustersInfo,
}
runTest(t, cfg)
}
})
}
}

View File

@@ -7,6 +7,7 @@ import (
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/argoproj/gitops-engine/pkg/health"
@@ -20,6 +21,7 @@ import (
applister "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/git"
"github.com/argoproj/argo-cd/v2/util/healthz"
"github.com/argoproj/argo-cd/v2/util/profile"
)
type MetricsServer struct {
@@ -49,6 +51,8 @@ const (
var (
descAppDefaultLabels = []string{"namespace", "name", "project"}
descAppLabels *prometheus.Desc
descAppInfo = prometheus.NewDesc(
"argocd_app_info",
"Information about application.",
@@ -121,7 +125,7 @@ var (
redisRequestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "argocd_redis_request_total",
Help: "Number of kubernetes requests executed during application reconciliation.",
Help: "Number of redis requests executed during application reconciliation.",
},
[]string{"hostname", "initiator", "failed"},
)
@@ -137,19 +141,31 @@ var (
)
// NewMetricsServer returns a new prometheus server which collects application metrics
func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, healthCheck func(r *http.Request) error) (*MetricsServer, error) {
func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, healthCheck func(r *http.Request) error, appLabels []string) (*MetricsServer, error) {
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
if len(appLabels) > 0 {
normalizedLabels := normalizeLabels("label", appLabels)
descAppLabels = prometheus.NewDesc(
"argocd_app_labels",
"Argo Application labels converted to Prometheus labels",
append(descAppDefaultLabels, normalizedLabels...),
nil,
)
}
mux := http.NewServeMux()
registry := NewAppRegistry(appLister, appFilter)
registry := NewAppRegistry(appLister, appFilter, appLabels)
mux.Handle(MetricsPath, promhttp.HandlerFor(prometheus.Gatherers{
// contains app controller specific metrics
registry,
// contains process, golang and controller workqueues metrics
prometheus.DefaultGatherer,
}, promhttp.HandlerOpts{}))
profile.RegisterProfiler(mux)
healthz.ServeHealthCheck(mux, healthCheck)
registry.MustRegister(syncCounter)
@@ -180,6 +196,17 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil
}, nil
}
func normalizeLabels(prefix string, appLabels []string) []string {
results := []string{}
for _, label := range appLabels {
//prometheus labels don't accept dash in their name
curr := strings.ReplaceAll(label, "-", "_")
result := fmt.Sprintf("%s_%s", prefix, curr)
results = append(results, result)
}
return results
}
func (m *MetricsServer) RegisterClustersInfoSource(ctx context.Context, source HasClustersInfo) {
collector := &clusterCollector{infoSource: source}
go collector.Run(ctx)
@@ -272,25 +299,30 @@ func (m *MetricsServer) SetExpiration(cacheExpiration time.Duration) error {
type appCollector struct {
store applister.ApplicationLister
appFilter func(obj interface{}) bool
appLabels []string
}
// NewAppCollector returns a prometheus collector for application metrics
func NewAppCollector(appLister applister.ApplicationLister, appFilter func(obj interface{}) bool) prometheus.Collector {
func NewAppCollector(appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, appLabels []string) prometheus.Collector {
return &appCollector{
store: appLister,
appFilter: appFilter,
appLabels: appLabels,
}
}
// NewAppRegistry creates a new prometheus registry that collects applications
func NewAppRegistry(appLister applister.ApplicationLister, appFilter func(obj interface{}) bool) *prometheus.Registry {
func NewAppRegistry(appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, appLabels []string) *prometheus.Registry {
registry := prometheus.NewRegistry()
registry.MustRegister(NewAppCollector(appLister, appFilter))
registry.MustRegister(NewAppCollector(appLister, appFilter, appLabels))
return registry
}
// Describe implements the prometheus.Collector interface
func (c *appCollector) Describe(ch chan<- *prometheus.Desc) {
if len(c.appLabels) > 0 {
ch <- descAppLabels
}
ch <- descAppInfo
ch <- descAppSyncStatusCode
ch <- descAppHealthStatus
@@ -305,7 +337,7 @@ func (c *appCollector) Collect(ch chan<- prometheus.Metric) {
}
for _, app := range apps {
if c.appFilter(app) {
collectApps(ch, app)
c.collectApps(ch, app)
}
}
}
@@ -317,7 +349,7 @@ func boolFloat64(b bool) float64 {
return 0
}
func collectApps(ch chan<- prometheus.Metric, app *argoappv1.Application) {
func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.Application) {
addConstMetric := func(desc *prometheus.Desc, t prometheus.ValueType, v float64, lv ...string) {
project := app.Spec.GetProject()
lv = append([]string{app.Namespace, app.Name, project}, lv...)
@@ -344,6 +376,15 @@ func collectApps(ch chan<- prometheus.Metric, app *argoappv1.Application) {
addGauge(descAppInfo, 1, git.NormalizeGitURL(app.Spec.Source.RepoURL), app.Spec.Destination.Server, app.Spec.Destination.Namespace, string(syncStatus), string(healthStatus), operation)
if len(c.appLabels) > 0 {
labelValues := []string{}
for _, desiredLabel := range c.appLabels {
value := app.GetLabels()[desiredLabel]
labelValues = append(labelValues, value)
}
addGauge(descAppLabels, 1, labelValues...)
}
// Deprecated controller metrics
if os.Getenv(EnvVarLegacyControllerMetrics) == "true" {
addGauge(descAppCreated, float64(app.CreationTimestamp.Unix()))

View File

@@ -10,6 +10,7 @@ import (
"testing"
"time"
gitopsCache "github.com/argoproj/gitops-engine/pkg/cache"
"github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"
@@ -29,6 +30,9 @@ kind: Application
metadata:
name: my-app
namespace: argocd
labels:
team-name: my-team
team-bu: bu-id
spec:
destination:
namespace: dummy-namespace
@@ -50,6 +54,9 @@ kind: Application
metadata:
name: my-app-2
namespace: argocd
labels:
team-name: my-team
team-bu: bu-id
spec:
destination:
namespace: dummy-namespace
@@ -77,6 +84,9 @@ metadata:
name: my-app-3
namespace: argocd
deletionTimestamp: "2020-03-16T09:17:45Z"
labels:
team-name: my-team
team-bu: bu-id
spec:
destination:
namespace: dummy-namespace
@@ -138,7 +148,7 @@ func newFakeLister(fakeAppYAMLs ...string) (context.CancelFunc, applister.Applic
fakeApps = append(fakeApps, a)
}
appClientset := appclientset.NewSimpleClientset(fakeApps...)
factory := appinformer.NewFilteredSharedInformerFactory(appClientset, 0, "argocd", func(options *metav1.ListOptions) {})
factory := appinformer.NewSharedInformerFactoryWithOptions(appClientset, 0, appinformer.WithNamespace("argocd"), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {}))
appInformer := factory.Argoproj().V1alpha1().Applications().Informer()
go appInformer.Run(ctx.Done())
if !cache.WaitForCacheSync(ctx.Done(), appInformer.HasSynced) {
@@ -148,30 +158,71 @@ func newFakeLister(fakeAppYAMLs ...string) (context.CancelFunc, applister.Applic
}
func testApp(t *testing.T, fakeAppYAMLs []string, expectedResponse string) {
cancel, appLister := newFakeLister(fakeAppYAMLs...)
t.Helper()
testMetricServer(t, fakeAppYAMLs, expectedResponse, []string{})
}
type fakeClusterInfo struct {
clustersInfo []gitopsCache.ClusterInfo
}
func (f *fakeClusterInfo) GetClustersInfo() []gitopsCache.ClusterInfo {
return f.clustersInfo
}
type TestMetricServerConfig struct {
FakeAppYAMLs []string
ExpectedResponse string
AppLabels []string
ClustersInfo []gitopsCache.ClusterInfo
}
func testMetricServer(t *testing.T, fakeAppYAMLs []string, expectedResponse string, appLabels []string) {
t.Helper()
cfg := TestMetricServerConfig{
FakeAppYAMLs: fakeAppYAMLs,
ExpectedResponse: expectedResponse,
AppLabels: appLabels,
ClustersInfo: []gitopsCache.ClusterInfo{},
}
runTest(t, cfg)
}
func runTest(t *testing.T, cfg TestMetricServerConfig) {
t.Helper()
cancel, appLister := newFakeLister(cfg.FakeAppYAMLs...)
defer cancel()
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck)
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, cfg.AppLabels)
assert.NoError(t, err)
if len(cfg.ClustersInfo) > 0 {
ci := &fakeClusterInfo{clustersInfo: cfg.ClustersInfo}
collector := &clusterCollector{
infoSource: ci,
info: ci.GetClustersInfo(),
}
metricsServ.registry.MustRegister(collector)
}
req, err := http.NewRequest("GET", "/metrics", nil)
assert.NoError(t, err)
rr := httptest.NewRecorder()
metricsServ.Handler.ServeHTTP(rr, req)
assert.Equal(t, rr.Code, http.StatusOK)
body := rr.Body.String()
log.Println(body)
assertMetricsPrinted(t, expectedResponse, body)
assertMetricsPrinted(t, cfg.ExpectedResponse, body)
}
type testCombination struct {
applications []string
expectedResponse string
responseContains string
}
func TestMetrics(t *testing.T) {
combinations := []testCombination{
{
applications: []string{fakeApp, fakeApp2, fakeApp3},
expectedResponse: `
responseContains: `
# HELP argocd_app_info Information about application.
# TYPE argocd_app_info gauge
argocd_app_info{dest_namespace="dummy-namespace",dest_server="https://localhost:6443",health_status="Degraded",name="my-app-3",namespace="argocd",operation="delete",project="important-project",repo="https://github.com/argoproj/argocd-example-apps",sync_status="OutOfSync"} 1
@@ -181,7 +232,7 @@ argocd_app_info{dest_namespace="dummy-namespace",dest_server="https://localhost:
},
{
applications: []string{fakeDefaultApp},
expectedResponse: `
responseContains: `
# HELP argocd_app_info Information about application.
# TYPE argocd_app_info gauge
argocd_app_info{dest_namespace="dummy-namespace",dest_server="https://localhost:6443",health_status="Healthy",name="my-app",namespace="argocd",operation="",project="default",repo="https://github.com/argoproj/argocd-example-apps",sync_status="Synced"} 1
@@ -190,7 +241,50 @@ argocd_app_info{dest_namespace="dummy-namespace",dest_server="https://localhost:
}
for _, combination := range combinations {
testApp(t, combination.applications, combination.expectedResponse)
testApp(t, combination.applications, combination.responseContains)
}
}
func TestMetricLabels(t *testing.T) {
type testCases struct {
testCombination
description string
metricLabels []string
}
cases := []testCases{
{
description: "will return the labels metrics successfully",
metricLabels: []string{"team-name", "team-bu"},
testCombination: testCombination{
applications: []string{fakeApp, fakeApp2, fakeApp3},
responseContains: `
# TYPE argocd_app_labels gauge
argocd_app_labels{label_team_bu="bu-id",label_team_name="my-team",name="my-app",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_team_bu="bu-id",label_team_name="my-team",name="my-app-2",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_team_bu="bu-id",label_team_name="my-team",name="my-app-3",namespace="argocd",project="important-project"} 1
`,
},
},
{
description: "metric will have empty label value if not present in the application",
metricLabels: []string{"non-existing"},
testCombination: testCombination{
applications: []string{fakeApp, fakeApp2, fakeApp3},
responseContains: `
# TYPE argocd_app_labels gauge
argocd_app_labels{label_non_existing="",name="my-app",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_non_existing="",name="my-app-2",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_non_existing="",name="my-app-3",namespace="argocd",project="important-project"} 1
`,
},
},
}
for _, c := range cases {
c := c
t.Run(c.description, func(t *testing.T) {
testMetricServer(t, c.applications, c.responseContains, c.metricLabels)
})
}
}
@@ -222,7 +316,7 @@ argocd_app_sync_status{name="my-app",namespace="argocd",project="important-proje
func TestMetricsSyncCounter(t *testing.T) {
cancel, appLister := newFakeLister()
defer cancel()
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck)
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{})
assert.NoError(t, err)
appSyncTotal := `
@@ -252,11 +346,12 @@ argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespa
// assertMetricsPrinted asserts every line in the expected lines appears in the body
func assertMetricsPrinted(t *testing.T, expectedLines, body string) {
t.Helper()
for _, line := range strings.Split(expectedLines, "\n") {
if line == "" {
continue
}
assert.Contains(t, body, line)
assert.Contains(t, body, line, "expected metrics mismatch")
}
}
@@ -273,7 +368,7 @@ func assertMetricsNotPrinted(t *testing.T, expectedLines, body string) {
func TestReconcileMetrics(t *testing.T) {
cancel, appLister := newFakeLister()
defer cancel()
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck)
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{})
assert.NoError(t, err)
appReconcileMetrics := `
@@ -306,7 +401,7 @@ argocd_app_reconcile_count{dest_server="https://localhost:6443",namespace="argoc
func TestMetricsReset(t *testing.T) {
cancel, appLister := newFakeLister()
defer cancel()
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck)
metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{})
assert.NoError(t, err)
appSyncTotal := `

View File

@@ -64,6 +64,7 @@ type AppStateManager interface {
SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState)
}
// comparisonResult holds the state of an application after the reconciliation
type comparisonResult struct {
syncStatus *v1alpha1.SyncStatus
healthStatus *v1alpha1.HealthStatus
@@ -98,6 +99,7 @@ type appStateManager struct {
cache *appstatecache.Cache
namespace string
statusRefreshTimeout time.Duration
resourceTracking argo.ResourceTracking
}
func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1.ApplicationSource, appLabelKey, revision string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, *apiclient.ManifestResponse, error) {
@@ -148,6 +150,7 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1
if err != nil {
return nil, nil, err
}
kustomizeOptions, err := kustomizeSettings.GetOptions(app.Spec.Source)
if err != nil {
return nil, nil, err
@@ -158,7 +161,7 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1
return nil, nil, err
}
ts.AddCheckpoint("build_options_ms")
serverVersion, apiGroups, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server)
serverVersion, apiResources, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server)
if err != nil {
return nil, nil, err
}
@@ -176,9 +179,10 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1
Plugins: tools,
KustomizeOptions: kustomizeOptions,
KubeVersion: serverVersion,
ApiVersions: argo.APIGroupsToVersions(apiGroups),
ApiVersions: argo.APIResourcesToStrings(apiResources, true),
VerifySignature: verifySignature,
HelmRepoCreds: permittedHelmCredentials,
TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)),
HelmOptions: helmOptions,
})
if err != nil {
@@ -461,14 +465,16 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
// filter out all resources which are not permitted in the application project
for k, v := range liveObjByKey {
if !project.IsLiveResourcePermitted(v, app.Spec.Destination.Server) {
if !project.IsLiveResourcePermitted(v, app.Spec.Destination.Server, app.Spec.Destination.Name) {
delete(liveObjByKey, k)
}
}
trackingMethod := argo.GetTrackingMethod(m.settingsMgr)
for _, liveObj := range liveObjByKey {
if liveObj != nil {
appInstanceName := kubeutil.GetAppInstanceLabel(liveObj, appLabelKey)
appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, trackingMethod)
if appInstanceName != "" && appInstanceName != app.Name {
conditions = append(conditions, v1alpha1.ApplicationCondition{
Type: v1alpha1.ApplicationConditionSharedResourceWarning,
@@ -503,6 +509,10 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
_, refreshRequested := app.IsRefreshRequested()
noCache = noCache || refreshRequested || app.Status.Expired(m.statusRefreshTimeout)
for i := range reconciliation.Target {
_ = m.resourceTracking.Normalize(reconciliation.Target[i], reconciliation.Live[i], appLabelKey, string(trackingMethod))
}
if noCache || specChanged || revisionChanged || m.cache.GetAppManagedResources(app.Name, &cachedDiff) != nil {
// (rare) cache miss
diffResults, err = diff.DiffArray(reconciliation.Target, reconciliation.Live, diffOpts...)
@@ -687,6 +697,7 @@ func NewAppStateManager(
metricsServer *metrics.MetricsServer,
cache *appstatecache.Cache,
statusRefreshTimeout time.Duration,
resourceTracking argo.ResourceTracking,
) AppStateManager {
return &appStateManager{
liveStateCache: liveStateCache,
@@ -700,5 +711,6 @@ func NewAppStateManager(
projInformer: projInformer,
metricsServer: metricsServer,
statusRefreshTimeout: statusRefreshTimeout,
resourceTracking: resourceTracking,
}
}

View File

@@ -60,6 +60,16 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
return
}
syncOp = *state.Operation.Sync
// validates if it should fail the sync if it finds shared resources
hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app)
if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") &&
hasSharedResource {
state.Phase = common.OperationFailed
state.Message = fmt.Sprintf("Shared resouce found: %s", sharedResourceMessage)
return
}
if syncOp.Source == nil {
// normal sync case (where source is taken from app.spec.source)
source = app.Spec.Source
@@ -87,7 +97,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
revision = syncOp.Revision
}
proj, err := argo.GetAppProject(&app.Spec, listersv1alpha1.NewAppProjectLister(m.projInformer.GetIndexer()), m.namespace, m.settingsMgr)
proj, err := argo.GetAppProject(&app.Spec, listersv1alpha1.NewAppProjectLister(m.projInformer.GetIndexer()), m.namespace, m.settingsMgr, m.db, context.TODO())
if err != nil {
state.Phase = common.OperationError
state.Message = fmt.Sprintf("Failed to load application project: %v", err)
@@ -127,7 +137,13 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
}
atomic.AddUint64(&syncIdPrefix, 1)
syncId := fmt.Sprintf("%05d-%s", syncIdPrefix, rand.RandString(5))
randSuffix, err := rand.String(5)
if err != nil {
state.Phase = common.OperationError
state.Message = fmt.Sprintf("Failed generate random sync ID: %v", err)
return
}
syncId := fmt.Sprintf("%05d-%s", syncIdPrefix, randSuffix)
logEntry := log.WithFields(log.Fields{"application": app.Name, "syncId": syncId})
initialResourcesRes := make([]common.ResourceSyncResult, 0)
@@ -176,7 +192,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
if !proj.IsGroupKindPermitted(un.GroupVersionKind().GroupKind(), res.Namespaced) {
return fmt.Errorf("Resource %s:%s is not permitted in project %s.", un.GroupVersionKind().Group, un.GroupVersionKind().Kind, proj.Name)
}
if res.Namespaced && !proj.IsDestinationPermitted(v1alpha1.ApplicationDestination{Namespace: un.GetNamespace(), Server: app.Spec.Destination.Server}) {
if res.Namespaced && !proj.IsDestinationPermitted(v1alpha1.ApplicationDestination{Namespace: un.GetNamespace(), Server: app.Spec.Destination.Server, Name: app.Spec.Destination.Name}) {
return fmt.Errorf("namespace %v is not permitted in project '%s'", un.GetNamespace(), proj.Name)
}
return nil
@@ -245,6 +261,18 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
}
}
// hasSharedResourceCondition will check if the Application has any resource that has already
// been synced by another Application. If the resource is found in another Application it returns
// true along with a human readable message of which specific resource has this condition.
func hasSharedResourceCondition(app *v1alpha1.Application) (bool, string) {
for _, condition := range app.Status.Conditions {
if condition.Type == v1alpha1.ApplicationConditionSharedResourceWarning {
return true, condition.Message
}
}
return false, ""
}
// delayBetweenSyncWaves is a gitops-engine SyncWaveHook which introduces an artificial delay
// between each sync wave. We introduce an artificial delay in order give other controllers a
// _chance_ to react to the spec change that we just applied. This is important because without

View File

@@ -5,6 +5,7 @@ import (
"os"
"testing"
"github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/stretchr/testify/assert"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -142,3 +143,71 @@ func TestSyncComparisonError(t *testing.T) {
assert.NotEmpty(t, conditions)
assert.Equal(t, "abc123", opState.SyncResult.Revision)
}
func TestAppStateManager_SyncAppState(t *testing.T) {
type fixture struct {
project *v1alpha1.AppProject
application *v1alpha1.Application
controller *ApplicationController
}
setup := func() *fixture {
app := newFakeApp()
app.Status.OperationState = nil
app.Status.History = nil
project := &v1alpha1.AppProject{
ObjectMeta: v1.ObjectMeta{
Namespace: test.FakeArgoCDNamespace,
Name: "default",
},
Spec: v1alpha1.AppProjectSpec{
SignatureKeys: []v1alpha1.SignatureKey{{KeyID: "test"}},
},
}
data := fakeData{
apps: []runtime.Object{app, project},
manifestResponse: &apiclient.ManifestResponse{
Manifests: []string{},
Namespace: test.FakeDestNamespace,
Server: test.FakeClusterURL,
Revision: "abc123",
},
managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured),
}
ctrl := newFakeController(&data)
return &fixture{
project: project,
application: app,
controller: ctrl,
}
}
t.Run("will fail the sync if finds shared resources", func(t *testing.T) {
// given
t.Parallel()
f := setup()
syncErrorMsg := "deployment already applied by another application"
condition := v1alpha1.ApplicationCondition{
Type: v1alpha1.ApplicationConditionSharedResourceWarning,
Message: syncErrorMsg,
}
f.application.Status.Conditions = append(f.application.Status.Conditions, condition)
// Sync with source unspecified
opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{
Sync: &v1alpha1.SyncOperation{
Source: &v1alpha1.ApplicationSource{},
SyncOptions: []string{"FailOnSharedResource=true"},
},
}}
// when
f.controller.appStateManager.SyncAppState(f.application, opState)
// then
assert.Equal(t, common.OperationFailed, opState.Phase)
assert.Contains(t, opState.Message, syncErrorMsg)
})
}

0
docs/assets/azure-enterprise-claims.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

0
docs/assets/azure-enterprise-saml-urls.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

0
docs/assets/azure-enterprise-users.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/assets/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -15,7 +15,7 @@ Since the CI pipeline is triggered on Git commits, there is currently no (known)
If you are absolutely sure that the failure was due to a failure in the pipeline, and not an error within the changes you committed, you can push an empty commit to your branch, thus retriggering the pipeline without any code changes. To do so, issue
```bash
git commit --allow-empty -m "Retrigger CI pipeline"
git commit -s --allow-empty -m "Retrigger CI pipeline"
git push origin <yourbranch>
```
@@ -23,7 +23,9 @@ git push origin <yourbranch>
First, make sure the failing build step succeeds on your machine. Remember the containerized build toolchain is available, too.
If the build is failing at the `Ensuring Gopkg.lock is up-to-date` step, you need to update the dependencies before you push your commits. Run `make dep-ensure` and `make dep` and commit the changes to `Gopkg.lock` to your branch.
If the build is failing at the `Ensure Go modules synchronicity` step, you need to first download all Go dependent modules locally via `go mod download` and then run `go mod tidy` to make sure the dependent Go modules are tidied up. Finally commit and push your changes to `go.mod` and `go.sum` to your branch.
If the build is failing at the `Build & cache Go code`, you need to make sure `make build-local` runs successfully on your local machine.
### Why does the codegen step fail?

View File

@@ -45,7 +45,7 @@ If you make changes to the Argo UI component, and your Argo CD changes depend on
1. Make changes to Argo UI and submit the PR request.
2. Also, prepare your Argo CD changes, but don't create the PR just yet.
3. **After** the Argo UI PR has been merged to master, then as part of your Argo CD changes:
- Run `yarn add git+https://github.com/argoproj/argo-ui.git`, and then,
- Run `yarn add git+https://github.com/argoproj/argo-ui.git` in the `ui/` directory, and then,
- Check in the regenerated yarn.lock file as part of your Argo CD commit
4. Create the Argo CD PR when you are ready. The PR build and test checks should pass.

View File

@@ -24,8 +24,7 @@ You will need at least the following things in your toolchain in order to develo
* A Kubernetes cluster. You won't need a fully blown multi-master, multi-node cluster, but you will need something like K3S, Minikube or microk8s. You will also need a working Kubernetes client (`kubectl`) configuration in your development environment. The configuration must reside in `~/.kube/config` and the API server URL must point to the IP address of your local machine (or VM), and **not** to `localhost` or `127.0.0.1` if you are using the virtualized development toolchain (see below)
* You will also need a working Docker runtime environment, to be able to build and run images.
The Docker version must be fairly recent, and support multi-stage builds. You should not work as root. Make your local user a member of the `docker` group to be able to control the Docker service on your machine.
* You will also need a working Docker runtime environment, to be able to build and run images. The Docker version must be 17.05.0 or higher, to support multi-stage builds.
* Obviously, you will need a `git` client for pulling source code and pushing back your changes.
@@ -269,7 +268,7 @@ and others. Although you can make changes to these files and run them locally, i
6. Commit changes and open a PR to [Argo UI](https://github.com/argoproj/argo-ui).
7. Once your PR has been merged in Argo UI, `cd` into your `argo-cd` folder and run `yarn add https://github.com/argoproj/argo-ui.git`. This will update the commit SHA in the `ui/yarn.lock` file to use the lastest master commit for argo-ui.
7. Once your PR has been merged in Argo UI, `cd` into your `argo-cd/ui` folder and run `yarn add git+https://github.com/argoproj/argo-ui.git`. This will update the commit SHA in the `ui/yarn.lock` file to use the lastest master commit for argo-ui.
8. Submit changes to `ui/yarn.lock`in a PR to Argo CD.
@@ -304,7 +303,7 @@ You need to pull in all required Go dependencies. To do so, run
### Test your build toolchain
The first thing you can do whether your build toolchain is setup correctly is by generating the glue code for the API and after that, run a normal build:
The first thing you can do to test whether your build toolchain is setup correctly is by generating the glue code for the API and after that, run a normal build:
* `make codegen-local`
* `make build-local`

View File

@@ -73,13 +73,9 @@ in your Argo CD installation namespace. You can simply retrieve this password
using `kubectl`:
```bash
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
```
For better readability, e.g. if you want to copy & paste the generated password,
you can simply append `&& echo` to above command, which will add a newline to
the output.
!!! warning
You should delete the `argocd-initial-admin-secret` from the Argo CD
namespace once you changed the password. The secret serves no other
@@ -93,6 +89,9 @@ Using the username `admin` and the password from above, login to Argo CD's IP or
argocd login <ARGOCD_SERVER>
```
!!! note
The CLI environment must be able to communicate with the Argo CD controller. If it isn't directly accessible as described above in step 3, you can tell the CLI to access it using port forwarding through one of these mechanisms: 1) add `--port-forward-namespace argocd` flag to every CLI command; or 2) set `ARGOCD_OPTS` environment variable: `export ARGOCD_OPTS='--port-forward-namespace argocd'`.
Change the password using the command:
```bash
@@ -131,10 +130,11 @@ An example repository containing a guestbook application is available at
### Creating Apps Via CLI
!!! note
You can access Argo CD using port forwarding: add `--port-forward-namespace argocd` flag to every CLI command or set `ARGOCD_OPTS` environment variable: `export ARGOCD_OPTS='--port-forward-namespace argocd'`:
Create the example guestbook application with the following command:
`argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default`
```bash
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default`
```
### Creating Apps Via UI
@@ -152,7 +152,7 @@ Connect the [https://github.com/argoproj/argocd-example-apps.git](https://github
![connect repo](assets/connect-repo.png)
For **Destination**, set cluster to `in-cluster` and namespace to `default`:
For **Destination**, set cluster URL to `https://kubernetes.default.svc` (or `in-cluster` for cluster name) and namespace to `default`:
![destination](assets/destination.png)

View File

@@ -82,6 +82,14 @@ spec:
- code: false
name: foo
value: bar
# Exclude contains a glob pattern to match paths against that should be explicitly excluded from being used during
# manifest generation. This takes precedence over the `include` field.
# To match multiple patterns, wrap the patterns in {} and separate them with commas. For example: '{config.yaml,env-use2/*}'
exclude: 'config.yaml'
# Include contains a glob pattern to match paths against that should be explicitly included during manifest
# generation. If this field is set, only matching manifests will be included.
# To match multiple patterns, wrap the patterns in {} and separate them with commas. For example: '{*.yml,*.yaml}'
include: '*.yaml'
# plugin specific config
plugin:

View File

@@ -228,8 +228,23 @@ data:
# Optional link for banner. If set, the entire banner text will become a link.
# You can have bannercontent without a bannerurl, but not the other way around.
ui.bannerurl: "https://argoproj.github.io"
# Uncomment to make the banner not show the close buttons, thereby making the banner permanent.
# Because it is permanent, only one line of text is available to not take up too much real estate in the UI,
# so it is recommended that the length of the bannercontent text is kept reasonably short. Note that you can
# have either a permanent banner or a regular closeable banner, and NOT both. eg. A user can't dismiss a
# notification message (closeable) banner, to then immediately see a permanent banner.
# ui.bannerpermanent: "true"
# An option to specify the position of the banner, either the top or bottom of the page. The default is at the top.
# Uncomment to make the banner appear at the bottom of the page. Any value other than "bottom" will make the banner appear at the top.
# ui.bannerposition: "bottom"
# Application reconciliation timeout is the max amount of time required to discover if a new manifests version got
# published to the repository. Reconciliation by timeout is disabled if timeout is set to 0. Three minutes by default.
# > Note: argocd-repo-server deployment must be manually restarted after changing the setting.
timeout.reconciliation: 180s
# oidc.tls.insecure.skip.verify determines whether certificate verification is skipped when verifying tokens with the
# configured OIDC provider (either external or the bundled Dex instance). Setting this to "true" will cause JWT
# token verification to pass despite the OIDC provider having an invalid certificate. Only set to "true" if you
# understand the risks.
oidc.tls.insecure.skip.verify: "false"

View File

@@ -103,4 +103,8 @@ data:
reposerver.repo.cache.expiration: "24h0m0s"
# Cache expiration default (default 24h0m0s)
reposerver.default.cache.expiration: "24h0m0s"
# Max combined manifest file size for a single directory-type Application. In-memory manifest representation may be as
# much as 300x the manifest file size. Limit this to stay within the memory limits of the repo-server while allowing
# for 300x memory expansion and N Applications running at the same time.
# (example 10M max * 300 expansion * 10 Apps = 30G max theoretical memory usage).
reposerver.max.combined.directory.manifests.size: '10M'

View File

@@ -28,3 +28,8 @@ data:
# If omitted, defaults to: '[groups]'. The scope value can be a string, or a list of strings.
scopes: '[cognito:groups, email]'
# matchMode configures the matchers function for casbin.
# There are two options for this, 'glob' for glob matcher or 'regex' for regex matcher. If omitted or mis-configured,
# will be set to 'glob' as default.
policy.matchMode: 'glob'

View File

@@ -96,4 +96,23 @@ Note that the CSS file should be mounted within a subdirectory of the "/shared/a
## Developing Style Overlays
The styles specified in the injected CSS file should be specific to components and classes defined in [argo-ui](https://github.com/argoproj/argo-ui).
It is recommended to test out the styles you wish to apply first by making use of your browser's built-in developer tools. For a more full-featured
experience, you may wish to build a separate project using the [Argo CD UI dev server](https://webpack.js.org/configuration/dev-server/).
experience, you may wish to build a separate project using the [Argo CD UI dev server](https://webpack.js.org/configuration/dev-server/).
## Banners
Argo CD can optionally display a banner that can be used to notify your users of upcoming maintenance and operational changes. This feature can be enabled by specifying the banner message using the `ui.bannercontent` field in the `argocd-cm` ConfigMap and Argo CD will display this message at the top of every UI page. You can optionally add a link to this message by setting `ui.bannerurl`.
### argocd-cm
```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
...
name: argocd-cm
data:
ui.bannercontent: "Banner message linked to a URL"
ui.bannerurl: "www.bannerlink.com"
```
![banner with link](../assets/banner.png)

View File

@@ -171,6 +171,9 @@ Repository details are stored in secrets. To configure a repo, create a secret w
Consider using [bitnami-labs/sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) to store an encrypted secret definition as a Kubernetes manifest.
Each repository must have a `url` field and, depending on whether you connect using HTTPS, SSH, or GitHub App, `username` and `password` (for HTTPS), `sshPrivateKey` (for SSH), or `githubAppPrivateKey` (for GitHub App).
!!!warning
When using [bitnami-labs/sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) the labels will be removed and have to be readded as descibed here: https://github.com/bitnami-labs/sealed-secrets#sealedsecrets-as-templates-for-secrets
Example for HTTPS:
```yaml
@@ -182,6 +185,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/private-repo
password: my-password
username: my-username
@@ -198,6 +202,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: git@github.com:argoproj/my-private-repository
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
@@ -215,6 +220,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
repo: https://github.com/argoproj/my-private-repository
githubAppID: 1
githubAppInstallationID: 2
@@ -231,6 +237,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
repo: https://ghe.example.com/argoproj/my-private-repository
githubAppID: 1
githubAppInstallationID: 2
@@ -257,6 +264,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/private-repo
---
apiVersion: v1
@@ -267,6 +275,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/other-private-repo
---
apiVersion: v1
@@ -277,6 +286,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
type: git
url: https://github.com/argoproj
password: my-password
username: my-username
@@ -418,6 +428,7 @@ metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/argoproj/private-repo
proxy: https://proxy-server-url:8888
password: my-password
@@ -471,6 +482,7 @@ The secret data must include following fields:
* `name` - cluster name
* `server` - cluster api server url
* `namespaces` - optional comma-separated list of namespaces which are accessible in that cluster. Cluster level resources would be ignored if namespace list is not empty.
* `clusterResources` - optional boolean string (`"true"` or `"false"`) determining whether Argo CD can manage cluster-level resources on this cluster. This setting is used only if the list of managed namespaces is not empty.
* `config` - JSON representation of following data structure:
```yaml
@@ -497,13 +509,13 @@ execProviderConfig:
installHint: string
# Transport layer security configuration settings
tlsClientConfig:
# PEM-encoded bytes (typically read from a client certificate file).
# Base64 encoded PEM-encoded bytes (typically read from a client certificate file).
caData: string
# PEM-encoded bytes (typically read from a client certificate file).
# Base64 encoded PEM-encoded bytes (typically read from a client certificate file).
certData: string
# Server should be accessed without verifying the TLS certificate
insecure: boolean
# PEM-encoded bytes (typically read from a client certificate key file).
# Base64 encoded PEM-encoded bytes (typically read from a client certificate key file).
keyData: string
# ServerName is passed to the server for SNI and is used in the client to check server
# certificates against. If ServerName is empty, the hostname used to contact the

View File

@@ -38,7 +38,7 @@ and might fail. To avoid failed syncs use `ARGOCD_GIT_ATTEMPTS_COUNT` environmen
* `argocd_git_request_total` - Number of git requests. The metric provides two tags: `repo` - Git repo URL; `request_type` - `ls-remote` or `fetch`.
* `ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM` (v1.8+) - environment variable that enables collecting RPC performance metrics. Enable it if you need to troubleshoot performance issue. Note: metric is expensive to both query and store!
* `ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM` - environment variable that enables collecting RPC performance metrics. Enable it if you need to troubleshoot performance issue. Note: metric is expensive to both query and store!
### argocd-application-controller
@@ -61,7 +61,7 @@ number of allowed concurrent kubectl fork/execs.
* The controller uses Kubernetes watch APIs to maintain lightweight Kubernetes cluster cache. This allows to avoid querying Kubernetes during app reconciliation and significantly improve
performance. For performance reasons controller monitors and caches only preferred the version of a resource. During reconciliation, the controller might have to convert cached resource from
preferred version into a version of the resource stored in Git. If `kubectl convert` fails because conversion is not supported then controller falls back to Kubernetes API query which slows down
reconciliation. In this case advice user-preferred resource version in Git.
reconciliation. In this case, we advise you to use the preferred resource version in Git.
* The controller polls Git every 3m by default. You can increase this duration using `timeout.reconciliation` setting in the `argocd-cm` ConfigMap.
@@ -86,7 +86,7 @@ spec:
value: "2"
```
* `ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM` (v1.8+)- environment variable that enables collecting RPC performance metrics. Enable it if you need to troubleshoot performance issue. Note: metric is expensive to both query and store!
* `ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM` - environment variable that enables collecting RPC performance metrics. Enable it if you need to troubleshoot performance issue. Note: metric is expensive to both query and store!
**metrics**
@@ -119,26 +119,24 @@ If the manifest generation has no side effects then requests are processed in pa
* **Multiple Helm based applications pointing to the same directory in one Git repository:** ensure that your Helm chart don't have conditional
[dependencies](https://helm.sh/docs/chart_best_practices/dependencies/#conditions-and-tags) and create `.argocd-allow-concurrency` file in chart directory.
* **Multiple Custom plugin based applications:** avoid creating temporal files during manifest generation and and create `.argocd-allow-concurrency` file in app directory.
* **Multiple Custom plugin based applications:** avoid creating temporal files during manifest generation and create `.argocd-allow-concurrency` file in app directory.
* **Multiple Kustomize or Ksonnet applications in same repository with [parameter overrides](../user-guide/parameters.md):** sorry, no workaround for now.
### Webhook and Manifest Paths Annotation
Argo CD aggressively caches generated manifests and uses repository commit SHA as a cache key. A new commit to the Git repository invalidates cache for all applications configured in the repository
that again negatively affect mono repositories with multiple applications. You might use [webhooks](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/webhook.md) and `argocd.argoproj.io/manifest-generate-paths` Application
CRD annotation to solve this problem and improve performance.
Argo CD aggressively caches generated manifests and uses the repository commit SHA as a cache key. A new commit to the Git repository invalidates the cache for all applications configured in the repository.
This can negatively affect repositories with multiple applications. You can use [webhooks](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/webhook.md) and the `argocd.argoproj.io/manifest-generate-paths` Application CRD annotation to solve this problem and improve performance.
The `argocd.argoproj.io/manifest-generate-paths` contains a semicolon-separated list of paths within the Git repository that are used during manifest generation. The webhook compares paths specified in the annotation
with the changed files specified in the webhook payload. If non of the changed files are located in the paths then webhook don't trigger application reconciliation and re-uses previously generated manifests cache for a new commit.
The `argocd.argoproj.io/manifest-generate-paths` annotation contains a semicolon-separated list of paths within the Git repository that are used during manifest generation. The webhook compares paths specified in the annotation with the changed files specified in the webhook payload. If no modified files match the paths specified in `argocd.argoproj.io/manifest-generate-paths`, then the webhook will not trigger application reconciliation and the existing cache will be considered valid for the new commit.
Installations that use a different repo for each app are **not** subject to this behavior and will likely get no benefit from using these annotations.
Installations that use a different repository for each application are **not** subject to this behavior and will likely get no benefit from using these annotations.
!!! note
Application manifest paths annotation support depends on the git provider used for the Application. It is currently only supported for GitHub, GitLab, and Gogs based repos
I'm using `.Second()` modifier to avoid distracting users who already rely on `--app-resync` flag.
* **Relative path** The annotation might contains relative path. In this case the path is considered relative to the path specified in the application source:
Application manifest paths annotation support depends on the git provider used for the Application. It is currently only supported for GitHub, GitLab, and Gogs based repos.
* **Relative path** The annotation might contain a relative path. In this case the path is considered relative to the path specified in the application source:
```yaml
apiVersion: argoproj.io/v1alpha1
@@ -156,7 +154,8 @@ spec:
path: guestbook
# ...
```
* **Absolute path** The annotation value might be an absolute path started from '/'. In this case path is considered as an absolute path within the Git repository:
* **Absolute path** The annotation value might be an absolute path starting with '/'. In this case path is considered as an absolute path within the Git repository:
```yaml
apiVersion: argoproj.io/v1alpha1

View File

@@ -79,7 +79,7 @@ Since Contour Ingress supports only a single protocol per Ingress object, define
Internal HTTP/HTTPS Ingress:
```yaml
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-http
@@ -102,7 +102,7 @@ spec:
Internal gRPC Ingress:
```yaml
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-grpc
@@ -124,7 +124,7 @@ spec:
External HTTPS SSO Callback Ingress:
```yaml
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-external-callback-http
@@ -178,7 +178,7 @@ In order to expose the Argo CD API server with a single ingress rule and hostnam
must be used to passthrough TLS connections and terminate TLS at the Argo CD API server.
```yaml
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
@@ -244,7 +244,7 @@ way would be to define two Ingress objects. One for HTTP/HTTPS, and the other fo
HTTP/HTTPS Ingress:
```yaml
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-http-ingress
@@ -269,7 +269,7 @@ spec:
gRPC Ingress:
```yaml
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-grpc-ingress
@@ -379,7 +379,7 @@ spec:
Once we create this service, we can configure the Ingress to conditionally route all `application/grpc` traffic to the new HTTP2 backend, using the `alb.ingress.kubernetes.io/conditions` annotation, as seen below. Note: The value after the . in the condition annotation _must_ be the same name as the service that you want traffic to route to - and will be applied on any path with a matching serviceName.
```yaml
apiVersion: networking.k8s.io/v1 # Use extensions/v1beta1 for Kubernetes 1.18 and older
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
@@ -408,6 +408,162 @@ Once we create this service, we can configure the Ingress to conditionally route
- argocd.argoproj.io
```
## Google Cloud load balancers with Kubernetes Ingress
You can make use of the integration of GKE with Google Cloud to deploy Load Balancers using just Kubernetes objects.
For this we will need these five objects:
- A Service
- A BackendConfig
- A FrontendConfig
- A secret with your SSL certificate
- An Ingress for GKE
If you need detail for all the options available for these Google integrations, you can check the [Google docs on configuring Ingress features](https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features)
### Disable internal TLS
First, to avoid internal redirection loops from HTTP to HTTPS, the API server should be run with TLS disabled. Edit the argocd-server deployment to add the --insecure flag to the argocd-server command. For this you can edit your resource live with `kubectl -n argocd edit deployments.apps argocd-server` or use a kustomize patch before installing Argo CD.
The container command should change from:
```yaml
containers:
- command:
- argocd-server
- --staticassets
- /shared/app
```
To:
```yaml
containers:
- command:
- argocd-server
- --insecure
- --staticassets
- /shared/app
```
### Creating a service
Now you need an externally accesible service. This is practically the same as the internal service Argo CD has, but as a NodePort and with Google Cloud annotations. Note that this service is annotated to use a [Network Endpoint Group](https://cloud.google.com/load-balancing/docs/negs) (NEG) to allow your load balancer to send traffic directly to your pods without using kube-proxy, so remove the `neg` annotation it that's not what you want.
The service:
```yaml
apiVersion: v1
kind: Service
metadata:
name: argocd-server-external
namespace: argocd
annotations:
cloud.google.com/neg: '{"ingress": true}'
cloud.google.com/backend-config: '{"ports": {"http":"argocd-backend-config"}}'
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app.kubernetes.io/name: argocd-server
```
### Creating a BackendConfig
See that previous service referencing a backend config called `argo-backend-config`? So lets deploy it using this yaml:
```yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: argocd-backend-config
namespace: argocd
spec:
healthCheck:
checkIntervalSec: 30
timeoutSec: 5
healthyThreshold: 1
unhealthyThreshold: 2
type: HTTP
requestPath: /healthz
port: 8080
```
It uses the same health check as the pods.
### Creating a FrontendConfig
Now we can deploy a frontend config with an HTTP to HTTPS redirect:
```yaml
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: argocd-frontend-config
namespace: argocd
spec:
redirectToHttps:
enabled: true
```
---
!!! note
The next two steps (the certificate secret and the Ingress) are described supposing that you manage the certificate yourself, and you have the certificate and key files for it. In the case that your certificate is Google-managed, fix the next two steps using the [guide to use a Google-managed SSL certificate](https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs#creating_an_ingress_with_a_google-managed_certificate).
---
### Creating a certificate secret
We need now to create a secret with the SSL certificate we want in our load balancer. It's as easy as executing this command on the path you have your certificate keys stored:
```
kubectl -n argocd create secret tls secret-yourdomain-com \
--cert cert-file.crt --key key-file.key
```
### Creating an Ingress
And finally, to top it all, our Ingress. Note the reference to our frontend config, the service, and to the certificate secret:
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: argocd
namespace: argocd
annotations:
networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config
spec:
tls:
- secretName: secret-yourdomain-com
rules:
- host: argocd.yourdomain.com
http:
paths:
- path: /*
backend:
serviceName: argocd-server-external
servicePort: http
```
---
!!! warning "Deprecation Warning"
Note that, according to this [deprecation guide](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#ingress-v122), if you're using Kubernetes 1.22+, instead of `networking.k8s.io/v1beta1`, you should use `networking.k8s.io/v1`.
---
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.
You can get that IP address describing the Ingress object like this:
```
kubectl -n argocd describe ingresses argocd | grep Address
```
Once the DNS change is propagated, you're ready to use Argo with your Google Cloud Load Balancer
## Authenticating through multiple layers of authenticating reverse proxies
ArgoCD endpoints may be protected by one or more reverse proxies layers, in that case, you can provide additional headers through the `argocd` CLI `--header` parameter to authenticate through those layers.

View File

@@ -1,13 +1,27 @@
# Metrics
Argo CD exposes two sets of Prometheus metrics
Argo CD exposes different sets of Prometheus metrics per server.
## Application Metrics
## Application Controller Metrics
Metrics about applications. Scraped at the `argocd-metrics:8082/metrics` endpoint.
* Gauge for application health status
* Gauge for application sync status
* Counter for application sync history
| Metric | Type | Description |
|--------|:----:|-------------|
| `argocd_app_info` | gauge | Information about Applications. It contains labels such as `sync_status` and `health_status` that reflect the application state in ArgoCD. |
| `argocd_app_k8s_request_total` | counter | Number of kubernetes requests executed during application reconciliation |
| `argocd_app_labels` | gauge | Argo Application labels converted to Prometheus labels. Disabled by default. See section below about how to enable it. |
| `argocd_app_reconcile` | histogram | Application reconciliation performance. |
| `argocd_app_sync_total` | counter | Counter for application sync history |
| `argocd_cluster_api_resource_objects` | gauge | Number of k8s resource objects in the cache. |
| `argocd_cluster_api_resources` | gauge | Number of monitored kubernetes API resources. |
| `argocd_cluster_cache_age_seconds` | gauge | Cluster cache age in seconds. |
| `argocd_cluster_connection_status` | gauge | The k8s cluster current connection status. |
| `argocd_cluster_events_total` | counter | Number of processes k8s resource events. |
| `argocd_cluster_info` | gauge | Information about cluster. |
| `argocd_kubectl_exec_pending` | gauge | Number of pending kubectl executions |
| `argocd_kubectl_exec_total` | counter | Number of kubectl executions |
| `argocd_redis_request_duration` | histogram | Redis requests duration. |
| `argocd_redis_request_total` | counter | Number of redis requests executed during application reconciliation |
If you use ArgoCD with many application and project creation and deletion,
the metrics page will keep in cache your application and project's history.
@@ -16,10 +30,57 @@ to deleted resources, you can schedule a metrics reset to clean the
history with an application controller flag. Example:
`--metrics-cache-expiration="24h0m0s"`.
### Exposing Application labels as Prometheus metrics
There are use-cases where ArgoCD Applications contain labels that are desired to be exposed as Prometheus metrics.
Some examples are:
* Having the team name as a label to allow routing alerts to specific receivers
* Creating dashboards broken down by business units
As the Application labels are specific to each company, this feature is disabled by default. To enable it, add the
`--metrics-application-labels` flag to the ArgoCD application controller.
The example below will expose the ArgoCD Application labels `team-name` and `business-unit` to Prometheus:
containers:
- command:
- argocd-application-controller
- --metrics-application-labels
- team-name
- --metrics-application-labels
- business-unit
In this case, the metric would look like:
```
# TYPE argocd_app_labels gauge
argocd_app_labels{label_business_unit="bu-id-1",label_team_name="my-team",name="my-app-1",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_business_unit="bu-id-1",label_team_name="my-team",name="my-app-2",namespace="argocd",project="important-project"} 1
argocd_app_labels{label_business_unit="bu-id-2",label_team_name="another-team",name="my-app-3",namespace="argocd",project="important-project"} 1
```
## API Server Metrics
Metrics about API Server API request and response activity (request totals, response codes, etc...).
Scraped at the `argocd-server-metrics:8083/metrics` endpoint.
| Metric | Type | Description |
|--------|:----:|-------------|
| `argocd_redis_request_duration` | histogram | Redis requests duration. |
| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application reconciliation. |
## Repo Server Metrics
Metrics about the Repo Server.
Scraped at the `argocd-repo-server:8084/metrics` endpoint.
| Metric | Type | Description |
|--------|:----:|-------------|
| `argocd_git_request_duration_seconds` | histogram | Git requests duration seconds. |
| `argocd_git_request_total` | counter | Number of git requests performed by repo server |
| `argocd_redis_request_duration_seconds` | histogram | Redis requests duration seconds. |
| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application reconciliation. |
| `argocd_repo_pending_request_total` | gauge | Number of pending requests requiring repository lock |
## Prometheus Operator
If using Prometheus Operator, the following ServiceMonitor example manifests can be used.
@@ -65,7 +126,7 @@ metadata:
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-repo-server-metrics
app.kubernetes.io/name: argocd-repo-server
endpoints:
- port: metrics
```

View File

@@ -39,6 +39,10 @@ configures a custom role, named `org-admin`. The role is assigned to any user wh
`your-github-org:your-team` group. All other users get the default policy of `role:readonly`,
which cannot modify Argo CD settings.
!!! warning
All authenticated users get _at least_ the permissions granted by the default policy. This access cannot be blocked
by a `deny` rule. Instead, restrict the default policy and then grant permissions to individual roles as needed.
*ArgoCD ConfigMap `argocd-rbac-cm` Example:*
```yaml

View File

@@ -4,7 +4,7 @@ Argo CD is un-opinionated about how secrets are managed. There's many ways to do
* [Bitnami Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets)
* [GoDaddy Kubernetes External Secrets](https://github.com/godaddy/kubernetes-external-secrets)
* [External Secrets Operator](https://github.com/ContainerSolutions/externalsecret-operator)
* [External Secrets Operator](https://github.com/external-secrets/external-secrets)
* [Hashicorp Vault](https://www.vaultproject.io)
* [Banzai Cloud Bank-Vaults](https://github.com/banzaicloud/bank-vaults)
* [Helm Secrets](https://github.com/jkroepke/helm-secrets)

View File

@@ -11,7 +11,8 @@ Authentication to Argo CD API server is performed exclusively using [JSON Web To
in one of the following ways:
1. For the local `admin` user, a username/password is exchanged for a JWT using the `/api/v1/session`
endpoint. This token is signed & issued by the Argo CD API server itself, and has no expiration.
endpoint. This token is signed & issued by the Argo CD API server itself and it expires after 24 hours
(this token used not to expire, see [CVE-2021-26921](https://github.com/argoproj/argo-cd/security/advisories/GHSA-9h6w-j7w4-jr52)).
When the admin password is updated, all existing admin JWT tokens are immediately revoked.
The password is stored as a bcrypt hash in the [`argocd-secret`](https://github.com/argoproj/argo-cd/blob/master/manifests/base/config/argocd-secret.yaml) Secret.
@@ -196,3 +197,53 @@ Payloads from webhook events are considered untrusted. Argo CD only examines the
the involved applications of the webhook event (e.g. which repo was modified), then refreshes
the related application for reconciliation. This refresh is the same refresh which occurs regularly
at three minute intervals, just fast-tracked by the webhook event.
## Logging
Argo CD logs payloads of most API requests except request that are considered sensitive, such as
`/cluster.ClusterService/Create`, `/session.SessionService/Create` etc. The full list of method
can be found in [server/server.go](https://github.com/argoproj/argo-cd/blob/abba8dddce8cd897ba23320e3715690f465b4a95/server/server.go#L516).
Argo CD does not log IP addresses of clients requesting API endpoints, since the API server is typically behind a proxy. Instead, it is recommended
to configure IP addresses logging in the proxy server that sits in front of the API server.
## Limiting Directory App Memory Usage
> >2.2.10, 2.1.16, >2.3.5
Directory-type Applications (those whose source is raw JSON or YAML files) can consume significant
[repo-server](architecture.md#repository-server) memory, depending on the size and structure of the YAML files.
To avoid over-using memory in the repo-server (potentially causing a crash and denial of service), set the
`reposerver.max.combined.directory.manifests.size` config option in [argocd-cmd-params-cm](argocd-cmd-params-cm.yaml).
This option limits the combined size of all JSON or YAML files in an individual app. Note that the in-memory
representation of a manifest may be as much as 300x the size of the manifest on disk. Also note that the limit is per
Application. If manifests are generated for multiple applications at once, memory usage will be higher.
**Example:**
Suppose your repo-server has a 10G memory limit, and you have ten Applications which use raw JSON or YAML files. To
calculate the max safe combined file size per Application, divide 10G by 300 * 10 Apps (300 being the worst-case memory
growth factor for the manifests).
```
10G / 300 * 10 = 3M
```
So a reasonably safe configuration for this setup would be a 3M limit per app.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
data:
reposerver.max.combined.directory.manifests.size: '3M'
```
The 300x ratio assumes a maliciously-crafted manifest file. If you only want to protect against accidental excessive
memory use, it is probably safe to use a smaller ratio.
Keep in mind that if a malicious user can create additional Applications, they can increase the total memory usage.
Grant [App creation privileges](rbac.md) carefully.

View File

@@ -30,6 +30,7 @@ argocd-application-controller [flags]
--kubectl-parallelism-limit int Number of allowed concurrent kubectl fork/execs. Any value less the 1 means no limit. (default 20)
--logformat string Set the logging format. One of: text|json (default "text")
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
--metrics-application-labels strings List of Application labels that will be added to the argocd_application_labels metric
--metrics-cache-expiration duration Prometheus metrics cache expiration (disabled by default. e.g. 24h0m0s)
--metrics-port int Start metrics server on given port (default 8082)
-n, --namespace string If present, the namespace scope for this CLI request

View File

@@ -13,27 +13,28 @@ argocd-repo-server [flags]
### Options
```
--default-cache-expiration duration Cache expiration default (default 24h0m0s)
--disable-tls Disable TLS on the gRPC endpoint
-h, --help help for argocd-repo-server
--logformat string Set the logging format. One of: text|json (default "text")
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
--metrics-port int Start metrics server on given port (default 8084)
--parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit.
--port int Listen on given port for incoming connections (default 8081)
--redis string Redis server hostname and port (e.g. argocd-redis:6379).
--redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.
--redis-client-certificate string Path to Redis client certificate (e.g. /etc/certs/redis/client.crt).
--redis-client-key string Path to Redis client key (e.g. /etc/certs/redis/client.crt).
--redis-insecure-skip-tls-verify Skip Redis server certificate validation.
--redis-use-tls Use TLS when connecting to Redis.
--redisdb int Redis database.
--repo-cache-expiration duration Cache expiration for repo state, incl. app lists, app details, manifest generation, revision meta-data (default 24h0m0s)
--revision-cache-expiration duration Cache expiration for cached revision (default 3m0s)
--sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379).
--sentinelmaster string Redis sentinel master group name. (default "master")
--tlsciphers string The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384")
--tlsmaxversion string The maximum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.3")
--tlsminversion string The minimum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.2")
--default-cache-expiration duration Cache expiration default (default 24h0m0s)
--disable-tls Disable TLS on the gRPC endpoint
-h, --help help for argocd-repo-server
--logformat string Set the logging format. One of: text|json (default "text")
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
--max-combined-directory-manifests-size string Max combined size of manifest files in a directory-type Application (default "10M")
--metrics-port int Start metrics server on given port (default 8084)
--parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit.
--port int Listen on given port for incoming connections (default 8081)
--redis string Redis server hostname and port (e.g. argocd-redis:6379).
--redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.
--redis-client-certificate string Path to Redis client certificate (e.g. /etc/certs/redis/client.crt).
--redis-client-key string Path to Redis client key (e.g. /etc/certs/redis/client.crt).
--redis-insecure-skip-tls-verify Skip Redis server certificate validation.
--redis-use-tls Use TLS when connecting to Redis.
--redisdb int Redis database.
--repo-cache-expiration duration Cache expiration for repo state, incl. app lists, app details, manifest generation, revision meta-data (default 24h0m0s)
--revision-cache-expiration duration Cache expiration for cached revision (default 3m0s)
--sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379).
--sentinelmaster string Redis sentinel master group name. (default "master")
--tlsciphers string The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384")
--tlsmaxversion string The maximum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.3")
--tlsminversion string The minimum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.2")
```

View File

@@ -0,0 +1,89 @@
# v2.1 to 2.2
## Upgraded Helm Version
Note that bundled Helm has been upgraded from 3.6.0 to v3.7+. This includes following breaking changes:
- Repository credentials are no longer passed to download charts that
are being served from a different domain than the repository.
You can still force older behavior with `--helm-pass-credentials` option to `argocd app create`.
More information in the [Helm v3.6.1 release notes](https://github.com/helm/helm/releases/tag/v3.6.1).
- Experimental OCI support has been rewritten.
More information in the [Helm v3.7.0 release notes](https://github.com/helm/helm/releases/tag/v3.7.0).
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed in 2.2.12
Argo CD 2.2.12 upgraded its base image from Ubuntu 21.10 to Ubuntu 22.04, which upgraded OpenSSH to 8.9. OpenSSH starting
with 8.8 [dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
The signature algorithm is _not_ the same as the algorithm used when generating the key. There is no need to update
keys.
The signature algorithm is negotiated with the SSH server when the connection is being set up. The client offers its
list of accepted signature algorithms, and if the server has a match, the connection proceeds. For most SSH servers on
up-to-date git providers, acceptable algorithms other than `ssh-rsa` should be available.
Before upgrading to Argo CD 2.2.12, check whether your git provider(s) using SSH authentication support algorithms newer
than `rsa-ssh`.
1. Make sure your version of SSH >= 8.9 (the version used by Argo CD). If not, upgrade it before proceeding.
```shell
ssh -V
```
Example output: `OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022`
2. Once you have a recent version of OpenSSH, follow the directions from the [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.7):
> To check whether a server is using the weak ssh-rsa public key
> algorithm, for host authentication, try to connect to it after
> removing the ssh-rsa algorithm from ssh(1)'s allowed list:
>
> ```shell
> ssh -oHostKeyAlgorithms=-ssh-rsa user@host
> ```
>
> If the host key verification fails and no other supported host key
> types are available, the server software on that host should be
> upgraded.
If the server does not support an acceptable version, you will get an error similar to this;
```
$ ssh -oHostKeyAlgorithms=-ssh-rsa vs-ssh.visualstudio.com
Unable to negotiate with 20.42.134.1 port 22: no matching host key type found. Their offer: ssh-rsa
```
This indicates that the server needs to update its supported key signature algorithms, and Argo CD will not connect
to it.
### Workaround
The [OpenSSH 8.8 release notes](https://www.openssh.com/txt/release-8.8) describe a workaround if you cannot change the
server's key signature algorithms configuration.
> Incompatibility is more likely when connecting to older SSH
> implementations that have not been upgraded or have not closely tracked
> improvements in the SSH protocol. For these cases, it may be necessary
> to selectively re-enable RSA/SHA1 to allow connection and/or user
> authentication via the HostkeyAlgorithms and PubkeyAcceptedAlgorithms
> options. For example, the following stanza in ~/.ssh/config will enable
> RSA/SHA1 for host and user authentication for a single destination host:
>
> ```
> Host old-host
> HostkeyAlgorithms +ssh-rsa
> PubkeyAcceptedAlgorithms +ssh-rsa
> ```
>
> We recommend enabling RSA/SHA1 only as a stopgap measure until legacy
> implementations can be upgraded or reconfigured with another key type
> (such as ECDSA or Ed25519).
To apply this to Argo CD, you could create a ConfigMap with the desired ssh config file and then mount it at
`/home/argocd/.ssh/config`.

View File

@@ -3,7 +3,7 @@
!!!note
This section contains information on upgrading Argo CD. Before upgrading please make sure to read details about
the breaking changes between Argo CD versions.
the breaking changes between Argo CD versions.
Argo CD uses the semver versioning and ensures that following rules:
@@ -16,7 +16,7 @@ please make sure to check upgrading details in both [v1.3 to v1.4](./1.3-1.4.md
Argo CD settings using disaster recovery [guide](../disaster_recovery.md).
After reading the relevant notes about possible breaking changes introduced in Argo CD version use the following
command to upgrade Argo CD. Make sure to replace `<version>` with the required version number:
command to upgrade Argo CD. Make sure to replace `<version>` with the required version number:
**Non-HA**:
@@ -33,15 +33,18 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/<v
Even though some releases require only image change it is still recommended to apply whole manifests set.
Manifest changes might include important parameter modifications and applying the whole set will protect you from
introducing misconfiguration.
introducing misconfiguration.
<hr/>
* [v1.7 to v1.8](./1.7-1.8.md)
* [v1.6 to v1.7](./1.6-1.7.md)
* [v1.5 to v1.6](./1.5-1.6.md)
* [v1.4 to v1.5](./1.4-1.5.md)
* [v1.3 to v1.4](./1.3-1.4.md)
* [v2.1 to v2.2](./2.1-2.2.md)
* [v2.0 to v2.1](./2.0-2.1.md)
* [v1.8 to v2.0](./1.8-2.0.md)
* [v1.7 to v1.8](./1.7-1.8.md)
* [v1.6 to v1.7](./1.6-1.7.md)
* [v1.5 to v1.6](./1.5-1.6.md)
* [v1.4 to v1.5](./1.4-1.5.md)
* [v1.3 to v1.4](./1.3-1.4.md)
* [v1.2 to v1.3](./1.2-1.3.md)
* [v1.1 to v1.2](./1.1-1.2.md)
* [v1.0 to v1.1](./1.0-1.1.md)
* [v1.1 to v1.2](./1.1-1.2.md)
* [v1.0 to v1.1](./1.0-1.1.md)

View File

@@ -1,6 +1,13 @@
# Google
* [G Suite SAML App Auth using Dex](#g-suite-saml-app-auth-using-dex)
There are three different ways to integrate Argo CD login with your Google Workspace users. Generally the OpenID Connect (_oidc_) method would be the recommended way of doing this integration (and easier, as well...), but depending on your needs, you may choose a different option.
* [OpenID Connect using Dex](#openid-connect-using-dex)
This is the recommended login method if you don't need information about the groups the user's belongs to. Google doesn't expose the `groups` claim via _oidc_, so you won't be able to use Google Groups membership information for RBAC.
* [SAML App Auth using Dex](#saml-app-auth-using-dex)
Dex [recommends avoiding this method](https://dexidp.io/docs/connectors/saml/#warning). Also, you won't get Google Groups membership information through this method.
* [OpenID Connect plus Google Groups using Dex](#openid-connect-plus-google-groups-using-dex)
This is the recommended method if you need to user Google Groups membership in your RBAC configuration.
Once you've set up one of the above integrations, be sure to edit `argo-rbac-cm` to configure permissions (as in the example below). See [RBAC Configurations](../rbac.md) for more detailed scenarios.
@@ -14,10 +21,66 @@ data:
policy.default: role:readonly
```
## G Suite SAML App Auth using Dex
## OpenID Connect using Dex
### Configure your OAuth consent screen
If you've never configured this, you'll be redirected straight to this if you try to create an OAuth Client ID
1. Go to your [OAuth Consent](https://console.cloud.google.com/apis/credentials/consent) configuration. If you still haven't created one, select `Internal` or `External` and click `Create`
2. Go and [edit your OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent/edit) Verify you're in the correct project!
3. Configure a name for your login app and a user support email address
4. The app logo and filling the information links is not mandatory, but it's a nice touch for the login page
5. In "Authorized domains" add the domains who are allowed to log in to ArgoCD (e.g. if you add `example.com`, all Google Workspace users with an `@example.com` address will be able to log in)
6. Save to continue to the "Scopes" section
7. Click on "Add or remove scopes" and add the `.../auth/userinfo.profile` and the `openid` scopes
8. Save, review the summary of your changes and finish
### Configure a new OAuth Client ID
1. Go to your [Google API Credentials](https://console.cloud.google.com/apis/credentials) console, and make sure you're in the correct project.
2. Click on "+Create Credentials"/"OAuth Client ID"
3. Select "Web Application" in the Application Type drop down menu, and enter an identifying name for your app (e.g. `Argo CD`)
4. Fill "Authorized JavaScript origins" with your Argo CD URL, e.g. `https://argocd.example.com`
5. Fill "Authorized redirect URIs" with your Argo CD URL plus `/api/dex/callback`, e.g. `https://argocd.example.com/api/dex/callback`
![](../../assets/google-admin-oidc-uris.png)
6. Click "Create" and save your "Client ID" and your "Client Secret" for later
### Configure Argo to use OpenID Connect
Edit `argo-cm` and add the following `dex.config` to the data section, replacing `clientID` and `clientSecret` with the values you saved before:
```yaml
data:
url: https://argocd.example.com
dex.config: |
connectors:
- config:
issuer: https://accounts.google.com
clientID: XXXXXXXXXXXXX.apps.googleusercontent.com
clientSecret: XXXXXXXXXXXXX
type: oidc
id: google
name: Google
```
### References
- [Dex oidc connector docs](https://dexidp.io/docs/connectors/oidc/)
## SAML App Auth using Dex
### Configure a new SAML App
---
!!! warning "Deprecation Warning"
Note that, according to [Dex documentation](https://dexidp.io/docs/connectors/saml/#warning), SAML is considered unsafe and they are planning to deprecate that module.
---
1. In the [Google admin console](https://admin.google.com), open the left-side menu and select `Apps` > `SAML Apps`
![Google Admin Apps Menu](../../assets/google-admin-saml-apps-menu.png "Google Admin menu with the Apps / SAML Apps path selected")
@@ -76,3 +139,97 @@ data:
- [Dex SAML connector docs](https://dexidp.io/docs/connectors/saml/)
- [Google's SAML error messages](https://support.google.com/a/answer/6301076?hl=en)
## OpenID Connect plus Google Groups using Dex
---
!!! warning "Limited group information"
When using this feature you'll only receive the list of groups the user is a direct member.
So, lets say you have this hierarchy of groups and subgroups:
`all@example.com --> tech@example.com --> devs@example.com --> you@example.com`
The only group you would receive through Dex would be `devs@example.com`
---
We're going to use Dex's `google` connector to get additional Google Groups information from your users, allowing you to use group membership on your RBAC, i.e., giving `admin` role to the whole `sysadmins@yourcompany.com` group.
This connector uses two different credentials:
- An oidc client ID and secret
Same as when you're configuring an [OpenID connection](#openid-connect-using-dex), this authenticates your users
- A Google service account
This is used to connect to the Google Directory API and pull information about your user's group membership
Also, you'll need the email address for an admin user on this domain. Dex will impersonate that user identity to fetch user information from the API.
### Configure OpenID Connect
Go through the same steps as in [OpenID Connect using Dex](#openid-connect-using-dex), except for configuring `argocd-cm`. We'll do that later.
### Set up Directory API access
1. Follow [Google instructions to create a service account with Domain-Wide Delegation](https://developers.google.com/admin-sdk/directory/v1/guides/delegation)
- When assigning API scopes to the service account assign **only** the `https://www.googleapis.com/auth/admin.directory.group.readonly` scope and nothing else. If you assign any other scopes, you won't be able to fetch information from the API
- Create the credentials in JSON format and store them in a safe place, we'll need them later
2. Enable the [Admin SDK](https://console.developers.google.com/apis/library/admin.googleapis.com/)
### Configure Dex
1. Create a secret with the contents of the previous json file encoded in base64, like this:
apiVersion: v1
kind: Secret
metadata:
name: argocd-google-groups-json
namespace: argocd
data:
googleAuth.json: JSON_FILE_BASE64_ENCODED
2. Edit your `argocd-dex-server` deployment to mount that secret as a file
- Add a volume mount in `/spec/template/spec/containers/0/volumeMounts/` like this. Be aware of editing the running container and not the init container!
volumeMounts:
- mountPath: /shared
name: static-files
- mountPath: /tmp
name: dexconfig
- mountPath: /tmp/oidc
name: google-json
readOnly: true
- Add a volume in `/spec/template/spec/volumes/` like this:
volumes:
- emptyDir: {}
name: static-files
- emptyDir: {}
name: dexconfig
- name: google-json
secret:
defaultMode: 420
secretName: argocd-google-groups-json
3. Edit `argo-cm` and add the following `dex.config` to the data section, replacing `clientID` and `clientSecret` with the values you saved before, `adminEmail` with the address for the admin user you're going to impersonate, and editing `redirectURI` with your Argo CD domain:
dex.config: |
connectors:
- config:
redirectURI: https://argocd.example.com/api/dex/callback
clientID: XXXXXXXXXXXXX.apps.googleusercontent.com
clientSecret: XXXXXXXXXXXXX
serviceAccountFilePath: /tmp/oidc/googleAuth.json
adminEmail: admin-email@example.com
type: google
id: google
name: Google
4. Restart your `argocd-dex-server` deployment to be sure it's using the latest configuration
5. Login to Argo CD and go to the "User info" section, were you should see the groups you're member
![User info](../../assets/google-groups-membership.png)
6. Now you can use groups email addresses to give RBAC permissions
### References
- [Dex Google connector docs](https://dexidp.io/docs/connectors/google/)

View File

@@ -77,6 +77,7 @@ argocd account get --account <username>
* Set user password
```bash
# if you are managing users as the admin user, <current-user-password> should be the current admin password.
argocd account update-password \
--account <name> \
--current-password <current-user-password> \
@@ -114,7 +115,8 @@ There are two ways that SSO can be configured:
* [Bundled Dex OIDC provider](#dex) - use this option if your current provider does not support OIDC (e.g. SAML,
LDAP) or if you wish to leverage any of Dex's connector features (e.g. the ability to map GitHub
organizations and teams to OIDC groups claims).
organizations and teams to OIDC groups claims). Dex also supports OIDC directly and can fetch user
information from the identity provider when the groups cannot be included in the IDToken.
* [Existing OIDC provider](#existing-oidc-provider) - use this if you already have an OIDC provider which you are using (e.g.
[Okta](okta.md), [OneLogin](onelogin.md), [Auth0](auth0.md), [Microsoft](microsoft.md), [Keycloak](keycloak.md),
@@ -196,6 +198,91 @@ NOTES:
Argo CD will automatically use the correct `redirectURI` for any OAuth2 connectors, to match the
correct external callback URL (e.g. `https://argocd.example.com/api/dex/callback`)
## OIDC Configuration with DEX
Dex can be used for OIDC authentication instead of ArgoCD directly. This provides a separate set of
features such as fetching information from the `UserInfo` endpoint and
[federated tokens](https://dexidp.io/docs/custom-scopes-claims-clients/#cross-client-trust-and-authorized-party)
### Configuration:
* In the `argocd-cm` ConfigMap add the `OIDC` connector to the `connectors` sub field inside `dex.config`.
See Dex's [OIDC connect documentation](https://dexidp.io/docs/connectors/oidc/) to see what other
configuration options might be useful. We're going to be using a minimal configuration here.
* The issuer URL should be where Dex talks to the OIDC provider. There would normally be a
`.well-known/openid-configuration` under this URL which has information about what the provider supports.
e.g. https://accounts.google.com/.well-known/openid-configuration
```yaml
data:
url: "https://argocd.example.com"
dex.config: |
connectors:
# OIDC
- type: OIDC
id: oidc
name: OIDC
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
```
### Requesting additional ID token claims
By default Dex only retrieves the profile and email scopes. In order to retrieve more more claims you
can add them under the `scopes` entry in the Dex configuration. To enable group claims through Dex,
`insecureEnableGroups` also needs to enabled. Group information is currently only refreshed at authentication
time and support to refresh group information more dynamically can be tracked here: [dexidp/dex#1065](https://github.com/dexidp/dex/issues/1065).
```yaml
data:
url: "https://argocd.example.com"
dex.config: |
connectors:
# OIDC
- type: OIDC
id: oidc
name: OIDC
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
```
!!! warning
Because group information is only refreshed at authentication time just adding or removing an account from a group will not change a user's membership until they reauthenticate. Depending on your organization's needs this could be a security risk and could be mitigated by changing the authentication token's lifetime.
### Retrieving claims that are not in the token
When an Idp does not or cannot support certain claims in an IDToken they can be retrieved separately using
the UserInfo endpoint. Dex supports this functionality using the `getUserInfo` endpoint. One of the most
common claims that is not supported in the IDToken is the `groups` claim and both `getUserInfo` and `insecureEnableGroups`
must be set to true.
```yaml
data:
url: "https://argocd.example.com"
dex.config: |
connectors:
# OIDC
- type: OIDC
id: oidc
name: OIDC
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
getUserInfo: true
```
## Existing OIDC Provider
To configure Argo CD to delegate authenticate to your existing OIDC provider, add the OAuth2
@@ -286,6 +373,21 @@ You are not required to specify a logoutRedirectURL as this is automatically gen
!!! note
The post logout redirect URI may need to be whitelisted against your OIDC provider's client settings for ArgoCD.
### Configuring a custom root CA certificate for communicating with the OIDC provider
If your OIDC provider is setup with a certificate which is not signed by one of the well known certificate authorities
you can provide a custom certificate which will be used in verifying the OIDC provider's TLS certificate when
communicating with it.
Add a `rootCA` to your `oidc.config` which contains the PEM encoded root certificate:
```yaml
oidc.config: |
...
rootCA: |
-----BEGIN CERTIFICATE-----
... encoded certificate data here ...
-----END CERTIFICATE-----
```
## SSO Further Reading
@@ -390,3 +492,20 @@ data:
clientSecret: $another-secret:oidc.auth0.clientSecret # Mind the ':'
...
```
### Skipping certificate verification on OIDC provider connections
By default, all connections made by the API server to OIDC providers (either external providers or the bundled Dex
instance) must pass certificate validation. These connections occur when getting the OIDC provider's well-known
configuration, when getting the OIDC provider's keys, and when exchanging an authorization code or verifying an ID
token as part of an OIDC login flow.
Disabling certificate verification might make sense if:
* You are using the bundled Dex instance **and** your Argo CD instance has TLS configured with a self-signed certificate
**and** you understand and accept the risks of skipping OIDC provider cert verification.
* You are using an external OIDC provider **and** that provider uses an invalid certificate **and** you cannot solve
the problem by setting `oidcConfig.rootCA` **and** you understand and accept the risks of skipping OIDC provider cert
verification.
If either of those two applies, then you can disable OIDC provider certificate verification by setting
`oidc.tls.insecure.skip.verify` to `"true"` in the `argocd-cm` ConfigMap.

View File

@@ -57,17 +57,19 @@ Let's start by storing the client secret you generated earlier in the argocd sec
1. First you'll need to encode the client secret in base64: `$ echo -n '83083958-8ec6-47b0-a411-a8c55381fbd2' | base64`
2. Then you can edit the secret and add the base64 value to a new key called _oidc.keycloak.clientSecret_ using `$ kubectl edit secret argocd-secret`.
Your Secret should look something like this:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
data:
...
oidc.keycloak.clientSecret: ODMwODM5NTgtOGVjNi00N2IwLWE0MTEtYThjNTUzODFmYmQy
...
```
Your Secret should look something like this:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
data:
...
oidc.keycloak.clientSecret: ODMwODM5NTgtOGVjNi00N2IwLWE0MTEtYThjNTUzODFmYmQy
...
```
Now we can configure the config map and add the oidc configuration to enable our keycloak authentication.
You can use `$ kubectl edit configmap argocd-cm`.

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