Compare commits

...

128 Commits

Author SHA1 Message Date
argo-bot
a48bca03c7 Bump version to 2.4.6 2022-07-12 22:19:23 +00:00
argo-bot
6930ceb414 Bump version to 2.4.6 2022-07-12 22:19:14 +00:00
CI
01b7a73922 chore: fix build error
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-12 16:46:39 -04:00
taksenov
ff2d9b918d docs: fix typo in Generators-Git.md (#9949)
`ApplictionSet` --> `ApplicationSet`
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-12 16:29:03 -04:00
Jake
cea91ce935 docs: add terminal documentation (#9948)
Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>
2022-07-12 16:28:24 -04:00
Michael Crenshaw
51b73096f5 fix: 'unexpected reserved bits' breaking web terminal (#9605) (#9895)
* fix: 'unexpected reserved bits' breaking web terminal (#9605)

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

* make things more like they were originally, since the mutex fixes the problem

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

* fix typo, don't pass around a pointer when it isn't necessary

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

* apply suggestions

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-07-12 16:28:01 -04:00
Yuan Tang
2c166dac97 feat: Treat connection reset as a retryable error (#9739)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2022-07-12 16:25:08 -04:00
jannfis
16c015f0cb test: Use dedicated multi-arch workloads in e2e tests (#9921)
* test: Use dedicated multi-arch workloads in e2e tests

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

* Use correct tag

Signed-off-by: jannfis <jann@mistrust.net>
2022-07-12 16:24:41 -04:00
Xiao Yang
7ca60cb957 fix: argocd login just hangs on 2.4.0 #9679 (#9935)
Signed-off-by: Xiao Yang <muma.378@163.com>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-12 16:24:23 -04:00
Jake
d0c80ee0bb fix: CMP manifest generation fails with ENHANCE_YOUR_CALM if over 40s (#9922)
* fix: CMP manifest generation fails with ENHANCE_YOUR_CALM if over 40s

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>

* fix timeouts across all gRPC servers

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>

* use common consts

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>
2022-07-12 16:24:00 -04:00
yongguangl
9f1a33865a fix: NotAfter is not set when ValidFor is set (#9911)
Signed-off-by: yongguangl <1363186473@qq.com>
2022-07-12 16:21:21 -04:00
Hyeonmin Park
f09c84f30a fix: add missing download CLI tool link for ppc64le, s390x (#9649)
Signed-off-by: Hyeonmin Park <hyeonmin.park@kennysoft.kr>
2022-07-12 16:21:03 -04:00
jannfis
f7f7493e9f fix: Check tracking annotation for being self-referencing (#9791)
* fix: Check tracking annotation for being self-referencing

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

* Tweak isManagedLiveObj() logic

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

* Rename isManagedLiveResource to isSelfReferencedObj

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

* Add e2e test

Signed-off-by: jannfis <jann@mistrust.net>
2022-07-12 16:20:21 -04:00
jannfis
c1ddb53d29 fix: Make change of tracking method work at runtime (#9820)
* fix: Make change of tracking method work at runtime

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

* GetAppName() will figure tracking label or annotation on its own

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

* Correct test comments and add another test

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

* Add a read lock before getting cache settings

Signed-off-by: jannfis <jann@mistrust.net>
2022-07-12 16:19:41 -04:00
Shunki
e04288482d fix: argo-cd git submodule is using SSH auth instead of HTTPs (#3118) (#9821)
* fix: argo-cd git submodule is using SSH auth instead of HTTPs (#3118)

Signed-off-by: shunki-fujita <shunki-fujita@cybozu.co.jp>

* Add submodule functions and unit tests
Signed-off-by: shunki-fujita <shunki-fujita@cybozu.co.jp>
2022-07-12 16:16:48 -04:00
YaytayAtWork
1f3e1ec803 #9429: Adding blank line so list is formatted correctly. (#9880)
Signed-off-by: CI <michael@crenshaw.dev>
2022-07-12 16:14:05 -04:00
Jake
c3423e8df3 docs: small fix for plugin stream filtering (#9871)
Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>
2022-07-12 16:13:45 -04:00
Didrik Finnøy
5ef48c1123 docs: Document the possibility of rendering Helm charts with Kustomize (#9841)
* Update kustomize.md

Resolves  #7835.

Signed-off-by: Didrik Finnøy <djfinnoy@protonmail.com>

* Removed unnecessary command flag from example. Minor text edits.

Signed-off-by: Didrik Finnøy <djfinnoy@protonmail.com>

* spelling

Signed-off-by: Didrik Finnøy <djfinnoy@protonmail.com>
2022-07-12 16:13:22 -04:00
YaytayAtWork
e3ae286e2d docs: getting started notes on self-signed cert (#9429) (#9784)
* Fix #9429: A couple of notes in the docs to explain that the default certificate is insecure.

Signed-off-by: Jim Talbut <jim.talbut@groupgti.com>

* Fixes #9429: More verbose, but complete, text for Getting Started.

Signed-off-by: Jim Talbut <jim.talbut@groupgti.com>
2022-07-12 16:12:41 -04:00
Michael Crenshaw
7abf6713b4 test: check for error messages from CI env (#9953)
test: check for error messages from CI env (#9953)

Signed-off-by: CI <michael@crenshaw.dev>
2022-07-12 15:31:44 -04:00
argo-bot
0232073ccf Bump version to 2.4.5 2022-07-12 16:08:04 +00:00
argo-bot
860d8fd7e1 Bump version to 2.4.5 2022-07-12 16:07:57 +00:00
Michael Crenshaw
147ff80543 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
Michael Crenshaw
3800a1e49d Merge pull request from GHSA-pmjg-52h9-72qv
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

formatting

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

fixes from comments

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

fix test

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-07-12 08:45:22 -04:00
argo-bot
fe80bdcfdc Bump version to 2.4.4 2022-07-07 06:57:43 +00:00
argo-bot
94c09dff59 Bump version to 2.4.4 2022-07-07 06:57:37 +00:00
jannfis
3d9e4d439e 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-06 19:18:51 +00:00
noah
4a955e25a0 docs: custom secret must be labeled (#9835)
As far as I can tell, this isn't explicitly documented anywhere (some docs mentioned this label in reference to ConfigMaps) I only figure it out by looking at the code.
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-07-01 15:55:34 -04:00
noah
4f99f251bf fix: missing path segments for git file generator (#9839)
* fix: missing path segments for git file generator

given the path:

  /one/two/file.yaml

This change adds the params:

path[1]=two
path.filename=file.yaml
path.filenameNormalized

The use case is for symmetry with other generators (e.g., merge with a directory generator using the key path[1]). As no existing parameter values are changed it should be non-breaking.

Signed-off-by: Noah Perks Sloan <noah@hackedu.io>

* fix: expose all path elements for directory generator

This makes it consistent with the files generator and removes un-intuitive behavior without any breaking change.

docs: clarify - can use either baseName or nth path element
docs: use "directory", like the name of the generator, where "folder" was mentioned
Signed-off-by: Noah Perks Sloan <noah@hackedu.io>
2022-07-01 15:54:15 -04:00
Alexander Matyushentsev
fd418cec0d fix: make sure api server informer does not stop after setting change (#9842)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-06-30 15:30:33 -07:00
Xiao Yang
dc291a629f fix: support resource logs and exec (#9833)
Signed-off-by: Xiao Yang <muma.378@163.com>
2022-06-30 09:07:00 -04:00
Paulo Coelho
e23a1c6026 docs: update archlinux install with official package (#9718)
Signed-off-by: Paulo Coelho <prscoelho@protonmail.com>
2022-06-29 16:38:21 -04:00
Chris Reilly
aee88c6452 docs: explain rightmost git generator path parameter behavior (#9799)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-29 16:31:15 -04:00
KevinSnyderCodes
3f111cc640 git: prune any deleted refs before fetching (#9504)
* git: prune any deleted refers before fetching

This commit modifies `nativeGitClient.Fetch()` to call `git remote prune origin` before fetching refs.

In some cases, an old branch may exist that conflicts with the name of a new branch. The old branch will have been deleted from `origin` but still exist locally in the `argocd-repo-server`.

Example: an old branch `feature/foo` conflicts with a new branch `feature/foo/bar`

In these cases, syncing an application results in the error:

```
rpc error: code = Internal desc = Failed to fetch default: `git fetch origin --tags --force` failed exit status 1: error: cannot lock ref 'refs/remotes/origin/feature/foo/bar': 'refs/remotes/origin/feature/foo' exists; cannot create 'refs/remotes/origin/feature/foo/bar' From https://github.com/org/repo ! [new branch] feature/foo/bar -> origin/feature/foo/bar (unable to update local ref) error: some local refs could not be updated; try running 'git remote prune origin' to remove any old, conflicting branches
```

Adding `git remote prune origin` before fetching, as recommended by the error message, should fix this issue.

The current workaround is to restart the `argocd-repo-server` which should flush the local repository folder. This works when Argo CD is installed using the Helm chart.

Signed-off-by: Kevin Snyder <kevin.snyder.codes@gmail.com>

* fix: added extra protection to syncing app with replace (#9187)

* fix: added extra protection to syncing app with replace

Signed-off-by: ciiay <yicai@redhat.com>

* Code clean up

Signed-off-by: ciiay <yicai@redhat.com>

* Updated logic for isAppOfAppsPattern

Signed-off-by: ciiay <yicai@redhat.com>

* Updated text strings as per comment

Signed-off-by: ciiay <yicai@redhat.com>

* Fixed lint issue

Signed-off-by: ciiay <yicai@redhat.com>
Signed-off-by: Kevin Snyder <kevin.snyder.codes@gmail.com>

* chore: Simplified GetRepoHTTPClient function (#9396)

* chore: Simplified GetRepoHTTPClient function

Signed-off-by: ls0f <lovedboy.tk@qq.com>

* simplified code and improve unit test coverage

Signed-off-by: ls0f <lovedboy.tk@qq.com>
Signed-off-by: Kevin Snyder <kevin.snyder.codes@gmail.com>

* Only prune if fetch error message indicates that it is worthwhile, add unit tests

Confirmed that `Test_nativeGitClient_Fetch_Prune` fails without the bug fix, succeeds with it.

Signed-off-by: Kevin Snyder <kevin.snyder.codes@gmail.com>

* fix: avoid k8s call before authorization for terminal endpoint (#9434)

* fix: avoid k8s API call before authorization in k8s endpoint

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

* check for bad project

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

* lint

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

* more logging

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

* handle 404, return 500 instead of 400 for other errors

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

* use user input

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

* refactor validation

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

* fix tests

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

* fixes, tests

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Kevin Snyder <kevin.snyder.codes@gmail.com>

* Match against "try running 'git remote prune origin'"

Signed-off-by: Kevin Snyder <kevin.snyder.codes@gmail.com>

Co-authored-by: Yi Cai <yicai@redhat.com>
Co-authored-by: ls0f <lovedboy.tk@qq.com>
Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-29 16:28:51 -04:00
Jake
596038fc0f fix: configurable CMP tar exclusions (#9675) (#9789)
* feat: configurable CMP tar exclusions

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>

* rename cmp to plugin

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>

* add test for tar stream exclusions

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>

* fix tests

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>

* update cmp guide

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>

* fully parameterize

Signed-off-by: notfromstatefarm <86763948+notfromstatefarm@users.noreply.github.com>
2022-06-29 16:27:41 -04:00
argo-bot
471685feae Bump version to 2.4.3 2022-06-27 20:53:14 +00:00
argo-bot
42e1f29117 Bump version to 2.4.3 2022-06-27 20:53:07 +00:00
Michael Crenshaw
c089f9a5e5 fix: respect OIDC providers' supported token signing algorithms (#9433) (#9761)
* fix: respect OIDC providers' supported token signing algorithms (#9433)

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

* go mod tidy

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-27 16:32:35 -04:00
TomHellier
1dc5e6aaf9 fix: websockets for terminal not working on subPath (#9795)
Signed-off-by: Tom Hellier <me@tomhellier.com>
2022-06-27 13:26:11 -07:00
Alexander Matyushentsev
82726fcbcf fix: avoid closing and re-opening port of api server settings change (#9778)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-06-24 10:17:20 -07:00
Nicolas Fillot
e715e085aa [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:27:15 -04:00
Michael Crenshaw
7db5ab71b0 fix: overrides should not appear in the manifest cache key (#9601)
* fix: overrides should not appear in the manifest cache key

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

* fix Helm regression

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

* fix test

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

* fix test again

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-22 09:24:29 -04:00
argo-bot
c6d0c8baaa Bump version to 2.4.2 2022-06-21 20:32:13 +00:00
argo-bot
2115bf7746 Bump version to 2.4.2 2022-06-21 20:32:08 +00:00
Yaakov Selkowitz
0a2520f511 test/remote: Allow override of base image (#9734)
ubuntu:22.04 bumped the ppc64el baseline to POWER9, rendering this
unusable on existing POWER8 systems.  This allows customization similar
to the top-level Dockerfile.

Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
2022-06-21 15:24:13 -04:00
Soumya Ghosh Dastidar
211e9f6127 fix: updated config file permission requirements for windows (#9732)
* fix: reduced config file permission restriction on windows

Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>

* fix: updated localconfig tests to check error

Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>
2022-06-21 15:09:48 -04:00
hritikch24
792e278080 Update sync-options.md (#9687)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 14:49:10 -04:00
Michael Crenshaw
93bf321002 fix: project filter (#9651) (#9709)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 14:39:34 -04:00
Joren Zandstra
48c2e0bf21 fix broken symlink in Dockerfile (#9674)
Signed-off-by: Joren Zandstra <jorenzandstra@yahoo.com>
2022-06-21 14:39:26 -04:00
Soumya Ghosh Dastidar
b4b893ca1c fix: updated baseHRefRegex to perform lazy match (#9724)
* fix: updated baseHRefRegex to perform lazy match

Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>

* feat: added unit tests for replaceBaseHRef

Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>
2022-06-21 10:39:12 -07:00
argo-bot
52e6025f8b Bump version to 2.4.1 2022-06-21 16:27:47 +00:00
argo-bot
b121b89c81 Bump version to 2.4.1 2022-06-21 16:27:40 +00:00
Michael Crenshaw
12149c0710 chore: fix docs gen
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 10:34:03 -04:00
Michael Crenshaw
9d67469428 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
04c3053964 Merge pull request from GHSA-q4w5-4gq2-98vm
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix tests/lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 09:39:56 -04:00
Michael Crenshaw
17f7f4f462 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 tests

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

fix tests/lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 09:39:01 -04:00
Michael Crenshaw
8bc3ef690d Merge pull request from GHSA-h4w9-6x78-8vrj
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

fix tests/lint

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-21 09:36:38 -04:00
Michael Crenshaw
8fe9a58c21 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>
2022-06-14 16:12:12 -04:00
Leonardo Luz Almeida
269c61a9c8 chore: Implement tests to validate aws auth retry (#9627)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-06-14 10:11:38 -04:00
Leonardo Luz Almeida
9a08c123f9 chore: Implement a retry in aws auth command (#9618)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-06-14 10:10:43 -04:00
jannfis
971f0f1ff1 test: Remove temp directories from repo server tests (#9501)
Signed-off-by: jannfis <jann@mistrust.net>
2022-06-13 15:42:29 -04:00
jannfis
1ae2f97b05 test: Make context tests idempodent (#9502)
Signed-off-by: jannfis <jann@mistrust.net>
2022-06-13 15:41:55 -04:00
Michael Crenshaw
bb26cc207b test: fix plugin var test for OSX (#9590)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-13 15:37:00 -04:00
Christian Hernandez
77d3dcdc62 Update Generators-Git.md (#9632)
Document how to deploy from the root of the git repository

Signed-off-by: Christian Hernandez <christian@codefresh.io>
2022-06-13 10:57:28 -04:00
Hari Sekhon
f414a8e985 docs: added environment variables documentation (#8680)
* added environment variables page

Signed-off-by: Hari Sekhon <harisekhon@gmail.com>

* added Environment Variables page to User Guide

Signed-off-by: Hari Sekhon <harisekhon@gmail.com>

* reformatted table cells as multiline for clarity

Signed-off-by: Hari Sekhon <harisekhon@gmail.com>

* fixed typo

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-13 10:38:39 -04:00
argo-bot
91aefabc5b Bump version to 2.4.0 2022-06-10 17:13:43 +00:00
argo-bot
56b8e2f356 Bump version to 2.4.0 2022-06-10 17:13:30 +00:00
Michael Crenshaw
101477a638 docs: document OpenSSH upgrade (#9598) (#9615)
docs: document OpenSSH upgrade (#9598) (#9615)

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-09 15:59:59 -07:00
Alexander Matyushentsev
9bf7d1b95b fix: change repo-server command to expand 'ARGOCD_REDIS_SERVICE' env variable (#9628)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-06-09 15:59:54 -07:00
Daniel Helfand
da8e7b9697 fix: use serviceaccount name instead of struct (#9614) (#9617)
* fix: use serviceaccount name instead of struct

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

* fix: change name of param from sa to serviceAccount

Signed-off-by: Daniel Helfand <helfand.4@gmail.com>
2022-06-08 16:20:29 -04:00
Daniel Helfand
eb183dcde1 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-06-08 14:01:25 -04:00
Michael Crenshaw
ccecc693c2 docs: document argocd cluster add behavior for 1.24 clusters (#9611)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-08 13:54:38 -04:00
Yaakov Selkowitz
dc1d4b060d chore: Fix working directory for remote e2e test image (#9600)
Commit cc6c625401 changed a RUN mkdir
command into a WORKDIR, which also affected the entrypoint.  This
triggered an error in goreman which looks for Procfile (which is
installed here in the root directory) in the working directory.

Since COPY creates any missing directories in the destination path,
there is no need for a separate step to create it.  This change leaves
WORKDIR as the default (the root directory) as before.

Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
2022-06-07 17:31:33 +00:00
Michael Crenshaw
512233806c chore: fix long socket path breaking test on osx (#9391)
* chore: fix long socket path breaking test on osx

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

* comment

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

* simplify

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

* simplify

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-06 17:48:42 -04:00
argo-bot
b84dd8bbfa Bump version to 2.4.0-rc5 2022-06-06 19:03:38 +00:00
argo-bot
e6f37d7245 Bump version to 2.4.0-rc5 2022-06-06 19:03:30 +00:00
Michael Crenshaw
57bac9ac75 chore: update changelog
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-06 14:59:46 -04:00
34FathomBelow
3034183791 chore: upgrade base image to ubuntu:20.04 (#9551)
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>
2022-06-06 14:52:10 -04:00
34FathomBelow
26c87b3f16 chore upgrade base image for test containers Ubuntu:22.04 (#9563)
Signed-off-by: Justin Marquis <34fathombelow@protonmail.com>
2022-06-06 14:52:02 -04:00
34FathomBelow
bd8d26d444 chore: update Kex-Algorithms (#9561)
* chore: update Kex-Algorithms

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

* sorted kex-algorithms

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

Co-authored-by: douhunt <douhunt@protonmail.com>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-06 14:51:54 -04:00
Michael Crenshaw
a6c58748cd 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-04 20:17:12 -04:00
Bjorn Stange
46af59e258 docs: fix cm typo (#9577)
Signed-off-by: Bjorn Stange <bjorn.stange@expel.io>
2022-06-03 13:21:08 -04:00
Alexander Matyushentsev
867660a709 chore: remove obsolete repo-server unit test (#9559)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-06-03 09:30:57 -04:00
margueritepd
b1addf5bf1 docs: document action RBAC action and application resource path (#8413)
Signed-off-by: Marguerite des Trois Maisons <marguerite+github@pagerduty.com>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-02 17:51:08 -04:00
Pierre Crégut
0a9d1607e2 feat: Add plugin call variables to sidecar plugin discovery (#9273) (#9319)
* fix: do not export repo-server environment to sidecar (#9393)

getPluginEnvs is both used for local plugins and sidecar plugins. For the later
do not include the environement variables of the repo-server in the supplied
variables.

Fixes: #9393
Signed-off-by: Pierre Crégut <pierre.cregut@orange.com>

* feat: Add plugin call variables to sidecar plugin discovery (#9273)

Gives access to variables declared in the call of the plugin in the application
manifest to the discover command run on the CMP server.

Variables are prefixed with ARGOCD_ENV_ to avoid security issues (plugin call
overiding important variables).

Fixes #9273

Signed-off-by: Pierre Crégut <pierre.cregut@orange.com>
2022-06-02 17:50:29 -04:00
Michael Crenshaw
09fc32e6cb docs: document plugin prefixed env vars (#9548)
* docs: document plugin prefixed env vars

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

* restructure, clarify env vars from main container behavior

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

* grammer

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

* grammer

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

* no link - the cert is bad

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

* fixes

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-06-02 15:46:50 -04:00
argo-bot
1be9296e6c Bump version to 2.4.0-rc4 2022-06-01 22:49:24 +00:00
argo-bot
76fad02f4a Bump version to 2.4.0-rc4 2022-06-01 22:49:15 +00:00
Alexander Matyushentsev
2f8eb04b84 fix: web terminal due to query parameters name mismatch (#9560)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-06-01 14:39:32 -07:00
argo-bot
66aa0e6e01 Bump version to 2.4.0-rc3 2022-05-31 19:24:04 +00:00
argo-bot
955270eb0d Bump version to 2.4.0-rc3 2022-05-31 19:23:57 +00:00
Michael Crenshaw
225a0af9f7 docs: security warning for plugins (#9547)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-31 11:49:36 -07:00
Leonardo Luz Almeida
5191cd077c chore: Improve application logs adding message context (#9435)
* chore: Improve application logs adding message context

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

* fix bug returning error incorrectly

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

* Fix unit-test and avoid api breaking change

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

* Fix test

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

* Fix e2e test

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

* Fix e2e test

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

* small fix

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

* Address review comments

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-05-31 14:19:02 -04:00
Leonardo Luz Almeida
c6b928c830 fix: Ignore diff with schema (#9170) 2022-05-31 10:27:32 -07:00
Michael Crenshaw
4e73b3c7ee docs: document new repo-server ServiceAccount (#9484)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-31 12:28:38 -04:00
Michael Crenshaw
708c9e79b9 fix: avoid k8s call before authorization for terminal endpoint (#9434)
* fix: avoid k8s API call before authorization in k8s endpoint

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

* check for bad project

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

* lint

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

* more logging

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

* handle 404, return 500 instead of 400 for other errors

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

* use user input

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

* refactor validation

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

* fix tests

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

* fixes, tests

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-31 12:18:25 -04:00
ls0f
da2c249814 receiveFile memory optimization: do not use bytes.buffer but write directly to file (#9415)
Signed-off-by: ls0f <lovedboy.tk@qq.com>
2022-05-31 12:17:39 -04:00
smcavallo
c27cf3f95e feat: support pod exec terminal logging (#9385)
* feat: support pod exec terminal logging
Signed-off-by: smcavallo <smcavallo@hotmail.com>

* enhanced validation and logging when resource not found
Signed-off-by: smcavallo <smcavallo@hotmail.com>

* fix lint
Signed-off-by: smcavallo <smcavallo@hotmail.com>

* log warning when pod or container not found
Signed-off-by: smcavallo <smcavallo@hotmail.com>

* go/log-injection fixes
Signed-off-by: smcavallo <smcavallo@hotmail.com>

* log levels and lowercase message
Signed-off-by: smcavallo <smcavallo@hotmail.com>
2022-05-31 12:17:01 -04:00
Daniel Helfand
dbd3ce3133 docs: add applicationset and notifications controllers to running locally instructions (#9517)
Signed-off-by: Daniel Helfand <helfand.4@gmail.com>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-31 12:11:53 -04:00
Pavel Savchenko
58062c45de docs: Update 2.3 notes - mention helm chart (#9512)
the helm chart values should be copied as-is into the `notifications` section of the argo-cd chart

Signed-off-by: Pavel Savchenko <asfaltboy@gmail.com>
2022-05-31 12:11:35 -04:00
reggie-k
3c61070411 docs: logs RBAC known UI issue section (#9479)
* updated changelog and upgrade instructions to contain know UI issue with logs rbac

Signed-off-by: reggie-k <reginakagan@gmail.com>

* updated changelog and upgrade instructions to contain know UI issue with logs rbac

Signed-off-by: reggie-k <reginakagan@gmail.com>
2022-05-31 12:11:09 -04:00
Michael Crenshaw
697fc77379 docs: more appset security docs (#9466)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-31 12:10:40 -04:00
Michael Crenshaw
6655a22b0a docs: plugins need their own writeable tmp volume (#9389)
* docs: plugin needs temp dir

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

* revert temp changes

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

* fix version number

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

* update upgrade instructions

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

* simplify

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-31 12:07:56 -04:00
Michael Crenshaw
0d109279a8 docs: fix PR generators list (#9387)
* docs: fix PR generators list

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

* grammar

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-31 12:07:32 -04:00
neosu
4c1e1e0ad6 Fixes: #9364 (#9367)
In the #8929, the project parameter had changed to projects.

5f5d7aa59b/server/application/application.proto (L23)
Signed-off-by: neosu <neo@neobaran.com>
2022-05-30 19:19:27 -07:00
Michael Crenshaw
078cfe130b fix: test race (#9469)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-24 08:15:41 -07:00
Michael Crenshaw
cd098638f8 fix: lint (#9444)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-24 08:15:27 -07:00
Dan Garfield
2826a9215d refactor: Update notification engine (#9386)
refactor: Update notification engine  (#9386)

Signed-off-by: todaywasawesome <dan@codefresh.io>
2022-05-23 23:50:45 -07:00
Alexander Matyushentsev
13bef3a831 fix: api server should dynamically enabled terminal handler (#9497)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-05-23 23:49:56 -07:00
Alexander Matyushentsev
c6f80377a8 fix: Undefined cluster in UI when app is referencing cluster by name (#9493)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-05-23 22:52:34 -07:00
Alexander Matyushentsev
a8a451a84b fix: make more proto fields optional (#9490)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-05-23 13:46:15 -07:00
argo-bot
cd5b2af358 Bump version to 2.4.0-rc2 2022-05-18 12:32:45 +00:00
argo-bot
f6f9fa2cd6 Bump version to 2.4.0-rc2 2022-05-18 12:32:41 +00:00
jannfis
c7749ca67e 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:22 +02:00
Michael Crenshaw
3399a81bed 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: 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
80e5c55ca0 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
Saumeya Katyal
c4182aedc7 fix: update filter combo-box icon color (#9416)
Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2022-05-16 14:26:56 +00:00
Saumeya Katyal
e4404372af fix: favorite icon and overlapping app title (#9130)
Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2022-05-16 14:26:35 +00:00
Leonardo Luz Almeida
12140f8152 chore: Improve otel grpc traces adding span correlation (#9371)
* chore: Improve otel grpc traces adding span correlation

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

* Create a tracer for argocd controller

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

* Update controller command doc

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

* Instrument cmp-client

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

* Add otlp config as part of configmaps

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

* update manifests

Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-05-13 15:13:43 -04:00
Chetan Banavikalmutt
6cfd394445 fix: ListResourceActions() returns duplicate actions (#9360)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2022-05-13 15:09:33 -04:00
Michael Crenshaw
1998b016c0 docs: clarify Role/ClusterRole uses for exec feature (#9354)
* docs: clarify Role/ClusterRole uses for exec feature

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

* fix missed `get`s

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-12 11:14:10 -04:00
Michael Crenshaw
74bc1731f9 feat(manifests): Add service account for repo server (#9301) (#9355)
Signed-off-by: Hao Xin <haoxinst@gmail.com>
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

Co-authored-by: Hao Xin <haoxinst@qq.com>
2022-05-11 13:28:13 -04:00
Michael Crenshaw
bb28b3c697 docs: logs RBAC upgrate notes (#9345) (#9356)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-05-10 20:38:25 -04:00
Regina Scott
0ee9993369 fix: grouped node titles no longer wrap (#9340)
Signed-off-by: Regina Scott <rescott@redhat.com>
2022-05-09 19:34:14 -04:00
argo-bot
d8f845a126 Bump version to 2.4.0-rc1 2022-05-06 23:10:53 +00:00
argo-bot
5901b46785 Bump version to 2.4.0-rc1 2022-05-06 23:10:45 +00:00
David J. M. Karlsen
88542a616f feat: Add cli support for additional linux based architectures, s390x + ppc64le (#8991)
feat: Add cli support for additional linux based architectures, s390x + ppc64le (#8991)

Signed-off-by: David J. M. Karlsen <david@davidkarlsen.com>

* add more architectures for linux

Signed-off-by: David J. M. Karlsen <david@davidkarlsen.com>

* drop aix arch as it won't compile

Signed-off-by: David J. M. Karlsen <david@davidkarlsen.com>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-05-06 16:10:03 -07:00
Alexander Matyushentsev
cbe4f1b92e chore: add linux/s390x,linux/ppc64le platforms to release workflow (#9324)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-05-06 16:09:59 -07:00
244 changed files with 18066 additions and 1383 deletions

View File

@@ -202,7 +202,7 @@ jobs:
set -ue
git clean -fd
mkdir -p dist/
docker buildx build --platform linux/amd64,linux/arm64 --push -t ${IMAGE_NAMESPACE}/argocd:v${TARGET_VERSION} -t argoproj/argocd:v${TARGET_VERSION} .
docker buildx build --platform linux/amd64,linux/arm64,linux/s390x,linux/ppc64le --push -t ${IMAGE_NAMESPACE}/argocd:v${TARGET_VERSION} -t argoproj/argocd:v${TARGET_VERSION} .
make release-cli
make checksums
chmod +x ./dist/argocd-linux-amd64

View File

@@ -2,28 +2,32 @@
## v2.4.0 (Unreleased)
### Web Terminal In Argo CD UI
### Web Terminal In Argo CD UI
Feature enables engineers to start a shell in the running application container without leaving the web interface. Just find the required Kubernetes
Pod using the Application Details page, click on it and select the Terminal tab. The shell starts automatically and enables you to execute the required
commands, and helps to troubleshoot the application state.
### Access Control For Pod Logs & Web Terminal
### Access Control For Pod Logs & Web Terminal
Argo CD is used to manage the critical infrastructure of multiple organizations, which makes security the top priority of the project. We've listened to
your feedback and introduced additional access control settings that control access to Kubernetes Pod logs and the new Web Terminal feature.
#### Known UI Issue for Pod Logs Access
Currently, upon pressing the "LOGS" tab in pod view by users who don't have an explicit allow get logs policy, the red "unable to load data: Internal error" is received in the bottom of the screen, and "Failed to load data, please try again" is displayed.
### OpenTelemetry Tracing Integration
The new feature allows emitting richer telemetry data that might make identifying performance bottlenecks easier. The new feature is available for argocd-server
and argocd-repo-server components and can be enabled using the --otlp-address flag.
### Power PC and IBM Z Support
### Power PC and IBM Z Support
The list of supported architectures has been expanded, and now includes IBM Z (s390x) and PowerPC (ppc64le). Starting with the v2.4 release the official quay.io
repository is going to have images for amd64, arm64, ppc64le, and s390x architectures.
### Other Notable Changes
### Other Notable Changes
Overall v2.4 release includes more than 300 hundred commits from nearly 90 contributors. Here is a short sample of the contributions:

View File

@@ -1,4 +1,4 @@
ARG BASE_IMAGE=docker.io/library/ubuntu:21.10
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
@@ -63,7 +63,7 @@ RUN ln -s /usr/local/bin/entrypoint.sh /usr/local/bin/uid_entrypoint.sh
# support for mounting configuration from a configmap
WORKDIR /app/config/ssh
RUN touch ssh_known_hosts && \
ln -s ssh_known_hosts /etc/ssh/ssh_known_hosts
ln -s /app/config/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts
WORKDIR /app/config
RUN mkdir -p tls && \
@@ -127,4 +127,4 @@ RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server && \
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-applicationset-controller && \
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-k8s-auth
USER 999
USER 999

View File

@@ -234,6 +234,8 @@ release-cli: clean-debug build-ui
make BIN_NAME=argocd-darwin-arm64 GOOS=darwin GOARCH=arm64 argocd-all
make BIN_NAME=argocd-linux-amd64 GOOS=linux argocd-all
make BIN_NAME=argocd-linux-arm64 GOOS=linux GOARCH=arm64 argocd-all
make BIN_NAME=argocd-linux-ppc64le GOOS=linux GOARCH=ppc64le argocd-all
make BIN_NAME=argocd-linux-s390x GOOS=linux GOARCH=s390x argocd-all
make BIN_NAME=argocd-windows-amd64.exe GOOS=windows argocd-all
.PHONY: test-tools-image
@@ -566,4 +568,4 @@ applicationset-controller:
.PHONY: checksums
checksums:
for f in ./dist/$(BIN_NAME)-*; do openssl dgst -sha256 "$$f" | awk ' { print $$2 }' > "$$f".sha256 ; done
for f in ./dist/$(BIN_NAME)-*; do openssl dgst -sha256 "$$f" | awk ' { print $$2 }' > "$$f".sha256 ; done

View File

@@ -1,12 +1,12 @@
controller: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
api-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_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 $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} "
controller: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --otlp-address=${ARGOCD_OTLP_ADDRESS}"
api-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_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 $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS}"
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:7.0.0-alpine --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi"
repo-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_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} $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
cmp-server: [ "$ARGOCD_E2E_TEST" == 'true' ] && exit 0 || [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-cmp-server ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} $COMMAND --config-dir-path ./test/cmp --loglevel debug"
repo-server: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_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} $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --otlp-address=${ARGOCD_OTLP_ADDRESS}"
cmp-server: [ "$ARGOCD_E2E_TEST" == 'true' ] && exit 0 || [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-cmp-server ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} $COMMAND --config-dir-path ./test/cmp --loglevel debug --otlp-address=${ARGOCD_OTLP_ADDRESS}"
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
dev-mounter: [[ "$ARGOCD_E2E_TEST" != "true" ]] && go run hack/dev-mounter/main.go --configmap argocd-ssh-known-hosts-cm=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} --configmap argocd-tls-certs-cm=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} --configmap argocd-gpg-keys-cm=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source}
applicationset-controller: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_ASK_PASS_SOCK=/tmp/applicationset-ask-pass.sock ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-applicationset-controller $COMMAND --loglevel debug --metrics-addr localhost:12345 --probe-addr localhost:12346 --argocd-repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
notification: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications $COMMAND --loglevel debug"
notification: [ "$BIN_MODE" == 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications $COMMAND --loglevel debug"

View File

@@ -37,6 +37,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Chargetrip](https://chargetrip.com)
1. [Chime](https://www.chime.com)
1. [Cisco ET&I](https://eti.cisco.com/)
1. [Cobalt](https://www.cobalt.io/)
1. [Codefresh](https://www.codefresh.io/)
1. [Codility](https://www.codility.com/)
1. [Commonbond](https://commonbond.co/)

View File

@@ -1 +1 @@
2.4.0
2.4.6

View File

@@ -166,7 +166,7 @@ func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoappsetv1
}
// santize the name in accordance with the below rules
// sanitize the name in accordance with the below rules
// 1. contain no more than 253 characters
// 2. contain only lowercase alphanumeric characters, '-' or '.'
// 3. start and end with an alphanumeric character

View File

@@ -162,8 +162,10 @@ func (g *GitGenerator) generateParamsFromGitFile(filePath string, fileContent []
}
params["path"] = path.Dir(filePath)
params["path.basename"] = path.Base(params["path"])
params["path.filename"] = path.Base(filePath)
params["path.basenameNormalized"] = sanitizeName(path.Base(params["path"]))
for k, v := range strings.Split(strings.TrimSuffix(params["path"], params["path.basename"]), "/") {
params["path.filenameNormalized"] = sanitizeName(path.Base(params["path.filename"]))
for k, v := range strings.Split(params["path"], "/") {
if len(v) > 0 {
params["path["+strconv.Itoa(k)+"]"] = v
}
@@ -213,7 +215,7 @@ func (g *GitGenerator) generateParamsFromApps(requestedApps []string, _ *argopro
params["path"] = a
params["path.basename"] = path.Base(a)
params["path.basenameNormalized"] = sanitizeName(path.Base(a))
for k, v := range strings.Split(strings.TrimSuffix(params["path"], params["path.basename"]), "/") {
for k, v := range strings.Split(params["path"], "/") {
if len(v) > 0 {
params["path["+strconv.Itoa(k)+"]"] = v
}

View File

@@ -47,6 +47,28 @@ func (a argoCDServiceMock) GetDirectories(ctx context.Context, repoURL string, r
return args.Get(0).([]string), args.Error(1)
}
func Test_generateParamsFromGitFile(t *testing.T) {
params, err := (*GitGenerator)(nil).generateParamsFromGitFile("path/dir/file_name.yaml", []byte(`
foo:
bar: baz
`))
if err != nil {
t.Fatal(err)
}
assert.Equal(t, []map[string]string{
{
"foo.bar": "baz",
"path": "path/dir",
"path.basename": "dir",
"path.filename": "file_name.yaml",
"path.basenameNormalized": "dir",
"path.filenameNormalized": "file-name.yaml",
"path[0]": "path",
"path[1]": "dir",
},
}, params)
}
func TestGitGenerateParamsFromDirectories(t *testing.T) {
cases := []struct {
@@ -68,9 +90,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
},
repoError: nil,
expected: []map[string]string{
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
{"path": "app_3", "path.basename": "app_3", "path.basenameNormalized": "app-3"},
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1"},
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2", "path[0]": "app2"},
{"path": "app_3", "path.basename": "app_3", "path.basenameNormalized": "app-3", "path[0]": "app_3"},
},
expectedError: nil,
},
@@ -85,8 +107,8 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
},
repoError: nil,
expected: []map[string]string{
{"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path.basenameNormalized": "app2"},
{"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path.basenameNormalized": "app3"},
{"path": "p1/app2", "path.basename": "app2", "path[0]": "p1", "path[1]": "app2", "path.basenameNormalized": "app2"},
{"path": "p1/p2/app3", "path.basename": "app3", "path[0]": "p1", "path[1]": "p2", "path[2]": "app3", "path.basenameNormalized": "app3"},
},
expectedError: nil,
},
@@ -102,9 +124,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
},
repoError: nil,
expected: []map[string]string{
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path.basenameNormalized": "app3"},
{"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"},
{"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"},
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"},
},
expectedError: nil,
},
@@ -120,9 +142,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) {
},
repoError: nil,
expected: []map[string]string{
{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1"},
{"path": "app2", "path.basename": "app2", "path.basenameNormalized": "app2"},
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path.basenameNormalized": "app3"},
{"path": "app1", "path.basename": "app1", "path[0]": "app1", "path.basenameNormalized": "app1"},
{"path": "app2", "path.basename": "app2", "path[0]": "app2", "path.basenameNormalized": "app2"},
{"path": "p2/app3", "path.basename": "app3", "path[0]": "p2", "path[1]": "app3", "path.basenameNormalized": "app3"},
},
expectedError: nil,
},
@@ -238,7 +260,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
"path": "cluster-config/production",
"path.basename": "production",
"path[0]": "cluster-config",
"path[1]": "production",
"path.basenameNormalized": "production",
"path.filename": "config.json",
"path.filenameNormalized": "config.json",
},
{
"cluster.owner": "foo.bar@example.com",
@@ -247,7 +272,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
"path": "cluster-config/staging",
"path.basename": "staging",
"path[0]": "cluster-config",
"path[1]": "staging",
"path.basenameNormalized": "staging",
"path.filename": "config.json",
"path.filenameNormalized": "config.json",
},
},
expectedError: nil,
@@ -305,7 +333,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
"path": "cluster-config/production",
"path.basename": "production",
"path[0]": "cluster-config",
"path[1]": "production",
"path.basenameNormalized": "production",
"path.filename": "config.json",
"path.filenameNormalized": "config.json",
},
{
"cluster.owner": "john.doe@example.com",
@@ -314,7 +345,10 @@ func TestGitGenerateParamsFromFiles(t *testing.T) {
"path": "cluster-config/production",
"path.basename": "production",
"path[0]": "cluster-config",
"path[1]": "production",
"path.basenameNormalized": "production",
"path.filename": "config.json",
"path.filenameNormalized": "config.json",
},
},
expectedError: nil,
@@ -353,7 +387,10 @@ cluster:
"path": "cluster-config/production",
"path.basename": "production",
"path[0]": "cluster-config",
"path[1]": "production",
"path.basenameNormalized": "production",
"path.filename": "config.yaml",
"path.filenameNormalized": "config.yaml",
},
{
"cluster.owner": "foo.bar@example.com",
@@ -362,7 +399,10 @@ cluster:
"path": "cluster-config/staging",
"path.basename": "staging",
"path[0]": "cluster-config",
"path[1]": "staging",
"path.basenameNormalized": "staging",
"path.filename": "config.yaml",
"path.filenameNormalized": "config.yaml",
},
},
expectedError: nil,
@@ -393,7 +433,10 @@ cluster:
"path": "cluster-config/production",
"path.basename": "production",
"path[0]": "cluster-config",
"path[1]": "production",
"path.basenameNormalized": "production",
"path.filename": "config.yaml",
"path.filenameNormalized": "config.yaml",
},
{
"cluster.owner": "john.doe@example.com",
@@ -402,7 +445,10 @@ cluster:
"path": "cluster-config/production",
"path.basename": "production",
"path[0]": "cluster-config",
"path[1]": "production",
"path.basenameNormalized": "production",
"path.filename": "config.yaml",
"path.filenameNormalized": "config.yaml",
},
},
expectedError: nil,

View File

@@ -1,7 +1,7 @@
# Built-in policy which defines two roles: role:readonly and role:admin,
# and additionally assigns the admin user to the role:admin role.
# There are two policy formats:
# 1. Applications (which belong to a project):
# 1. Applications, logs, and exec (which belong to a project):
# p, <user/group>, <resource>, <action>, <project>/<object>
# 2. All other resources:
# p, <user/group>, <resource>, <action>, <object>
1 # Built-in policy which defines two roles: role:readonly and role:admin,
2 # and additionally assigns the admin user to the role:admin role.
3 # There are two policy formats:
4 # 1. Applications (which belong to a project): # 1. Applications, logs, and exec (which belong to a project):
5 # p, <user/group>, <resource>, <action>, <project>/<object>
6 # 2. All other resources:
7 # p, <user/group>, <resource>, <action>, <object>

View File

@@ -28,6 +28,7 @@ import (
kubeutil "github.com/argoproj/argo-cd/v2/util/kube"
"github.com/argoproj/argo-cd/v2/util/settings"
"github.com/argoproj/argo-cd/v2/util/tls"
"github.com/argoproj/argo-cd/v2/util/trace"
)
const (
@@ -58,6 +59,7 @@ func NewCommand() *cobra.Command {
redisClient *redis.Client
repoServerPlaintext bool
repoServerStrictTLS bool
otlpAddress string
)
var command = cobra.Command{
Use: cliName,
@@ -149,6 +151,14 @@ func NewCommand() *cobra.Command {
stats.StartStatsTicker(10 * time.Minute)
stats.RegisterHeapDumper("memprofile")
if otlpAddress != "" {
closeTracer, err := trace.InitTracer(ctx, "argocd-controller", otlpAddress)
if err != nil {
log.Fatalf("failed to initialize tracing: %v", err)
}
defer closeTracer()
}
go appController.Run(ctx, statusProcessors, operationProcessors)
// Wait forever
@@ -173,6 +183,7 @@ func NewCommand() *cobra.Command {
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")
command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to")
cacheSrc = appstatecache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {
redisClient = client
})

View File

@@ -1,6 +1,7 @@
package commands
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
@@ -40,16 +41,7 @@ func newAWSCommand() *cobra.Command {
var command = &cobra.Command{
Use: "aws",
Run: func(c *cobra.Command, args []string) {
sess, err := session.NewSession()
errors.CheckError(err)
stsAPI := sts.New(sess)
if roleARN != "" {
creds := stscreds.NewCredentials(sess, roleARN)
stsAPI = sts.New(sess, &aws.Config{Credentials: creds})
}
request, _ := stsAPI.GetCallerIdentityRequest(&sts.GetCallerIdentityInput{})
request.HTTPRequest.Header.Add(clusterIDHeader, clusterName)
presignedURLString, err := request.Presign(requestPresignParam)
presignedURLString, err := getSignedRequestWithRetry(time.Minute, 5*time.Second, clusterName, roleARN, getSignedRequest)
errors.CheckError(err)
token := v1Prefix + base64.RawURLEncoding.EncodeToString([]byte(presignedURLString))
// Set token expiration to 1 minute before the presigned URL expires for some cushion
@@ -62,6 +54,43 @@ func newAWSCommand() *cobra.Command {
return command
}
type getSignedRequestFunc func(clusterName, roleARN string) (string, error)
func getSignedRequestWithRetry(timeout, interval time.Duration, clusterName, roleARN string, fn getSignedRequestFunc) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
for {
signed, err := fn(clusterName, roleARN)
if err == nil {
return signed, nil
}
select {
case <-ctx.Done():
return "", fmt.Errorf("timeout while trying to get signed aws request: last error: %s", err)
case <-time.After(interval):
}
}
}
func getSignedRequest(clusterName, roleARN string) (string, error) {
sess, err := session.NewSession()
if err != nil {
return "", fmt.Errorf("error creating new AWS session: %s", err)
}
stsAPI := sts.New(sess)
if roleARN != "" {
creds := stscreds.NewCredentials(sess, roleARN)
stsAPI = sts.New(sess, &aws.Config{Credentials: creds})
}
request, _ := stsAPI.GetCallerIdentityRequest(&sts.GetCallerIdentityInput{})
request.HTTPRequest.Header.Add(clusterIDHeader, clusterName)
signed, err := request.Presign(requestPresignParam)
if err != nil {
return "", fmt.Errorf("error presigning AWS request: %s", err)
}
return signed, nil
}
func formatJSON(token string, expiration time.Time) string {
expirationTimestamp := metav1.NewTime(expiration)
execInput := &clientauthv1beta1.ExecCredential{

View File

@@ -0,0 +1,73 @@
package commands
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestGetSignedRequestWithRetry(t *testing.T) {
t.Run("will return signed request on first attempt", func(t *testing.T) {
// given
t.Parallel()
mock := &signedRequestMock{
returnFunc: func(m *signedRequestMock) (string, error) {
return "token", nil
},
}
// when
signed, err := getSignedRequestWithRetry(time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock)
// then
assert.NoError(t, err)
assert.Equal(t, "token", signed)
})
t.Run("will return signed request on third attempt", func(t *testing.T) {
// given
t.Parallel()
mock := &signedRequestMock{
returnFunc: func(m *signedRequestMock) (string, error) {
if m.getSignedRequestCalls < 3 {
return "", fmt.Errorf("some error")
}
return "token", nil
},
}
// when
signed, err := getSignedRequestWithRetry(time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock)
// then
assert.NoError(t, err)
assert.Equal(t, "token", signed)
})
t.Run("will return error on timeout", func(t *testing.T) {
// given
t.Parallel()
mock := &signedRequestMock{
returnFunc: func(m *signedRequestMock) (string, error) {
return "", fmt.Errorf("some error")
},
}
// when
signed, err := getSignedRequestWithRetry(time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock)
// then
assert.Error(t, err)
assert.Equal(t, "", signed)
})
}
type signedRequestMock struct {
getSignedRequestCalls int
returnFunc func(m *signedRequestMock) (string, error)
}
func (m *signedRequestMock) getSignedRequestMock(clusterName, roleARN string) (string, error) {
m.getSignedRequestCalls++
return m.returnFunc(m)
}

View File

@@ -14,6 +14,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"
@@ -70,15 +71,17 @@ func getSubmoduleEnabled() bool {
func NewCommand() *cobra.Command {
var (
parallelismLimit int64
listenPort int
metricsPort int
otlpAddress string
cacheSrc func() (*reposervercache.Cache, error)
tlsConfigCustomizer tls.ConfigCustomizer
tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error)
redisClient *redis.Client
disableTLS bool
parallelismLimit int64
listenPort int
metricsPort int
otlpAddress string
cacheSrc func() (*reposervercache.Cache, error)
tlsConfigCustomizer tls.ConfigCustomizer
tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error)
redisClient *redis.Client
disableTLS bool
maxCombinedDirectoryManifestsSize string
cmpTarExcludedGlobs []string
)
var command = cobra.Command{
Use: cliName,
@@ -98,15 +101,20 @@ func NewCommand() *cobra.Command {
cache, err := cacheSrc()
errors.CheckError(err)
maxCombinedDirectoryManifestsQuantity, err := resource.ParseQuantity(maxCombinedDirectoryManifestsSize)
errors.CheckError(err)
askPassServer := askpass.NewServer()
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(),
SubmoduleEnabled: getSubmoduleEnabled(),
MaxCombinedDirectoryManifestsSize: maxCombinedDirectoryManifestsQuantity,
CMPTarExcludedGlobs: cmpTarExcludedGlobs,
}, askPassServer)
errors.CheckError(err)
@@ -182,6 +190,8 @@ func NewCommand() *cobra.Command {
command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortRepoServerMetrics, "Start metrics server on given port")
command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_REPO_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to")
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")
command.Flags().StringArrayVar(&cmpTarExcludedGlobs, "plugin-tar-exclude", env.StringsFromEnv("ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS", []string{}, ";"), "Globs to filter when sending tarballs to plugins.")
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {

View File

@@ -152,7 +152,10 @@ func NewCommand() *cobra.Command {
stats.RegisterStackDumper()
stats.StartStatsTicker(10 * time.Minute)
stats.RegisterHeapDumper("memprofile")
argocd := server.NewServer(context.Background(), argoCDOpts)
argocd.Init(context.Background())
lns, err := argocd.Listen()
errors.CheckError(err)
for {
var closer func()
ctx := context.Background()
@@ -163,8 +166,7 @@ func NewCommand() *cobra.Command {
log.Fatalf("failed to initialize tracing: %v", err)
}
}
argocd := server.NewServer(ctx, argoCDOpts)
argocd.Run(ctx, listenPort, metricsPort)
argocd.Run(ctx, lns)
cancel()
if closer != nil {
closer()

View File

@@ -88,6 +88,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) {
kubeClientset := kubefake.NewSimpleClientset(deployment, &cm)
clusterCache := clustermocks.ClusterCache{}
clusterCache.On("IsNamespaced", mock.Anything).Return(true, nil)
clusterCache.On("GetGVKParser", mock.Anything).Return(nil)
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(&argocdclient.ManifestResponse{
Manifests: []string{test.DeploymentManifest},

View File

@@ -609,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

@@ -25,6 +25,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"
@@ -778,7 +779,7 @@ func getLocalObjectsString(app *argoappv1.Application, local, localRepoRoot, app
ApiVersions: apiVersions,
Plugins: configManagementPlugins,
TrackingMethod: trackingMethod,
}, true, &git.NoopCredsStore{})
}, true, &git.NoopCredsStore{}, resource.MustParse("0"))
errors.CheckError(err)
return res.Manifests

View File

@@ -101,7 +101,7 @@ 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 {
isTerminal := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd())
@@ -115,7 +115,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
os.Exit(1)
}
}
managerBearerToken, err = clusterauth.InstallClusterManagerRBAC(clientset, clusterOpts.SystemNamespace, clusterOpts.Namespaces)
managerBearerToken, err = clusterauth.InstallClusterManagerRBAC(clientset, clusterOpts.SystemNamespace, clusterOpts.Namespaces, common.BearerTokenTimeout)
}
errors.CheckError(err)
}

View File

@@ -36,13 +36,13 @@ users:
- auth-token: vErrYS3c3tReFRe$hToken
name: localhost:8080`
const testConfigFilePath = "./testdata/config"
const testConfigFilePath = "./testdata/local.config"
func TestContextDelete(t *testing.T) {
// Write the test config file
err := ioutil.WriteFile(testConfigFilePath, []byte(testConfig), os.ModePerm)
assert.NoError(t, err)
defer os.Remove(testConfigFilePath)
err = os.Chmod(testConfigFilePath, 0600)
require.NoError(t, err, "Could not change the file permission to 0600 %v", err)
@@ -75,9 +75,4 @@ func TestContextDelete(t *testing.T) {
assert.NotContains(t, localConfig.Servers, localconfig.Server{PlainText: true, Server: "localhost:8080"})
assert.NotContains(t, localConfig.Users, localconfig.User{AuthToken: "vErrYS3c3tReFRe$hToken", Name: "localhost:8080"})
assert.Contains(t, localConfig.Contexts, localconfig.ContextRef{Name: "argocd2.example.com:443", Server: "argocd2.example.com:443", User: "argocd2.example.com:443"})
// Write the file again so that no conflicts are made in git
err = ioutil.WriteFile(testConfigFilePath, []byte(testConfig), os.ModePerm)
assert.NoError(t, err)
}

View File

@@ -215,8 +215,13 @@ func StartLocalServer(clientOpts *apiclient.ClientOptions, ctxStr string, port *
ListenHost: *address,
RepoClientset: &forwardRepoClientset{namespace: namespace, context: ctxStr},
})
srv.Init(ctx)
go srv.Run(ctx, *port, 0)
lns, err := srv.Listen()
if err != nil {
return err
}
go srv.Run(ctx, lns)
clientOpts.ServerAddr = fmt.Sprintf("%s:%d", *address, *port)
clientOpts.PlainText = true
if !cache2.WaitForCacheSync(ctx.Done(), srv.Initialized) {

View File

@@ -68,7 +68,8 @@ argocd login cd.argoproj.io --core`,
server = "kubernetes"
} else {
server = args[0]
tlsTestResult, err := grpc_util.TestTLS(server)
dialTime := 30 * time.Second
tlsTestResult, err := grpc_util.TestTLS(server, dialTime)
errors.CheckError(err)
if !tlsTestResult.TLS {
if !globalClientOpts.PlainText {
@@ -202,7 +203,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
@@ -212,7 +216,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[:])
@@ -296,7 +301,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

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient"
"github.com/argoproj/argo-cd/v2/util/localconfig"
@@ -16,6 +17,10 @@ func TestLogout(t *testing.T) {
// Write the test config file
err := ioutil.WriteFile(testConfigFilePath, []byte(testConfig), os.ModePerm)
assert.NoError(t, err)
defer os.Remove(testConfigFilePath)
err = os.Chmod(testConfigFilePath, 0600)
require.NoError(t, err)
localConfig, err := localconfig.ReadLocalConfig(testConfigFilePath)
assert.NoError(t, err)
@@ -32,9 +37,4 @@ func TestLogout(t *testing.T) {
assert.Contains(t, localConfig.Contexts, localconfig.ContextRef{Name: "argocd1.example.com:443", Server: "argocd1.example.com:443", User: "argocd1.example.com:443"})
assert.Contains(t, localConfig.Contexts, localconfig.ContextRef{Name: "argocd2.example.com:443", Server: "argocd2.example.com:443", User: "argocd2.example.com:443"})
assert.Contains(t, localConfig.Contexts, localconfig.ContextRef{Name: "localhost:8080", Server: "localhost:8080", User: "localhost:8080"})
// Write the file again so that no conflicts are made in git
err = ioutil.WriteFile(testConfigFilePath, []byte(testConfig), os.ModePerm)
assert.NoError(t, err)
}

View File

@@ -7,6 +7,7 @@ import (
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
@@ -46,6 +47,8 @@ func NewConnection(address string) (*grpc.ClientConn, error) {
grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...)),
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(unaryInterceptors...)),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),
}
dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))

View File

@@ -233,12 +233,12 @@ func (s *Service) MatchRepository(stream apiclient.ConfigManagementPluginService
}
}()
_, err = cmp.ReceiveRepoStream(bufferedCtx, stream, workDir)
metadata, err := cmp.ReceiveRepoStream(bufferedCtx, stream, workDir)
if err != nil {
return fmt.Errorf("match repository error receiving stream: %s", err)
}
isSupported, err := s.matchRepository(bufferedCtx, workDir)
isSupported, err := s.matchRepository(bufferedCtx, workDir, metadata.GetEnv())
if err != nil {
return fmt.Errorf("match repository error: %s", err)
}
@@ -251,7 +251,7 @@ func (s *Service) MatchRepository(stream apiclient.ConfigManagementPluginService
return nil
}
func (s *Service) matchRepository(ctx context.Context, workdir string) (bool, error) {
func (s *Service) matchRepository(ctx context.Context, workdir string, envEntries []*apiclient.EnvEntry) (bool, error) {
config := s.initConstants.PluginConfig
if config.Spec.Discover.FileName != "" {
log.Debugf("config.Spec.Discover.FileName is provided")
@@ -284,7 +284,9 @@ func (s *Service) matchRepository(ctx context.Context, workdir string) (bool, er
}
log.Debugf("Going to try runCommand.")
find, err := runCommand(ctx, config.Spec.Discover.Find.Command, workdir, os.Environ())
env := append(os.Environ(), environ(envEntries)...)
find, err := runCommand(ctx, config.Spec.Discover.Find.Command, workdir, env)
if err != nil {
return false, fmt.Errorf("error running find command: %s", err)
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/argoproj/argo-cd/v2/cmpserver/apiclient"
"github.com/argoproj/argo-cd/v2/test"
)
@@ -62,6 +63,7 @@ func TestMatchRepository(t *testing.T) {
type fixture struct {
service *Service
path string
env []*apiclient.EnvEntry
}
setup := func(t *testing.T, opts ...pluginOpt) *fixture {
t.Helper()
@@ -71,6 +73,7 @@ func TestMatchRepository(t *testing.T) {
return &fixture{
service: s,
path: path,
env: []*apiclient.EnvEntry{{Name: "ENV_VAR", Value: "1"}},
}
}
t.Run("will match plugin by filename", func(t *testing.T) {
@@ -81,7 +84,7 @@ func TestMatchRepository(t *testing.T) {
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path)
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
@@ -95,7 +98,7 @@ func TestMatchRepository(t *testing.T) {
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path)
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
@@ -111,7 +114,7 @@ func TestMatchRepository(t *testing.T) {
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path)
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
@@ -127,7 +130,7 @@ func TestMatchRepository(t *testing.T) {
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path)
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
@@ -145,7 +148,7 @@ func TestMatchRepository(t *testing.T) {
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path)
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
@@ -163,7 +166,44 @@ func TestMatchRepository(t *testing.T) {
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path)
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
assert.False(t, match)
})
t.Run("will match plugin because env var defined", func(t *testing.T) {
// given
d := Discover{
Find: Find{
Command: Command{
Command: []string{"sh", "-c", "echo -n $ENV_VAR"},
},
},
}
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
assert.True(t, match)
})
t.Run("will not match plugin because no env var defined", func(t *testing.T) {
// given
d := Discover{
Find: Find{
Command: Command{
// Use printf instead of echo since OSX prints the "-n" when there's no additional arg.
Command: []string{"sh", "-c", `printf "%s" "$ENV_NO_VAR"`},
},
},
}
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.NoError(t, err)
@@ -181,7 +221,7 @@ func TestMatchRepository(t *testing.T) {
f := setup(t, withDiscover(d))
// when
match, err := f.service.matchRepository(context.Background(), f.path)
match, err := f.service.matchRepository(context.Background(), f.path, f.env)
// then
assert.Error(t, err)

View File

@@ -2,12 +2,13 @@ package cmpserver
import (
"fmt"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"net"
"os"
"os/signal"
"syscall"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
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"
@@ -24,6 +25,7 @@ import (
"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"
"google.golang.org/grpc/keepalive"
)
// ArgoCDCMPServer is the config management plugin server implementation
@@ -61,6 +63,11 @@ func NewServer(initConstants plugin.CMPServerInitConstants) (*ArgoCDCMPServer, e
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(streamInterceptors...)),
grpc.MaxRecvMsgSize(apiclient.MaxGRPCMessageSize),
grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize),
grpc.KeepaliveEnforcementPolicy(
keepalive.EnforcementPolicy{
MinTime: common.GRPCKeepAliveEnforcementMinimum,
},
),
}
return &ArgoCDCMPServer{

View File

@@ -229,6 +229,12 @@ 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
@@ -280,3 +286,10 @@ const (
// AnnotationApplicationRefresh is an annotation that is added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconcilation.
AnnotationApplicationSetRefresh = "argocd.argoproj.io/application-set-refresh"
)
// gRPC settings
const (
GRPCKeepAliveEnforcementMinimum = 10 * time.Second
// Keep alive is 2x enforcement minimum to ensure network jitter does not introduce ENHANCE_YOUR_CALM errors
GRPCKeepAliveTime = 2 * GRPCKeepAliveEnforcementMinimum
)

View File

@@ -605,11 +605,16 @@ func (ctrl *ApplicationController) hideSecretData(app *appv1.Application, compar
return nil, fmt.Errorf("error getting tracking method: %s", err)
}
clusterCache, err := ctrl.stateCache.GetClusterCache(app.Spec.Destination.Server)
if err != nil {
return nil, fmt.Errorf("error getting cluster cache: %s", err)
}
diffConfig, err := argodiff.NewDiffConfigBuilder().
WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles).
WithTracking(appLabelKey, trackingMethod).
WithNoCache().
WithLogger(logutils.NewLogrusLogger(logutils.NewWithCurrentConfig())).
WithGVKParser(clusterCache.GetGVKParser()).
Build()
if err != nil {
return nil, fmt.Errorf("appcontroller error building diff config: %s", err)

View File

@@ -121,6 +121,7 @@ func newFakeController(data *fakeData) *ApplicationController {
clusterCacheMock := mocks.ClusterCache{}
clusterCacheMock.On("IsNamespaced", mock.Anything).Return(true, nil)
clusterCacheMock.On("GetOpenAPISchema").Return(nil, nil)
clusterCacheMock.On("GetGVKParser").Return(nil)
mockStateCache := mockstatecache.LiveStateCache{}
ctrl.appStateManager.(*appStateManager).liveStateCache = &mockStateCache

View File

@@ -176,6 +176,7 @@ func NewLiveStateCache(
type cacheSettings struct {
clusterSettings clustercache.Settings
appInstanceLabelKey string
trackingMethod appv1.TrackingMethod
}
type liveStateCache struct {
@@ -210,7 +211,7 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) {
ResourceHealthOverride: lua.ResourceHealthOverrides(resourceOverrides),
ResourcesFilter: resourcesFilter,
}
return &cacheSettings{clusterSettings, appInstanceLabelKey}, nil
return &cacheSettings{clusterSettings, appInstanceLabelKey, argo.GetTrackingMethod(c.settingsMgr)}, nil
}
func asResourceNode(r *clustercache.Resource) appv1.ResourceNode {
@@ -354,7 +355,8 @@ func isTransientNetworkErr(err error) bool {
}
if strings.Contains(errorString, "net/http: TLS handshake timeout") ||
strings.Contains(errorString, "i/o timeout") ||
strings.Contains(errorString, "connection timed out") {
strings.Contains(errorString, "connection timed out") ||
strings.Contains(errorString, "connection reset by peer") {
return true
}
return false
@@ -387,7 +389,6 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
return nil, fmt.Errorf("controller is configured to ignore cluster %s", cluster.Server)
}
trackingMethod := argo.GetTrackingMethod(c.settingsMgr)
clusterCacheOpts := []clustercache.UpdateSettingsFunc{
clustercache.SetListSemaphore(semaphore.NewWeighted(clusterCacheListSemaphoreSize)),
clustercache.SetListPageSize(clusterCacheListPageSize),
@@ -400,9 +401,12 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
clustercache.SetPopulateResourceInfoHandler(func(un *unstructured.Unstructured, isRoot bool) (interface{}, bool) {
res := &ResourceInfo{}
populateNodeInfo(un, res)
c.lock.RLock()
cacheSettings := c.cacheSettings
c.lock.RUnlock()
res.Health, _ = health.GetResourceHealth(un, cacheSettings.clusterSettings.ResourceHealthOverride)
appName := c.resourceTracking.GetAppName(un, cacheSettings.appInstanceLabelKey, trackingMethod)
appName := c.resourceTracking.GetAppName(un, cacheSettings.appInstanceLabelKey, cacheSettings.trackingMethod)
if isRoot && appName != "" {
res.AppName = appName
}

View File

@@ -111,6 +111,7 @@ func TestIsRetryableError(t *testing.T) {
tlsHandshakeTimeoutErr net.Error = netError("net/http: TLS handshake timeout")
ioTimeoutErr net.Error = netError("i/o timeout")
connectionTimedout net.Error = netError("connection timed out")
connectionReset net.Error = netError("connection reset by peer")
)
t.Run("Nil", func(t *testing.T) {
assert.False(t, isRetryableError(nil))
@@ -148,4 +149,7 @@ func TestIsRetryableError(t *testing.T) {
t.Run("ConnectionTimeout", func(t *testing.T) {
assert.True(t, isRetryableError(connectionTimedout))
})
t.Run("ConnectionReset", func(t *testing.T) {
assert.True(t, isRetryableError(connectionReset))
})
}

View File

@@ -461,7 +461,14 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
} else {
diffConfigBuilder.WithCache(m.cache, app.GetName())
}
// it necessary to ignore the error at this point to avoid creating duplicated
gvkParser, err := m.getGVKParser(app.Spec.Destination.Server)
if err != nil {
conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionUnknownError, Message: err.Error(), LastTransitionTime: &now})
}
diffConfigBuilder.WithGVKParser(gvkParser)
// it is necessary to ignore the error at this point to avoid creating duplicated
// application conditions as argo.StateDiffs will validate this diffConfig again.
diffConfig, _ := diffConfigBuilder.Build()
@@ -487,6 +494,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
}
gvk := obj.GroupVersionKind()
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, appLabelKey, trackingMethod)
resState := v1alpha1.ResourceStatus{
Namespace: obj.GetNamespace(),
Name: obj.GetName(),
@@ -494,7 +503,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
Version: gvk.Version,
Group: gvk.Group,
Hook: hookutil.IsHook(obj),
RequiresPruning: targetObj == nil && liveObj != nil,
RequiresPruning: targetObj == nil && liveObj != nil && isSelfReferencedObj,
}
var diffResult diff.DiffResult
@@ -503,8 +512,11 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap
} else {
diffResult = diff.DiffResult{Modified: false, NormalizedLive: []byte("{}"), PredictedLive: []byte("{}")}
}
if resState.Hook || ignore.Ignore(obj) || (targetObj != nil && hookutil.Skip(targetObj)) {
// For resource hooks or skipped resources, don't store sync status, and do not affect overall sync status
if resState.Hook || ignore.Ignore(obj) || (targetObj != nil && hookutil.Skip(targetObj)) || !isSelfReferencedObj {
// For resource hooks, skipped resources or objects that may have
// been created by another controller with annotations copied from
// the source object, don't store sync status, and do not affect
// overall sync status
} else if diffResult.Modified || targetObj == nil || liveObj == nil {
// Set resource state to OutOfSync since one of the following is true:
// * target and live resource are different
@@ -660,3 +672,33 @@ func NewAppStateManager(
resourceTracking: resourceTracking,
}
}
// isSelfReferencedObj returns whether the given obj is managed by the application
// according to the values in the tracking annotation. It returns true when all
// of the properties in the annotation (name, namespace, group and kind) match
// the properties of the inspected object, or if the tracking method used does
// not provide the required properties for matching.
func (m *appStateManager) isSelfReferencedObj(obj *unstructured.Unstructured, appLabelKey string, trackingMethod v1alpha1.TrackingMethod) bool {
if obj == nil {
return true
}
// If tracking method doesn't contain required metadata for this check,
// we are not able to determine and just assume the object to be managed.
if trackingMethod == argo.TrackingMethodLabel {
return true
}
// In order for us to assume obj to be managed by this application, the
// values from the annotation have to match the properties from the live
// object.
appInstance := m.resourceTracking.GetAppInstance(obj, appLabelKey, trackingMethod)
if appInstance != nil {
return obj.GetNamespace() == appInstance.Namespace &&
obj.GetName() == appInstance.Name &&
obj.GetObjectKind().GroupVersionKind().Group == appInstance.Group &&
obj.GetObjectKind().GroupVersionKind().Kind == appInstance.Kind
}
return true
}

View File

@@ -13,6 +13,7 @@ import (
. "github.com/argoproj/gitops-engine/pkg/utils/testing"
"github.com/stretchr/testify/assert"
v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
@@ -21,6 +22,7 @@ import (
argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/test"
"github.com/argoproj/argo-cd/v2/util/argo"
)
// TestCompareAppStateEmpty tests comparison when both git and live have no objects
@@ -770,3 +772,128 @@ func TestComparisonResult_GetSyncStatus(t *testing.T) {
assert.Equal(t, status, res.GetSyncStatus())
}
func TestIsLiveResourceManaged(t *testing.T) {
managedObj := kube.MustToUnstructured(&corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap1",
Namespace: "default",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:default/configmap1",
},
},
})
managedObjWithLabel := kube.MustToUnstructured(&corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap1",
Namespace: "default",
Labels: map[string]string{
common.LabelKeyAppInstance: "guestbook",
},
},
})
unmanagedObjWrongName := kube.MustToUnstructured(&corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap2",
Namespace: "default",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:default/configmap1",
},
},
})
unmanagedObjWrongKind := kube.MustToUnstructured(&corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap2",
Namespace: "default",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: "guestbook:/Service:default/configmap2",
},
},
})
unmanagedObjWrongGroup := kube.MustToUnstructured(&corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap2",
Namespace: "default",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: "guestbook:apps/ConfigMap:default/configmap2",
},
},
})
unmanagedObjWrongNamespace := kube.MustToUnstructured(&corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap2",
Namespace: "default",
Annotations: map[string]string{
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:fakens/configmap2",
},
},
})
ctrl := newFakeController(&fakeData{
apps: []runtime.Object{app, &defaultProj},
manifestResponse: &apiclient.ManifestResponse{
Manifests: []string{},
Namespace: test.FakeDestNamespace,
Server: test.FakeClusterURL,
Revision: "abc123",
},
managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{
kube.GetResourceKey(managedObj): managedObj,
kube.GetResourceKey(unmanagedObjWrongName): unmanagedObjWrongName,
kube.GetResourceKey(unmanagedObjWrongKind): unmanagedObjWrongKind,
kube.GetResourceKey(unmanagedObjWrongGroup): unmanagedObjWrongGroup,
kube.GetResourceKey(unmanagedObjWrongNamespace): unmanagedObjWrongNamespace,
},
})
manager := ctrl.appStateManager.(*appStateManager)
// Managed resource w/ annotations
assert.True(t, manager.isSelfReferencedObj(managedObj, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
assert.True(t, manager.isSelfReferencedObj(managedObj, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
// Managed resource w/ label
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
// Wrong resource name
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
// Wrong resource group
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
// Wrong resource kind
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
// Wrong resource namespace
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotationAndLabel))
// Nil resource
assert.True(t, manager.isSelfReferencedObj(nil, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation))
}

View File

@@ -17,6 +17,7 @@ import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/managedfields"
"k8s.io/kubectl/pkg/util/openapi"
cdcommon "github.com/argoproj/argo-cd/v2/common"
@@ -46,6 +47,14 @@ func (m *appStateManager) getOpenAPISchema(server string) (openapi.Resources, er
return cluster.GetOpenAPISchema(), nil
}
func (m *appStateManager) getGVKParser(server string) (*managedfields.GvkParser, error) {
cluster, err := m.liveStateCache.GetClusterCache(server)
if err != nil {
return nil, err
}
return cluster.GetGVKParser(), nil
}
func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) {
// Sync requests might be requested with ambiguous revisions (e.g. master, HEAD, v1.2.3).
// This can change meaning when resuming operations (e.g a hook sync). After calculating a
@@ -140,7 +149,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)

BIN
docs/assets/terminal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

@@ -4,10 +4,10 @@ You can download the latest Argo CD version from [the latest release page of thi
## Linux and WSL
### ArchLinux User Repository ([AUR](https://aur.archlinux.org/packages/))
### ArchLinux
```bash
yay -Sy argocd-bin
pacman -S argocd
```
### Homebrew

View File

@@ -27,6 +27,8 @@ kubectl -n argocd scale deployment/argocd-dex-server --replicas 0
kubectl -n argocd scale deployment/argocd-repo-server --replicas 0
kubectl -n argocd scale deployment/argocd-server --replicas 0
kubectl -n argocd scale deployment/argocd-redis --replicas 0
kubectl -n argocd scale deployment/argocd-applicationset-controller --replicas 0
kubectl -n argocd scale deployment/argocd-notifications-controller --replicas 0
```
### Start local services

View File

@@ -174,7 +174,9 @@ argocd ... --grpc-web
## Why Am I Getting `x509: certificate signed by unknown authority` When Using The CLI?
Your not running your server with correct certs.
The certificate created by default by Argo CD is not automatically recognised by the Argo CD CLI, in order
to create a secure system you must follow the instructions to [install a certificate](/operator-manual/tls/)
and configure your client OS to trust that certificate.
If you're not running in a production system (e.g. you're testing Argo CD out), try the `--insecure` flag:

View File

@@ -29,6 +29,13 @@ kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/core-install.yaml
```
This default installation will have a self-signed certificate and cannot be accessed without a bit of extra work.
Do one of:
* Follow the [instructions to configure a certificate](./operator-manual/tls) (and ensure that the client OS trusts it).
* Configure the client OS to trust the self signed certificate.
* Use the --insecure flag on all Argo CD CLI operations in this guide.
Use `argocd login --core` to [configure](./user-guide/commands/argocd_login.md) CLI access and skip steps 3-5.
## 2. Download Argo CD CLI

View File

@@ -45,7 +45,7 @@ spec:
metadata:
name: '{{name}}-guestbook' # 'name' field of the Secret
spec:
project: "default"
project: "my-project"
source:
repoURL: https://github.com/argoproj/argocd-example-apps/
targetRevision: HEAD
@@ -144,7 +144,7 @@ spec:
metadata:
name: '{{name}}-guestbook'
spec:
project: "default"
project: "my-project"
source:
repoURL: https://github.com/argoproj/argocd-example-apps/
# The cluster values field for each generator will be substituted here:

View File

@@ -2,6 +2,12 @@
The Git generator contains two subtypes: the Git directory generator, and Git file generator.
!!! warning
Git generators are often used to make it easier for (non-admin) developers to create Applications.
If the `project` field in your ApplicationSet is templated, developers may be able to create Applications under Projects with excessive permissions.
For ApplicationSets with a templated `project` field, [the source of truth _must_ be controlled by admins](./Security.md#templated-project-field)
- in the case of git generators, PRs must require admin approval.
## Git Generator: Directories
The Git directory generator, one of two subtypes of the Git generator, generates parameters using the directory structure of a specified Git repository.
@@ -41,7 +47,7 @@ spec:
metadata:
name: '{{path[0]}}'
spec:
project: default
project: "my-project"
source:
repoURL: https://github.com/argoproj/argo-cd.git
targetRevision: HEAD
@@ -59,13 +65,15 @@ The generator parameters are:
- `{{path.basename}}`: For any directory path within the Git repository that matches the `path` wildcard, the right-most path name is extracted (e.g. `/directory/directory2` would produce `directory2`).
- `{{path.basenameNormalized}}`: This field is the same as `path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `path.basename` of `directory_2` would produce `directory-2` here).
Whenever a new Helm chart/Kustomize YAML/Application/plain subfolder is added to the Git repository, the ApplicationSet controller will detect this change and automatically deploy the resulting manifests within new `Application` resources.
**Note**: The right-most path name always becomes `{{path.basename}}`. For example, for `- path: /one/two/three/four`, `{{path.basename}}` is `four`.
Whenever a new Helm chart/Kustomize YAML/Application/plain subdirectory is added to the Git repository, the ApplicationSet controller will detect this change and automatically deploy the resulting manifests within new `Application` resources.
As with other generators, clusters *must* already be defined within Argo CD, in order to generate Applications for them.
### Exclude directories
The Git directory generator will automatically exclude folders that begin with `.` (such as `.git`).
The Git directory generator will automatically exclude directories that begin with `.` (such as `.git`).
The Git directory generator also supports an `exclude` option in order to exclude directories in the repository from being scanned by the ApplicationSet controller:
@@ -88,7 +96,7 @@ spec:
metadata:
name: '{{path.basename}}'
spec:
project: default
project: "my-project"
source:
repoURL: https://github.com/argoproj/argo-cd.git
targetRevision: HEAD
@@ -99,7 +107,7 @@ spec:
```
(*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/examples/applicationset/git-generator-directory/excludes).*)
This example excludes the `exclude-helm-guestbook` directory from the list of directories scanned for this `ApplictionSet` resource.
This example excludes the `exclude-helm-guestbook` directory from the list of directories scanned for this `ApplicationSet` resource.
!!! note "Exclude rules have higher priority than include rules"
@@ -144,6 +152,41 @@ Or, a shorter way (using [path.Match](https://golang.org/pkg/path/#Match) syntax
exclude: true
```
### Root Of Git Repo
The Git directory generator can be configured to deploy from the root of the git repository by providing `'*'` as the `path`.
To exclude directories, you only need to put the name/[path.Match](https://golang.org/pkg/path/#Match) of the directory you do not want to deploy.
```yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/example/example-repo.git
revision: HEAD
directories:
- path: '*'
- path: donotdeploy
exclude: true
template:
metadata:
name: '{{path.basename}}'
spec:
project: "my-project"
source:
repoURL: https://github.com/example/example-repo.git
targetRevision: HEAD
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
```
## Git Generator: Files
The Git file generator is the second subtype of the Git generator. The Git file generator generates parameters using the contents of JSON/YAML files found within a specified repository.
@@ -164,7 +207,7 @@ Suppose you have a Git repository with the following directory structure:
└── git-generator-files.yaml
```
The folders are:
The directories are:
- `guestbook` contains the Kubernetes resources for a simple guestbook application
- `cluster-config` contains JSON/YAML files describing the individual engineering clusters: one for `dev` and one for `prod`.
@@ -228,10 +271,16 @@ As with other generators, clusters *must* already be defined within Argo CD, in
In addition to the flattened key/value pairs from the configuration file, the following generator parameters are provided:
- `{{path}}`: The path to the folder containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json`
- `{{path}}`: The path to the directory containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json`
- `{{path[n]}}`: The path to the matching configuration file within the Git repository, split into array elements (`n` - array index). Example: `path[0]: clusters`, `path[1]: clusterA`
- `{{path.basename}}`: Basename of the path to the folder containing the configuration file (e.g. `clusterA`, with the above example.)
- `{{path.basename}}`: Basename of the path to the directory containing the configuration file (e.g. `clusterA`, with the above example.)
- `{{path.basenameNormalized}}`: This field is the same as `path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `path.basename` of `directory_2` would produce `directory-2` here).
- `{{path.filename}}`: The matched filename. e.g., `config.json` in the above example.
- `{{path.filenameNormalized}}`: The matched filename with unsupported characters replaced with `-`.
**Note**: The right-most *directory* name always becomes `{{path.basename}}`. For example, from `- path: /one/two/three/four/config.json`, `{{path.basename}}` will be `four`.
The filename can always be accessed using `{{path.filename}}`.
## Webhook Configuration

View File

@@ -20,7 +20,7 @@ spec:
metadata:
name: '{{cluster}}-guestbook'
spec:
project: default
project: "my-project"
source:
repoURL: https://github.com/argoproj/argo-cd.git
targetRevision: HEAD

View File

@@ -1,7 +1,6 @@
# Pull Request Generator
The Pull Request generator uses the API of an SCMaaS provider (eg GitHub/GitLab) to automatically discover open pull requests within an repository. This fits well with the style of building a test environment when you create a pull request.
The Pull Request generator uses the API of an SCMaaS provider (GitHub, Gitea, or Bitbucket Server) to automatically discover open pull requests within a repository. This fits well with the style of building a test environment when you create a pull request.
```yaml
apiVersion: argoproj.io/v1alpha1
@@ -16,9 +15,15 @@ spec:
# ...
```
!!! note
Know the security implications of PR generators in ApplicationSets.
[Only admins may create ApplicationSets](./Security.md#only-admins-may-createupdatedelete-applicationsets) to avoid
leaking Secrets, and [only admins may create PRs](./Security.md#templated-project-field) if the `project` field of
an ApplicationSet with a PR generator is templated, to avoid granting management of out-of-bounds resources.
## GitHub
Specify the repository from which to fetch the Github Pull requests.
Specify the repository from which to fetch the GitHub Pull requests.
```yaml
apiVersion: argoproj.io/v1alpha1
@@ -48,7 +53,7 @@ spec:
```
* `owner`: Required name of the GitHub organization or user.
* `repo`: Required name of the Github repository.
* `repo`: Required name of the GitHub repository.
* `api`: If using GitHub Enterprise, the URL to access it. (Optional)
* `tokenRef`: A `Secret` name and key containing the GitHub access token to use for requests. If not specified, will make anonymous requests which have a lower rate limit and can only see public repositories. (Optional)
* `labels`: Labels is used to filter the PRs that you want to target. (Optional)
@@ -182,7 +187,7 @@ spec:
parameters:
- name: "image.tag"
value: "pull-{{head_sha}}"
project: default
project: "my-project"
destination:
server: https://kubernetes.default.svc
namespace: default
@@ -213,7 +218,7 @@ spec:
app.kubernetes.io/instance: {{branch}}-{{number}}
images:
- ghcr.io/myorg/myrepo:{{head_sha}}
project: default
project: "my-project"
destination:
server: https://kubernetes.default.svc
namespace: default
@@ -230,6 +235,7 @@ When using a Pull Request generator, the ApplicationSet controller polls every `
The configuration is almost the same as the one described [in the Git generator](Generators-Git.md), but there is one difference: if you want to use the Pull Request Generator as well, additionally configure the following settings.
In section 1, _"Create the webhook in the Git provider"_, add an event so that a webhook request will be sent when a pull request is created, closed, or label changed.
Select `Let me select individual events` and enable the checkbox for `Pull requests`.
![Add Webhook](../../assets/applicationset/webhook-config-pull-request.png "Add Webhook Pull Request")

View File

@@ -19,6 +19,12 @@ spec:
* `cloneProtocol`: Which protocol to use for the SCM URL. Default is provider-specific but ssh if possible. Not all providers necessarily support all protocols, see provider documentation below for available options.
!!! note
Know the security implications of using SCM generators. [Only admins may create ApplicationSets](./Security.md#only-admins-may-createupdatedelete-applicationsets)
to avoid leaking Secrets, and [only admins may create repos/branches](./Security.md#templated-project-field) if the
`project` field of an ApplicationSet with an SCM generator is templated, to avoid granting management of
out-of-bounds resources.
## GitHub
The GitHub mode uses the GitHub API to scan and organization in either github.com or GitHub Enterprise.

View File

@@ -22,9 +22,9 @@ Follow the [Argo CD Getting Started](../../getting_started.md) instructions for
### B) Install ApplicationSet into an existing Argo CD install (pre-Argo CD v2.3)
**Note**: These instruction only apply to versions of Argo CD before v2.3.0.
**Note**: These instructions only apply to versions of Argo CD before v2.3.0.
The ApplicationSet controller *must* be installed into the same namespace as the Argo CD it is targetting.
The ApplicationSet controller *must* be installed into the same namespace as the Argo CD it is targeting.
Presuming that Argo CD is installed into the `argocd` namespace, run the following command:

View File

@@ -0,0 +1,38 @@
# ApplicationSet Security
ApplicationSet is a powerful tool, and it is crucial to understand its security implications before using it.
## Only admins may create/update/delete ApplicationSets
ApplicationSets can create Applications under arbitrary [Projects](../../user-guide/projects.md). Argo CD setups often
include Projects (such as the `default`) with high levels of permissions, often including the ability to manage the
resources of Argo CD itself (like the RBAC ConfigMap).
ApplicationSets can also quickly create an arbitrary number of Applications and just as quickly delete them.
Finally, ApplicationSets can reveal privileged information. For example, the [git generator](./Generators-Git.md) can
read Secrets in the Argo CD namespace and send them to arbitrary URLs as auth headers. (This functionality is intended
for authorizing requests to SCM providers like GitHub, but it could be abused by a malicious user.)
For these reasons, **only admins** may be given permission (via Kubernetes RBAC or any other mechanism) to create,
update, or delete ApplicationSets.
## Admins must apply appropriate controls for ApplicationSets' sources of truth
Even if non-admins can't create ApplicationSet resources, they may be able to affect the behavior of ApplicationSets.
For example, if an ApplicationSet uses a [git generator](./Generators-Git.md), a malicious user with push access to the
source git repository could generate an excessively high number of Applications, putting strain on the ApplicationSet
and Application controllers. They could also cause the SCM provider's rate limiting to kick in, degrading ApplicationSet
service.
### Templated `project` field
It's important to pay special attention to ApplicationSets where the `project` field is templated. A malicious user with
write access to the generator's source of truth (for example, someone with push access to the git repo for a git
generator) could create Applications under Projects with insufficient restrictions. A malicious user with the ability to
create an Application under an unrestricted Project (like the `default` Project) could take control of Argo CD itself
by, for example, modifying its RBAC ConfigMap.
If the `project` field is not hard-coded in an ApplicationSet's template, then admins _must_ control all sources of
truth for the ApplicationSet's generators.

View File

@@ -15,6 +15,9 @@ The ApplicationSet controller, supplements Argo CD by adding additional features
- Improved support for monorepos: in the context of Argo CD, a monorepo is multiple Argo CD Application resources defined within a single Git repository
- Within multitenant clusters, improves the ability of individual cluster tenants to deploy applications using Argo CD (without needing to involve privileged cluster administrators in enabling the destination clusters/namespaces)
!!! note
Be aware of the [security implications](./Security.md) of ApplicationSets before using them.
## The ApplicationSet resource
This example defines a new `guestbook` resource of kind `ApplicationSet`:
@@ -37,6 +40,7 @@ spec:
metadata:
name: '{{cluster}}-guestbook'
spec:
project: my-project
source:
repoURL: https://github.com/infra-team/cluster-deployments.git
targetRevision: HEAD

View File

@@ -39,6 +39,8 @@ data:
# The URLs to download additional ArgoCD binaries (besides the Linux amd64 binary included by default)
# for different OS architectures. If provided, additional download buttons will be displayed on the help page.
help.download.linux-arm64: "path-or-url-to-download"
help.download.linux-ppc64le: "path-or-url-to-download"
help.download.linux-s390x: "path-or-url-to-download"
help.download.darwin-amd64: "path-or-url-to-download"
help.download.darwin-arm64: "path-or-url-to-download"
help.download.windows-amd64: "path-or-url-to-download"
@@ -231,6 +233,14 @@ data:
# If omitted, Argo CD injects the app name into the label: 'app.kubernetes.io/instance'
application.instanceLabelKey: mycompany.com/appname
# You can change the resource tracking method Argo CD uses by changing the
# setting application.resourceTrackingMethod to the desired method.
# The following methods are available:
# - label : Uses the application.instanceLabelKey label for tracking
# - annotation : Uses an annotation with additional metadata for tracking instead of the label
# - annotation+label : Also uses an annotation for tracking, but additionally labels the resource with the application name
application.resourceTrackingMethod: annotation
# disables admin user. Admin is enabled by default
admin.enabled: "false"
# add an additional local user with apiKey and login capabilities
@@ -288,3 +298,12 @@ data:
# exec.enabled indicates whether the UI exec feature is enabled. It is disabled by default.
exec.enabled: "false"
# exec.shells restricts which shells are allowed for `exec`, and in which order they are attempted
exec.shells: "bash,sh,powershell,cmd"
# 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

@@ -17,6 +17,9 @@ data:
# Redis database
redis.db:
# Open-Telemetry collector address: (e.g. "otel-collector:4317")
otlp.address:
## Controller Properties
# Repo server RPC call timeout seconds.
controller.repo.server.timeout.seconds: "60"
@@ -103,4 +106,10 @@ 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'
# Paths to be excluded from the tarball streamed to plugins. Separate with ;
reposerver.plugin.tar.exclusions: ""

View File

@@ -0,0 +1,66 @@
# Pagerduty
## Parameters
The Pagerduty notification service is used to create pagerduty incidents and requires specifying the following settings:
* `pagerdutyToken` - the pagerduty auth token
* `from` - email address of a valid user associated with the account making the request.
* `serviceID` - The ID of the resource.
## Example
The following snippet contains sample Pagerduty service configuration:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: <secret-name>
stringData:
pagerdutyToken: <pd-api-token>
```
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: <config-map-name>
data:
service.pagerduty: |
token: $pagerdutyToken
from: <emailid>
```
## Template
Notification templates support specifying subject for pagerduty notifications:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: <config-map-name>
data:
template.rollout-aborted: |
message: Rollout {{.rollout.metadata.name}} is aborted.
pagerduty:
title: "Rollout {{.rollout.metadata.name}}"
urgency: "high"
body: "Rollout {{.rollout.metadata.name}} aborted "
priorityID: "<priorityID of incident>"
```
NOTE: A Priority is a label representing the importance and impact of an incident. This is only available on Standard and Enterprise plans of pagerduty.
## Annotation
Annotation sample for pagerduty notifications:
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
annotations:
notifications.argoproj.io/subscribe.on-rollout-aborted.pagerduty: "<serviceID for Pagerduty>"
```

View File

@@ -54,6 +54,26 @@ The Slack notification service configuration includes following settings:
annotations:
notifications.argoproj.io/subscribe.on-sync-succeeded.slack: my_channel
1. Annotation with more than one trigger multiple of destinations and recipients
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
notifications.argoproj.io/subscriptions: |
- trigger: [on-scaling-replica-set, on-rollout-updated, on-rollout-step-completed]
destinations:
- service: slack
recipients: [my-channel-1, my-channel-2]
- service: email
recipients: [recipient-1, recipient-2, recipient-3 ]
- trigger: [on-rollout-aborted, on-analysis-run-failed, on-analysis-run-error]
destinations:
- service: slack
recipients: [my-channel-21, my-channel-22]
```
## Templates
Notification templates can be customized to leverage slack message blocks and attachments

View File

@@ -18,11 +18,11 @@ These default built-in role definitions can be seen in [builtin-policy.csv](http
Breaking down the permissions definition differs slightly between applications and every other resource type in Argo CD.
* All resources *except* applications permissions (see next bullet):
* All resources *except* application-specific permissions (see next bullet):
`p, <role/user/group>, <resource>, <action>, <object>`
* Applications (which belong to an AppProject):
* Applications, logs, and exec (which belong to an AppProject):
`p, <role/user/group>, <resource>, <action>, <appproject>/<object>`
@@ -30,28 +30,36 @@ Breaking down the permissions definition differs slightly between applications a
Resources: `clusters`, `projects`, `applications`, `repositories`, `certificates`, `accounts`, `gpgkeys`, `logs`, `exec`
Actions: `get`, `create`, `update`, `delete`, `sync`, `override`, `action`
Actions: `get`, `create`, `update`, `delete`, `sync`, `override`,
`action/<group/kind/action-name>`
#### Application resources
The resource path for application objects is of the form
`<project-name>/<application-name>`.
Delete access to sub-resources of a project, such as a rollout or a pod, cannot
be managed granularly. `<project-name>/<application-name>` grants access to all
subresources of an application.
#### The `action` action
The `action` action corresponds to either built-in resource customizations defined
[in the Argo CD repository](https://github.com/argoproj/argo-cd/search?q=filename%3Aaction.lua+path%3Aresource_customizations),
or to [custom resource actions](resource_actions.md#custom-resource-actions) defined by you.
The `action` path is of the form `action/<api-group>/<Kind>/<action-name>`. For
example, a resource customization path
`resource_customizations/extensions/DaemonSet/actions/restart/action.lua`
corresponds to the `action` path `action/extensions/DaemonSet/restart`. You can
also use glob patterns in the action path: `action/*` (or regex patterns if you have
[enabled the `regex` match mode](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-rbac-cm.yaml)).
#### `exec` resource
`exec` is a special resource. When enabled with the `create` action, this privilege allows a user to `exec` into Pods via
the Argo CD UI. The functionality is similar to `kubectl exec`.
`exec` is a powerful privilege. It allows the user to run arbitrary code on any Pod managed by an Application for which
they have `create` privileges. If the Pod mounts a ServiceAccount token (which is the default behavior of Kubernetes),
then the user effectively has the same privileges as that ServiceAccount.
The exec feature is disabled entirely by default. To enable it, set the `exec.enabled` key to "true" on the argocd-cm
ConfigMap. You will also need to add the following to the argocd-api-server Role or ClusterRole.
```yaml
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
```
See [Web-based Terminal](web_based_terminal.md) for more info.
## Tying It All Together
@@ -78,7 +86,7 @@ data:
p, role:org-admin, repositories, update, *, allow
p, role:org-admin, repositories, delete, *, allow
p, role:org-admin, logs, get, *, allow
p, role:org-admin, exec, get, *, allow
p, role:org-admin, exec, create, */*, allow
g, your-github-org:your-team, role:org-admin
```
@@ -94,12 +102,12 @@ p, role:staging-db-admins, applications, override, staging-db-admins/*, allow
p, role:staging-db-admins, applications, sync, staging-db-admins/*, allow
p, role:staging-db-admins, applications, update, staging-db-admins/*, allow
p, role:staging-db-admins, logs, get, staging-db-admins/*, allow
p, role:staging-db-admins, exec, get, staging-db-admins/*, allow
p, role:staging-db-admins, exec, create, staging-db-admins/*, allow
p, role:staging-db-admins, projects, get, staging-db-admins, allow
g, db-admins, role:staging-db-admins
```
This example defines a *role* called `staging-db-admins` with *eight permissions* that allow that role to perform the *actions* (`create`/`delete`/`get`/`override`/`sync`/`update` applications, `get` logs, `get` exec and `get` appprojects) against `*` (all) objects in the `staging-db-admins` Argo CD AppProject.
This example defines a *role* called `staging-db-admins` with *eight permissions* that allow that role to perform the *actions* (`create`/`delete`/`get`/`override`/`sync`/`update` applications, `get` logs, `create` exec and `get` appprojects) against `*` (all) objects in the `staging-db-admins` Argo CD AppProject.
## Anonymous Access

View File

@@ -119,6 +119,13 @@ kubectl delete secret argocd-manager-token-XXXXXX -n kube-system
argocd cluster add CONTEXTNAME
```
!!! note
Kubernetes 1.24 [stopped automatically creating tokens for Service Accounts](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.24.md#no-really-you-must-read-this-before-you-upgrade).
[Starting in Argo CD 2.4](https://github.com/argoproj/argo-cd/pull/9546), `argocd cluster add` creates a
ServiceAccount _and_ a non-expiring Service Account token Secret when adding 1.24 clusters. In the future, Argo CD
will [add support for the Kubernetes TokenRequest API](https://github.com/argoproj/argo-cd/issues/9610) to avoid
using long-lived tokens.
To revoke Argo CD's access to a managed cluster, delete the RBAC artifacts against the *_managed_*
cluster, and remove the cluster entry from Argo CD:
@@ -210,4 +217,50 @@ Argo CD logs payloads of most API requests except request that are considered se
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.
to configure IP addresses logging in the proxy server that sits in front of the API server.
## ApplicationSets
Argo CD's ApplicationSets feature has its own [security considerations](./applicationset/Security.md). Be aware of those
issues before using ApplicationSets.
## 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

@@ -37,6 +37,7 @@ argocd-application-controller [flags]
--metrics-port int Start metrics server on given port (default 8082)
-n, --namespace string If present, the namespace scope for this CLI request
--operation-processors int Number of application operation processors (default 10)
--otlp-address string OpenTelemetry collector address to send traces to
--password string Password for basic authentication to the API server
--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.

View File

@@ -13,28 +13,30 @@ 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)
--otlp-address string OpenTelemetry collector address to send traces to
--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)
--otlp-address string OpenTelemetry collector address to send traces to
--parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit.
--plugin-tar-exclude stringArray Globs to filter when sending tarballs to plugins.
--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

@@ -6,8 +6,11 @@ The Argo CD Notifications and ApplicationSet are part of Argo CD now. You no lon
The Notifications and ApplicationSet components are bundled into default Argo CD installation manifests.
The bundled manifests are drop-in replacements for the previous versions. If you are using Kustomize to bundle the manifests together then just
remove references to https://github.com/argoproj-labs/argocd-notifications and https://github.com/argoproj-labs/applicationset. No action is required
if you are using `kubectl apply`.
remove references to https://github.com/argoproj-labs/argocd-notifications and https://github.com/argoproj-labs/applicationset.
If you are using [the argocd-notifications helm chart](https://github.com/argoproj/argo-helm/tree/argocd-notifications-1.8.1/charts/argocd-notifications), you can move the chart [values](https://github.com/argoproj/argo-helm/blob/argocd-notifications-1.8.1/charts/argocd-notifications/values.yaml) to the `notifications` section of the argo-cd chart [values](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/values.yaml#L2152). Although most values remain as is, for details please look up the values that are relevant to you.
No action is required if you are using `kubectl apply`.
## Configure Additional Argo CD Binaries
@@ -42,4 +45,4 @@ Note that bundled Kustomize version has been upgraded from 4.2.0 to 4.4.1.
## Upgraded Helm Version
Note that bundled Helm version has been upgraded from 3.7.1 to 3.8.0.
Note that bundled Helm version has been upgraded from 3.7.1 to 3.8.0.

View File

@@ -2,20 +2,92 @@
## KSonnet support is removed
The [https://ksonnet.io/] had been deprecated in [2019](https://github.com/ksonnet/ksonnet/pull/914/files) and no longer maintained.
The time has come to remove it from the ArgoCD.
Ksonnet was deprecated in [2019](https://github.com/ksonnet/ksonnet/pull/914/files) and is no longer maintained.
The time has come to remove it from the Argo CD.
## Helm 2 support is removed
Helm 2 is not been officially supported since [Nov 2020](https://helm.sh/blog/helm-2-becomes-unsupported/). In order to ensure a smooth transition
Helm 2 support was preserved in the Argo CD. We feel that Helm 3 is stable and it is time to drop Helm 2 support.
Helm 2 has not been officially supported since [Nov 2020](https://helm.sh/blog/helm-2-becomes-unsupported/). In order to ensure a smooth transition,
Helm 2 support was preserved in the Argo CD. We feel that Helm 3 is stable, and it is time to drop Helm 2 support.
## Support for private repo SSH keys using the SHA-1 signature hash algorithm is removed
Argo CD 2.4 upgraded its base image from Ubuntu 20.04 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.4, 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`.
## Configure RBAC to account for new `exec` resource
2.4 introduces a new `exec` [RBAC resource](https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/#rbac-resources-and-actions).
When you upgrade to 2.4, RBAC policies with `*` in the resource field and `create` or `*` in the verb field will automatically grant the `exec` privilege.
When you upgrade to 2.4, RBAC policies with `*` in the resource field and `create` or `*` in the action field will automatically grant the `exec` privilege.
To avoid granting the new privilege, replace the existing policy with a list of new policies explicitly listing the old resources.
@@ -42,12 +114,61 @@ p, role: org-admin, accounts, create, my-proj/*, allow
p, role: org-admin, gpgkeys, create, my-proj/*, allow
```
## Remove the shared volume from any sidecar plugins
## Enable logs RBAC enforcement
2.4 introduced `logs` as a new RBAC resource. In 2.3, users with `applications, get` access automatically get logs
access. In 2.5, you will have to explicitly grant `logs, get` access. Logs RBAC enforcement can be enabled with a flag
in 2.4. We recommend enabling the flag now for an easier upgrade experience in 2.5.
To enabled logs RBAC enforcement, add this to your argocd-cm ConfigMap:
```yaml
server.rbac.log.enforce.enable: "true"
```
If you want to allow the same users to continue to have logs access, just find every line that grants
`applications, get` access and also grant `logs, get`.
### Example
Old:
```csv
p, role:staging-db-admins, applications, get, staging-db-admins/*, allow
p, role:test-db-admins, applications, *, staging-db-admins/*, allow
```
New:
```csv
p, role:staging-db-admins, applications, get, staging-db-admins/*, allow
p, role:staging-db-admins, logs, get, staging-db-admins/*, allow
p, role:test-db-admins, applications, *, staging-db-admins/*, allow
p, role:test-db-admins, logs, get, staging-db-admins/*, allow
```
## Known UI issue
Currently, upon pressing the "LOGS" tab in pod view by users who don't have an explicit allow get logs policy, the red "unable to load data: Internal error" is received in the bottom of the screen, and "Failed to load data, please try again" is displayed.
## Test repo-server with its new dedicated Service Account
As a security enhancement, the argocd-repo-server Deployment uses its own Service Account instead of `default`.
If you have a custom environment that might depend on repo-server using the `default` Service Account (such as a plugin
that uses the Service Account for auth), be sure to test before deploying the 2.4 upgrade to production.
## Plugins
### Remove the shared volume from any sidecar plugins
As a security enhancement, [sidecar plugins](../../user-guide/config-management-plugins.md#option-2-configure-plugin-via-sidecar)
no longer share the /tmp directory with the repo-server.
If you have one or more sidecar plugins enabled, remove the /tmp volume mount from the plugin container definition.
If you have one or more sidecar plugins enabled, replace the /tmp volume mount for each sidecar to use a volume specific
to each plugin.
```yaml
apiVersion: apps/v1
@@ -60,7 +181,47 @@ spec:
containers:
- name: your-plugin-name
volumeMounts:
# Remove the next two lines:
- mountPath: /tmp
name: tmp
name: your-plugin-name-tmp
volumes:
# Add this volume.
- name: your-plugin-name-tmp
emptyDir: {}
```
### Update plugins to use newly-prefixed environment variables
If you use plugins that depend on user-supplied environment variables, then they must be updated to be compatible with
Argo CD 2.4. Here is an example of user-supplied environment variables in the `plugin` section of an Application spec:
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
plugin:
env:
- name: FOO
value: bar
```
Going forward, all user-supplied environment variables will be prefixed with `ARGOCD_ENV_` before being sent to the
plugin's `init`, `generate`, or `discover` commands. This prevents users from setting potentially-sensitive environment
variables.
If you have written a custom plugin which handles user-provided environment variables, update it to handle the new
prefix.
If you use a third-party plugin which does not explicitly advertise Argo CD 2.4 support, it might not handle the
prefixed environment variables. Open an issue with the plugin's authors and confirm support before upgrading to Argo CD
2.4.
### Confirm sidecar plugins have all necessary environment variables
A bug in < 2.4 caused `init` and `generate` commands to receive environment variables from the main repo-server
container, taking precedence over environment variables from the plugin's sidecar.
Starting in 2.4, sidecar plugins will not receive environment variables from the main repo-server container. Make sure
that any environment variables necessary for the sidecar plugin to function are set on the sidecar plugin.
argocd-cm plugins will continue to receive environment variables from the main repo-server container.

View File

@@ -50,7 +50,7 @@ If you've never configured this, you'll be redirected straight to this if you tr
### 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:
Edit `argocd-cm` and add the following `dex.config` to the data section, replacing `clientID` and `clientSecret` with the values you saved before:
```yaml
data:
@@ -113,7 +113,7 @@ data:
### Configure Argo to use the new Google SAML App
Edit `argo-cm` and add the following `dex.config` to the data section, replacing the `caData`, `argocd.example.com`, `sso-url`, and optionally `google-entity-id` with your values from the Google SAML App:
Edit `argocd-cm` and add the following `dex.config` to the data section, replacing the `caData`, `argocd.example.com`, `sso-url`, and optionally `google-entity-id` with your values from the Google SAML App:
```yaml
data:
@@ -211,7 +211,7 @@ Go through the same steps as in [OpenID Connect using Dex](#openid-connect-using
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:
3. Edit `argocd-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:

View File

@@ -197,6 +197,7 @@ NOTES:
* There is no need to set `redirectURI` in the `connectors.config` as shown in the dex documentation.
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`)
* When using a custom secret (e.g., `some_K8S_secret` above,) it *must* have the label `app.kubernetes.io/part-of: argocd`.
## OIDC Configuration with DEX
@@ -495,3 +496,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

@@ -0,0 +1,45 @@
# Web-based Terminal
![Argo CD Terminal](../assets/terminal.png)
Since v2.4, Argo CD has a web-based terminal that allows you to get a shell inside a running pod just like you would with
`kubectl exec`. It's basically SSH from your browser, full ANSI color support and all! However, for security this feature
is disabled by default.
This is a powerful privilege. It allows the user to run arbitrary code on any Pod managed by an Application for which
they have the `exec/create` privilege. If the Pod mounts a ServiceAccount token (which is the default behavior of
Kubernetes), then the user effectively has the same privileges as that ServiceAccount.
## Enabling the terminal
1. Set the `exec.enabled` key to `true` on the `argocd-cm` ConfigMap.
2. Patch the `argocd-server` Role (if using namespaced Argo) or ClusterRole (if using clustered Argo) to allow `argocd-server`
to exec into pods
```yaml
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
```
3. Add RBAC rules to allow your users to `create` the `exec` resource, i.e.
```
p, role:myrole, exec, create, */*, allow
```
See [RBAC Configuration](rbac.md#exec-resource) for more info.
## Changing allowed shells
By default, Argo CD attempts to execute shells in this order:
1. bash
2. sh
3. powershell
4. cmd
If none of the shells are found, the terminal session will fail. To add to or change the allowed shells, change the
`exec.shells` key in the `argocd-cm` ConfigMap, separating them with commas.

View File

@@ -4,6 +4,10 @@ The [ApplicationSet controller](../operator-manual/applicationset/index.md) is a
The set of tools provided by the ApplicationSet controller may also be used to allow developers (without access to the Argo CD namespace) to independently create Applications without cluster-administrator intervention.
!!! warning
Be aware of the [security implications](../operator-manual/applicationset/Security.md) before allowing developers to
create Applications via ApplicationSets.
The ApplicationSet controller is installed alongside Argo CD (within the same namespace), and the controller automatically generates Argo CD Applications based on the contents of a new `ApplicationSet` Custom Resource (CR).
Here is an example of an `ApplicationSet` resource that can be used to target an Argo CD Application to multiple clusters:

View File

@@ -2,6 +2,11 @@
Argo CD allows integrating more config management tools using config management plugins.
!!! warning
Plugins are granted a level of trust in the Argo CD system, so it is important to implement plugins securely. Argo
CD administrators should only install plugins from trusted sources, and they should audit plugins to weigh their
particular risks and benefits.
## Installing a CMP
There are two ways to install a Config Management Plugin (CMP):
@@ -62,8 +67,6 @@ spec:
command: [sh, -c, 'echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}"']
discover:
fileName: "./subdir/s*.yaml"
allowConcurrency: true
lockRepo: false
```
!!! note
@@ -85,9 +88,6 @@ If `discover.fileName` is not provided, the `discover.find.command` is executed
application repository is supported by the plugin or not. The `find` command should return a non-error exit code
and produce output to stdout when the application source type is supported.
If your plugin makes use of `git` (e.g. `git crypt`), it is advised to set `lockRepo` to `true` so that your plugin will have exclusive access to the
repository at the time it is executed. Otherwise, two applications synced at the same time may result in a race condition and sync failure.
#### 2. Place the plugin configuration file in the sidecar
Argo CD expects the plugin configuration file to be located at `/home/argocd/cmp-server/config/plugin.yaml` in the sidecar.
@@ -114,8 +114,6 @@ data:
command: [sh, -c, 'echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}"']
discover:
fileName: "./subdir/s*.yaml"
allowConcurrency: true
lockRepo: false
```
#### 3. Register the plugin sidecar
@@ -140,10 +138,16 @@ containers:
- mountPath: /home/argocd/cmp-server/config/plugin.yaml
subPath: plugin.yaml
name: cmp-plugin
volumes:
- configMap:
name: cmp-plugin
# Starting with v2.4, do NOT mount the same tmp volume as the repo-server container. The filesystem separation helps
# mitigate path traversal attacks.
- mountPath: /tmp
name: cmp-tmp
volumes:
- configMap:
name: cmp-plugin
name: cmp-plugin
- emptyDir: {}
name: cmp-tmp
```
!!! important "Double-check these items"
@@ -155,7 +159,7 @@ containers:
CMP commands have access to
1. The system environment variables
1. The system environment variables (of the repo-server container for argocd-cm plugins or of the sidecar for sidecar plugins)
2. [Standard build environment](build-environment.md)
3. Variables in the application spec (References to system and build variables will get interpolated in the variables' values):
@@ -172,6 +176,19 @@ spec:
value: test-$ARGOCD_APP_REVISION
```
!!! note
The `discover.command` command only has access to the above environment starting with v2.4.
> v2.4
Before reaching the `init.command`, `generate.command`, and `discover.command` commands, Argo CD prefixes all
user-supplied environment variables (#3 above) with `ARGOCD_ENV_`. This prevents users from directly setting
potentially-sensitive environment variables.
If your plugin was written before 2.4 and depends on user-supplied environment variables, then you will need to update
your plugin's behavior to work with 2.4. If you use a third-party plugin, make sure they explicitly advertise support
for 2.4.
## Using a CMP
If your CMP is defined in the `argocd-cm` ConfigMap, you can create a new Application using the CLI. Replace
@@ -217,3 +234,18 @@ If you don't need to set any environment variables, you can set an empty plugin
Each CMP command will also independently timeout on the `ARGOCD_EXEC_TIMEOUT` set for the CMP sidecar. The default
is 90s. So if you increase the repo server timeout greater than 90s, be sure to set `ARGOCD_EXEC_TIMEOUT` on the
sidecar.
## Plugin tar stream exclusions
In order to increase the speed of manifest generation, certain files and folders can be excluded from being sent to your
plugin. We recommend excluding your `.git` folder if it isn't necessary. Use Go's
[filepatch.Match](https://pkg.go.dev/path/filepath#Match) syntax.
You can set it one of three ways:
1. The `--plugin-tar-exclude` argument on the repo server.
2. The `reposerver.plugin.tar.exclusions` key if you are using `argocd-cmd-params-cm`
3. Directly setting `ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS` environment variable on the repo server.
For option 1, the flag can be repeated multiple times. For option 2 and 3, you can specify multiple globs by separating
them with semicolons.

View File

@@ -0,0 +1,9 @@
# Environment Variables
The following environment variables can be used with `argocd` CLI:
| Environment Variable | Description |
| --- | --- |
| `ARGOCD_SERVER` | the address of the ArgoCD server without `https://` prefix <br> (instead of specifying `--server` for every command) <br> eg. `ARGOCD_SERVER=argocd.mycompany.com` if served through an ingress with DNS |
| `ARGOCD_AUTH_TOKEN` | the ArgoCD `apiKey` for your ArgoCD user to be able to authenticate |
| `ARGOCD_OPTS` | command-line options to pass to `argocd` CLI <br> eg. `ARGOCD_OPTS="--grpc-web"` |

View File

@@ -85,3 +85,22 @@ argocd app set <appName> --kustomize-version v3.5.4
## Build Environment
Kustomize does not support parameters and therefore cannot support the standard [build environment](build-environment.md).
## Kustomizing Helm charts
It's possible to [render Helm charts with Kustomize](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md).
Doing so requires that you pass the `--enable-helm` flag to the `kustomize build` command.
This flag is not part of the Kustomize options within Argo CD.
If you would like to render Helm charts through Kustomize in an Argo CD application, you have two options:
You can either create a [custom plugin](https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/), or modify the `argocd-cm` ConfigMap to include the `--enable-helm` flag globally for all Kustomize applications:
```
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
kustomize.buildOptions: --enable-helm
```

View File

@@ -83,7 +83,13 @@ Private repositories that require an SSH private key have a URL that typically s
> v1.2 or later
You can configure your Git repository using HTTPS either using the CLI or the UI.
You can configure your Git repository using SSH either using the CLI or the UI.
!!! note
Argo CD 2.4 upgraded to OpenSSH 8.9. OpenSSH 8.8
[dropped support for the `ssh-rsa` SHA-1 key signature algorithm](https://www.openssh.com/txt/release-8.8).
See the [2.3 to 2.4 upgrade guide](../operator-manual/upgrading/2.3-2.4.md) for details about testing SSH servers
for compatibility with Argo CD and for working around servers that do not support newer algorithms.
Using the CLI:

View File

@@ -2,7 +2,7 @@
ArgoCD allows users to customize some aspects of how it syncs the desired state in the target cluster. Some Sync Options can defined as annotations in a specific resource. Most of the Sync Options are configured in the Application resource `spec.syncPolicy.syncOptions` attribute.
Bellow you can find details about each available Sync Option:
Below you can find details about each available Sync Option:
## No Prune Resources

23
go.mod
View File

@@ -9,15 +9,15 @@ require (
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
github.com/alicebob/miniredis v2.5.0+incompatible
github.com/alicebob/miniredis/v2 v2.14.2
github.com/argoproj/gitops-engine v0.6.1-0.20220328190556-73bcea9c8c8f
github.com/argoproj/notifications-engine v0.3.1-0.20220322174744-ac18ca10234c
github.com/argoproj/gitops-engine v0.7.0
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0
github.com/aws/aws-sdk-go v1.38.49
github.com/bombsimon/logrusr/v2 v2.0.1
github.com/bradleyfalzon/ghinstallation/v2 v2.0.4
github.com/casbin/casbin/v2 v2.39.1
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
github.com/coreos/go-oidc v2.1.0+incompatible
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/dustin/go-humanize v1.0.0
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/fsnotify/fsnotify v1.5.1
@@ -60,7 +60,7 @@ require (
github.com/olekukonko/tablewriter v0.0.5
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1
github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d // indirect
github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/prometheus/client_golang v1.11.0
github.com/r3labs/diff v1.1.0
github.com/robfig/cron v1.2.0
@@ -75,11 +75,11 @@ require (
github.com/whilp/git-urls v0.0.0-20191001220047-6db9661140c0
github.com/xanzy/go-gitlab v0.60.0
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/net v0.0.0-20211209124913-491a49abca63
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
golang.org/x/net v0.0.0-20220621193019-9d032be2e588
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
google.golang.org/grpc v1.45.0
google.golang.org/protobuf v1.28.0
@@ -202,7 +202,7 @@ require (
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
golang.org/x/exp v0.0.0-20210901193431-a062eea981d2 // indirect
golang.org/x/mod v0.5.1-0.20210830214625-1b1db11ec8f4 // indirect
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff // indirect
@@ -214,10 +214,10 @@ require (
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/square/go-jose.v2 v2.2.2 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/apiserver v0.23.1 // indirect
k8s.io/apiserver v0.23.1
k8s.io/cli-runtime v0.23.1 // indirect
k8s.io/component-base v0.23.1 // indirect
k8s.io/component-helpers v0.23.1 // indirect
@@ -237,6 +237,7 @@ require (
)
require (
github.com/PagerDuty/go-pagerduty v1.5.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect

37
go.sum
View File

@@ -104,6 +104,8 @@ github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PagerDuty/go-pagerduty v1.5.0 h1:/p8FGD32G8HGm7MQIjlTPTGXRJ62Qkm8Lmt5BcUVJOo=
github.com/PagerDuty/go-pagerduty v1.5.0/go.mod h1:txr8VbObXdk2RkqF+C2an4qWssdGY99fK26XYUDjh+4=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -144,10 +146,10 @@ github.com/antonmedv/expr v1.8.9/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmH
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0/go.mod h1:iy07dV61Z7QQdCKJCIvUoDL21u6AIceRhZzyleh2ymc=
github.com/argoproj/gitops-engine v0.6.1-0.20220328190556-73bcea9c8c8f h1:3x8pG690gbZtGK2G/dlL7b243t/WyyeDT7OUs2n76Nk=
github.com/argoproj/gitops-engine v0.6.1-0.20220328190556-73bcea9c8c8f/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
github.com/argoproj/notifications-engine v0.3.1-0.20220322174744-ac18ca10234c h1:n/5BIocdWYtp1qC8/GFgUUV62I+gln54KFZZLgczwDc=
github.com/argoproj/notifications-engine v0.3.1-0.20220322174744-ac18ca10234c/go.mod h1:QF4tr3wfWOnhkKSaRpx7k/KEErQAh8iwKQ2pYFu/SfA=
github.com/argoproj/gitops-engine v0.7.0 h1:X6W8VP9bWTe74wWxAV3i8KZ0yBmre5DU8g+GWH09FCo=
github.com/argoproj/gitops-engine v0.7.0/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320 h1:XDjtTfccs4rSOT1n+i1zV9RpxQdKky1b4YBic16E0qY=
github.com/argoproj/notifications-engine v0.3.1-0.20220430155844-567361917320/go.mod h1:R3zlopt+/juYlebQc9Jarn9vBQ2xZruWOWjUNkfGY9M=
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc=
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0/go.mod h1:ra+bQPmbVAoEL+gYSKesuigt4m49i3Qa3mE/xQcjCiA=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -252,8 +254,9 @@ github.com/coredns/corefile-migration v1.0.14/go.mod h1:XnhgULOEouimnzgn0t4WPuFD
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -942,8 +945,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d h1:7gXyC293Lsm2YWgQ+0uaAFFFDO82ruiQSwc3ua+Vtlc=
github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
@@ -1228,8 +1231,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1340,8 +1344,10 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220621193019-9d032be2e588 h1:9ubFuySsnAJYGyJrZ3koiEv8FyqofCBdz3G9Mbf2YFc=
golang.org/x/net v0.0.0-20220621193019-9d032be2e588/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1361,8 +1367,9 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb h1:8tDJ3aechhddbdPAxpycgXHJRMLpk/Ab+aa4OgdN5/g=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1482,11 +1489,14 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1786,8 +1796,9 @@ gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=

View File

@@ -119,6 +119,12 @@ spec:
name: argocd-cmd-params-cm
key: controller.default.cache.expiration
optional: true
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
name: argocd-cmd-params-cm
key: otlp.address
optional: true
image: quay.io/argoproj/argocd:latest
imagePullPolicy: Always
name: argocd-application-controller
@@ -178,4 +184,4 @@ spec:
- key: tls.key
path: tls.key
- key: ca.crt
path: ca.crt
path: ca.crt

View File

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

View File

@@ -15,16 +15,13 @@ spec:
labels:
app.kubernetes.io/name: argocd-repo-server
spec:
serviceAccountName: argocd-repo-server
automountServiceAccountToken: false
containers:
- name: argocd-repo-server
image: quay.io/argoproj/argocd:latest
imagePullPolicy: Always
command:
- entrypoint.sh
- argocd-repo-server
- --redis
- $(ARGOCD_REDIS_SERVICE):6379
command: [ "sh", "-c", "entrypoint.sh argocd-repo-server --redis $(ARGOCD_REDIS_SERVICE):6379"]
env:
- name: ARGOCD_RECONCILIATION_TIMEOUT
valueFrom:
@@ -98,6 +95,24 @@ spec:
name: argocd-cmd-params-cm
key: reposerver.default.cache.expiration
optional: true
- name: ARGOCD_REPO_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
name: argocd-cmd-params-cm
key: otlp.address
optional: true
- name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE
valueFrom:
configMapKeyRef:
name: argocd-cmd-params-cm
key: reposerver.max.combined.directory.manifests.size
optional: true
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
valueFrom:
configMapKeyRef:
name: argocd-cmd-params-cm
key: reposerver.plugin.tar.exclusions
optional: true
- name: HELM_CACHE_HOME
value: /helm-working-dir
- name: HELM_CONFIG_HOME

View File

@@ -0,0 +1,8 @@
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/name: argocd-repo-server
app.kubernetes.io/part-of: argocd
app.kubernetes.io/component: repo-server
name: argocd-repo-server

View File

@@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- argocd-repo-server-sa.yaml
- argocd-repo-server-deployment.yaml
- argocd-repo-server-service.yaml
- argocd-repo-server-network-policy.yaml
- argocd-repo-server-network-policy.yaml

View File

@@ -178,6 +178,12 @@ spec:
name: argocd-cmd-params-cm
key: server.http.cookie.maxnumber
optional: true
- name: ARGOCD_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
name: argocd-cmd-params-cm
key: otlp.address
optional: true
volumeMounts:
- name: ssh-known-hosts
mountPath: /app/config/ssh

View File

@@ -9017,6 +9017,15 @@ metadata:
app.kubernetes.io/part-of: argocd
name: argocd-redis
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: repo-server
app.kubernetes.io/name: argocd-repo-server
app.kubernetes.io/part-of: argocd
name: argocd-repo-server
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
@@ -9376,7 +9385,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -9506,10 +9515,9 @@ spec:
automountServiceAccountToken: false
containers:
- command:
- entrypoint.sh
- argocd-repo-server
- --redis
- argocd-redis:6379
- sh
- -c
- entrypoint.sh argocd-repo-server --redis argocd-redis:6379
env:
- name: ARGOCD_RECONCILIATION_TIMEOUT
valueFrom:
@@ -9583,13 +9591,31 @@ spec:
key: reposerver.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.max.combined.directory.manifests.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
valueFrom:
configMapKeyRef:
key: reposerver.plugin.tar.exclusions
name: argocd-cmd-params-cm
optional: true
- name: HELM_CACHE_HOME
value: /helm-working-dir
- name: HELM_CONFIG_HOME
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -9638,7 +9664,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -9650,6 +9676,7 @@ spec:
volumeMounts:
- mountPath: /var/run/argocd
name: var-files
serviceAccountName: argocd-repo-server
volumes:
- configMap:
name: argocd-ssh-known-hosts-cm
@@ -9818,7 +9845,13 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

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

View File

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

View File

@@ -9042,6 +9042,15 @@ metadata:
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: repo-server
app.kubernetes.io/name: argocd-repo-server
app.kubernetes.io/part-of: argocd
name: argocd-repo-server
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: server
@@ -10311,7 +10320,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -10408,7 +10417,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -10448,7 +10457,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -10681,13 +10690,31 @@ spec:
key: reposerver.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.max.combined.directory.manifests.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
valueFrom:
configMapKeyRef:
key: reposerver.plugin.tar.exclusions
name: argocd-cmd-params-cm
optional: true
- name: HELM_CACHE_HOME
value: /helm-working-dir
- name: HELM_CONFIG_HOME
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -10736,7 +10763,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -10748,6 +10775,7 @@ spec:
volumeMounts:
- mountPath: /var/run/argocd
name: var-files
serviceAccountName: argocd-repo-server
volumes:
- configMap:
name: argocd-ssh-known-hosts-cm
@@ -10976,7 +11004,13 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -11178,7 +11212,13 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -51,6 +51,15 @@ metadata:
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: repo-server
app.kubernetes.io/name: argocd-repo-server
app.kubernetes.io/part-of: argocd
name: argocd-repo-server
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: server
@@ -1235,7 +1244,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1332,7 +1341,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1372,7 +1381,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1605,13 +1614,31 @@ spec:
key: reposerver.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.max.combined.directory.manifests.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
valueFrom:
configMapKeyRef:
key: reposerver.plugin.tar.exclusions
name: argocd-cmd-params-cm
optional: true
- name: HELM_CACHE_HOME
value: /helm-working-dir
- name: HELM_CONFIG_HOME
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1660,7 +1687,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1672,6 +1699,7 @@ spec:
volumeMounts:
- mountPath: /var/run/argocd
name: var-files
serviceAccountName: argocd-repo-server
volumes:
- configMap:
name: argocd-ssh-known-hosts-cm
@@ -1900,7 +1928,13 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2102,7 +2136,13 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -9033,6 +9033,15 @@ metadata:
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: repo-server
app.kubernetes.io/name: argocd-repo-server
app.kubernetes.io/part-of: argocd
name: argocd-repo-server
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: server
@@ -9683,7 +9692,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -9780,7 +9789,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -9820,7 +9829,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -9945,10 +9954,9 @@ spec:
automountServiceAccountToken: false
containers:
- command:
- entrypoint.sh
- argocd-repo-server
- --redis
- argocd-redis:6379
- sh
- -c
- entrypoint.sh argocd-repo-server --redis argocd-redis:6379
env:
- name: ARGOCD_RECONCILIATION_TIMEOUT
valueFrom:
@@ -10022,13 +10030,31 @@ spec:
key: reposerver.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.max.combined.directory.manifests.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
valueFrom:
configMapKeyRef:
key: reposerver.plugin.tar.exclusions
name: argocd-cmd-params-cm
optional: true
- name: HELM_CACHE_HOME
value: /helm-working-dir
- name: HELM_CONFIG_HOME
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -10077,7 +10103,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -10089,6 +10115,7 @@ spec:
volumeMounts:
- mountPath: /var/run/argocd
name: var-files
serviceAccountName: argocd-repo-server
volumes:
- configMap:
name: argocd-ssh-known-hosts-cm
@@ -10313,7 +10340,13 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -10509,7 +10542,13 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -42,6 +42,15 @@ metadata:
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: repo-server
app.kubernetes.io/name: argocd-repo-server
app.kubernetes.io/part-of: argocd
name: argocd-repo-server
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: server
@@ -607,7 +616,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -704,7 +713,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -744,7 +753,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -869,10 +878,9 @@ spec:
automountServiceAccountToken: false
containers:
- command:
- entrypoint.sh
- argocd-repo-server
- --redis
- argocd-redis:6379
- sh
- -c
- entrypoint.sh argocd-repo-server --redis argocd-redis:6379
env:
- name: ARGOCD_RECONCILIATION_TIMEOUT
valueFrom:
@@ -946,13 +954,31 @@ spec:
key: reposerver.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.max.combined.directory.manifests.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS
valueFrom:
configMapKeyRef:
key: reposerver.plugin.tar.exclusions
name: argocd-cmd-params-cm
optional: true
- name: HELM_CACHE_HOME
value: /helm-working-dir
- name: HELM_CONFIG_HOME
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1001,7 +1027,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.4.6
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1013,6 +1039,7 @@ spec:
volumeMounts:
- mountPath: /var/run/argocd
name: var-files
serviceAccountName: argocd-repo-server
volumes:
- configMap:
name: argocd-ssh-known-hosts-cm
@@ -1237,7 +1264,13 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_SERVER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -1433,7 +1466,13 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS
valueFrom:
configMapKeyRef:
key: otlp.address
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.4.6
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -44,6 +44,7 @@ nav:
- operator-manual/custom_tools.md
- operator-manual/custom-styles.md
- operator-manual/metrics.md
- operator-manual/web_based_terminal.md
- Notification:
- Overview: operator-manual/notifications/index.md
- operator-manual/notifications/triggers.md
@@ -64,6 +65,7 @@ nav:
- operator-manual/notifications/services/mattermost.md
- operator-manual/notifications/services/opsgenie.md
- operator-manual/notifications/services/overview.md
- operator-manual/notifications/services/pagerduty.md
- operator-manual/notifications/services/pushover.md
- operator-manual/notifications/services/rocketchat.md
- operator-manual/notifications/services/slack.md
@@ -75,6 +77,7 @@ nav:
- Introduction: operator-manual/applicationset/index.md
- Installations: operator-manual/applicationset/Getting-Started.md
- Use Cases: operator-manual/applicationset/Use-Cases.md
- Security: operator-manual/applicationset/Security.md
- How ApplicationSet controller interacts with Argo CD: operator-manual/applicationset/Argo-CD-Integration.md
- Generators:
- operator-manual/applicationset/Generators.md
@@ -127,6 +130,7 @@ nav:
- user-guide/compare-options.md
- user-guide/sync-options.md
- user-guide/parameters.md
- user-guide/environment-variables.md
- user-guide/build-environment.md
- user-guide/tracking_strategies.md
- user-guide/resource_tracking.md

View File

@@ -238,9 +238,9 @@ func (m *RevisionMetadataQuery) GetRevision() string {
// ApplicationEventsQuery is a query for application resource events
type ApplicationResourceEventsQuery struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
ResourceNamespace *string `protobuf:"bytes,2,req,name=resourceNamespace" json:"resourceNamespace,omitempty"`
ResourceName *string `protobuf:"bytes,3,req,name=resourceName" json:"resourceName,omitempty"`
ResourceUID *string `protobuf:"bytes,4,req,name=resourceUID" json:"resourceUID,omitempty"`
ResourceNamespace *string `protobuf:"bytes,2,opt,name=resourceNamespace" json:"resourceNamespace,omitempty"`
ResourceName *string `protobuf:"bytes,3,opt,name=resourceName" json:"resourceName,omitempty"`
ResourceUID *string `protobuf:"bytes,4,opt,name=resourceUID" json:"resourceUID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -951,7 +951,7 @@ func (m *ApplicationRollbackRequest) GetPrune() bool {
type ApplicationResourceRequest struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Namespace *string `protobuf:"bytes,2,req,name=namespace" json:"namespace,omitempty"`
Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
ResourceName *string `protobuf:"bytes,3,req,name=resourceName" json:"resourceName,omitempty"`
Version *string `protobuf:"bytes,4,req,name=version" json:"version,omitempty"`
Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"`
@@ -1038,7 +1038,7 @@ func (m *ApplicationResourceRequest) GetKind() string {
type ApplicationResourcePatchRequest struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Namespace *string `protobuf:"bytes,2,req,name=namespace" json:"namespace,omitempty"`
Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
ResourceName *string `protobuf:"bytes,3,req,name=resourceName" json:"resourceName,omitempty"`
Version *string `protobuf:"bytes,4,req,name=version" json:"version,omitempty"`
Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"`
@@ -1141,7 +1141,7 @@ func (m *ApplicationResourcePatchRequest) GetPatchType() string {
type ApplicationResourceDeleteRequest struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Namespace *string `protobuf:"bytes,2,req,name=namespace" json:"namespace,omitempty"`
Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
ResourceName *string `protobuf:"bytes,3,req,name=resourceName" json:"resourceName,omitempty"`
Version *string `protobuf:"bytes,4,req,name=version" json:"version,omitempty"`
Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"`
@@ -1244,7 +1244,7 @@ func (m *ApplicationResourceDeleteRequest) GetOrphan() bool {
type ResourceActionRunRequest struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Namespace *string `protobuf:"bytes,2,req,name=namespace" json:"namespace,omitempty"`
Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
ResourceName *string `protobuf:"bytes,3,req,name=resourceName" json:"resourceName,omitempty"`
Version *string `protobuf:"bytes,4,req,name=version" json:"version,omitempty"`
Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"`
@@ -1433,7 +1433,7 @@ func (m *ApplicationResourceResponse) GetManifest() string {
type ApplicationPodLogsQuery struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Namespace *string `protobuf:"bytes,2,req,name=namespace" json:"namespace,omitempty"`
Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
PodName *string `protobuf:"bytes,3,opt,name=podName" json:"podName,omitempty"`
Container *string `protobuf:"bytes,4,opt,name=container" json:"container,omitempty"`
SinceSeconds *int64 `protobuf:"varint,5,opt,name=sinceSeconds" json:"sinceSeconds,omitempty"`
@@ -2100,147 +2100,147 @@ func init() {
}
var fileDescriptor_df6e82b174b5eaec = []byte{
// 2237 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x8f, 0x1c, 0x47,
0x15, 0x57, 0xed, 0xe7, 0xcc, 0x1b, 0x7f, 0x56, 0x62, 0xd3, 0x69, 0xaf, 0x37, 0xab, 0xf2, 0xd7,
0x7a, 0xed, 0x9d, 0xb1, 0x07, 0x0b, 0x39, 0x1b, 0x10, 0x38, 0x89, 0xd9, 0x38, 0xec, 0x6e, 0x4c,
0xaf, 0x8d, 0x51, 0x38, 0x40, 0xa5, 0xbb, 0x66, 0xb6, 0xd9, 0x9e, 0xae, 0x76, 0x77, 0xcf, 0x58,
0x23, 0xe3, 0x4b, 0x10, 0x37, 0x04, 0x12, 0xe4, 0x80, 0x10, 0x42, 0x88, 0x28, 0x12, 0x37, 0xe0,
0x12, 0x21, 0x71, 0x81, 0x0b, 0x1f, 0x12, 0x07, 0x04, 0xff, 0x00, 0x58, 0x9c, 0xb8, 0x70, 0xe5,
0x88, 0xaa, 0xba, 0xba, 0xbb, 0x7a, 0x76, 0xa6, 0x67, 0xcc, 0x4e, 0x14, 0xdf, 0xfa, 0xd5, 0x54,
0xbd, 0xf7, 0xab, 0xf7, 0x59, 0xef, 0x69, 0xe0, 0x7c, 0xc4, 0xc2, 0x1e, 0x0b, 0x1b, 0x34, 0x08,
0x3c, 0xd7, 0xa6, 0xb1, 0xcb, 0x7d, 0xfd, 0xbb, 0x1e, 0x84, 0x3c, 0xe6, 0xb8, 0xa6, 0x2d, 0x99,
0x4b, 0x6d, 0xce, 0xdb, 0x1e, 0x6b, 0xd0, 0xc0, 0x6d, 0x50, 0xdf, 0xe7, 0xb1, 0x5c, 0x8e, 0x92,
0xad, 0x26, 0xd9, 0xbf, 0x19, 0xd5, 0x5d, 0x2e, 0x7f, 0xb5, 0x79, 0xc8, 0x1a, 0xbd, 0xeb, 0x8d,
0x36, 0xf3, 0x59, 0x48, 0x63, 0xe6, 0xa8, 0x3d, 0x37, 0xf2, 0x3d, 0x1d, 0x6a, 0xef, 0xb9, 0x3e,
0x0b, 0xfb, 0x8d, 0x60, 0xbf, 0x2d, 0x16, 0xa2, 0x46, 0x87, 0xc5, 0x74, 0xd8, 0xa9, 0xad, 0xb6,
0x1b, 0xef, 0x75, 0xdf, 0xad, 0xdb, 0xbc, 0xd3, 0xa0, 0x61, 0x9b, 0x07, 0x21, 0xff, 0xa6, 0xfc,
0x58, 0xb7, 0x9d, 0x46, 0xaf, 0x99, 0x33, 0xd0, 0xef, 0xd2, 0xbb, 0x4e, 0xbd, 0x60, 0x8f, 0x1e,
0xe4, 0x76, 0x7b, 0x0c, 0xb7, 0x90, 0x05, 0x5c, 0xe9, 0x46, 0x7e, 0xba, 0x31, 0x0f, 0xfb, 0xda,
0x67, 0xc2, 0x86, 0x7c, 0x84, 0xe0, 0xc4, 0xad, 0x5c, 0xde, 0x97, 0xbb, 0x2c, 0xec, 0x63, 0x0c,
0x73, 0x3e, 0xed, 0x30, 0x03, 0xad, 0xa0, 0xd5, 0xaa, 0x25, 0xbf, 0xb1, 0x01, 0x8b, 0x21, 0x6b,
0x85, 0x2c, 0xda, 0x33, 0x66, 0xe4, 0x72, 0x4a, 0x62, 0x13, 0x2a, 0x42, 0x38, 0xb3, 0xe3, 0xc8,
0x98, 0x5d, 0x99, 0x5d, 0xad, 0x5a, 0x19, 0x8d, 0x57, 0xe1, 0x78, 0xc8, 0x22, 0xde, 0x0d, 0x6d,
0xf6, 0x15, 0x16, 0x46, 0x2e, 0xf7, 0x8d, 0x39, 0x79, 0x7a, 0x70, 0x59, 0x70, 0x89, 0x98, 0xc7,
0xec, 0x98, 0x87, 0xc6, 0xbc, 0xdc, 0x92, 0xd1, 0x02, 0x8f, 0x00, 0x6e, 0x2c, 0x24, 0x78, 0xc4,
0x37, 0x79, 0x19, 0xaa, 0x3b, 0xdc, 0x61, 0x23, 0x01, 0x93, 0x4d, 0x38, 0x65, 0xb1, 0x9e, 0x2b,
0x98, 0x6f, 0xb3, 0x98, 0x3a, 0x34, 0xa6, 0x83, 0x9b, 0x67, 0xb2, 0xdb, 0x99, 0x50, 0x09, 0xd5,
0x66, 0x63, 0x46, 0xae, 0x67, 0x34, 0xf9, 0x05, 0x82, 0x65, 0x4d, 0x45, 0x96, 0x02, 0x7e, 0xbb,
0xc7, 0xfc, 0x38, 0x1a, 0xcd, 0xf2, 0x2a, 0x9c, 0x4c, 0xef, 0xb8, 0x43, 0x3b, 0x2c, 0x0a, 0xa8,
0xcd, 0x14, 0xef, 0x83, 0x3f, 0x60, 0x02, 0x47, 0xf4, 0x45, 0x63, 0x56, 0x6e, 0x2c, 0xac, 0xe1,
0x15, 0xa8, 0xa5, 0xf4, 0xfd, 0x3b, 0x6f, 0x18, 0x73, 0x72, 0x8b, 0xbe, 0x44, 0xde, 0x02, 0x43,
0x43, 0xba, 0x4d, 0x7d, 0xb7, 0xc5, 0xa2, 0x78, 0xd2, 0x6b, 0xa3, 0xc2, 0xb5, 0x4f, 0xc1, 0x0b,
0xc5, 0x5b, 0x07, 0xdc, 0x8f, 0x18, 0xf9, 0x2d, 0x2a, 0xc8, 0x78, 0x3d, 0x64, 0x34, 0x66, 0x16,
0x7b, 0xd8, 0x65, 0x51, 0x8c, 0xf7, 0x41, 0x8f, 0x34, 0x29, 0xaa, 0xd6, 0xbc, 0x53, 0xcf, 0x5d,
0xb5, 0x9e, 0xba, 0xaa, 0xfc, 0xf8, 0xba, 0xed, 0xd4, 0x7b, 0xcd, 0x7a, 0xb0, 0xdf, 0xae, 0x0b,
0xc7, 0xaf, 0xeb, 0x81, 0x9b, 0x3a, 0x7e, 0x5d, 0x07, 0xa1, 0x73, 0xc7, 0xa7, 0x61, 0xa1, 0x1b,
0x44, 0x2c, 0x8c, 0x25, 0xf4, 0x8a, 0xa5, 0x28, 0x71, 0xa9, 0x1e, 0xf5, 0x5c, 0x87, 0xc6, 0x42,
0x8d, 0xe2, 0x97, 0x8c, 0x26, 0x1f, 0x14, 0xd1, 0xdf, 0x0f, 0x9c, 0x4f, 0x0a, 0xbd, 0x8e, 0x72,
0x66, 0x00, 0x65, 0xaf, 0x00, 0xf2, 0x0d, 0xe6, 0xb1, 0x1c, 0xe4, 0x30, 0x33, 0x1a, 0xb0, 0x68,
0xd3, 0xc8, 0xa6, 0x4e, 0xca, 0x2a, 0x25, 0x85, 0x13, 0x06, 0x21, 0x0f, 0x68, 0x5b, 0x72, 0xba,
0xcb, 0x3d, 0xd7, 0xee, 0x4b, 0xa5, 0x54, 0xad, 0x83, 0x3f, 0x90, 0x73, 0x50, 0xdb, 0xed, 0xfb,
0xf6, 0xdb, 0x81, 0x4c, 0x88, 0xf8, 0x45, 0x98, 0x77, 0x63, 0xd6, 0x89, 0x0c, 0x24, 0xa3, 0x3a,
0x21, 0xc8, 0x7f, 0xe7, 0xe0, 0xb4, 0x86, 0x4e, 0x1c, 0x28, 0xc3, 0x56, 0xe2, 0x62, 0xc2, 0x82,
0x4e, 0xd8, 0xb7, 0xba, 0xbe, 0xb2, 0x93, 0xa2, 0x84, 0xe0, 0x20, 0xec, 0xfa, 0x4c, 0xe6, 0x8a,
0x8a, 0x95, 0x10, 0xb8, 0x05, 0x95, 0x28, 0x16, 0x29, 0xb0, 0xdd, 0x97, 0x19, 0xa2, 0xd6, 0x7c,
0xeb, 0x70, 0xb6, 0x11, 0xd0, 0x77, 0x15, 0x47, 0x2b, 0xe3, 0x8d, 0x1f, 0x42, 0x35, 0x8d, 0xa9,
0xc8, 0x58, 0x5c, 0x99, 0x5d, 0xad, 0x35, 0x77, 0x0f, 0x2f, 0xe8, 0xed, 0x40, 0xa4, 0x6f, 0x2d,
0x7f, 0x58, 0xb9, 0x14, 0xbc, 0x04, 0xd5, 0x8e, 0x0a, 0xd6, 0xc8, 0xa8, 0x48, 0x6d, 0xe7, 0x0b,
0xf8, 0xab, 0x30, 0xef, 0xfa, 0x2d, 0x1e, 0x19, 0x55, 0x09, 0xe6, 0xb5, 0xc3, 0x81, 0xb9, 0xe3,
0xb7, 0xb8, 0x95, 0x30, 0xc4, 0x0f, 0xe1, 0x68, 0xc8, 0xe2, 0xb0, 0x9f, 0x6a, 0xc1, 0x00, 0xa9,
0xd7, 0x2f, 0x1d, 0x4e, 0x82, 0xa5, 0xb3, 0xb4, 0x8a, 0x12, 0xf0, 0x06, 0xd4, 0xa2, 0xdc, 0xc7,
0x8c, 0x9a, 0x14, 0x68, 0x14, 0x18, 0x69, 0x3e, 0x68, 0xe9, 0x9b, 0xc9, 0xaf, 0x11, 0x2c, 0x1d,
0x88, 0xde, 0xdd, 0x80, 0x95, 0x3a, 0x20, 0x85, 0xb9, 0x28, 0x60, 0xb6, 0x4c, 0xbd, 0xb5, 0xe6,
0xf6, 0xd4, 0xc2, 0x59, 0xca, 0x95, 0xac, 0x4b, 0x33, 0x0e, 0x85, 0x4f, 0x69, 0x87, 0xee, 0xd2,
0xd8, 0xde, 0x2b, 0x43, 0x2b, 0x5c, 0x5f, 0xec, 0x51, 0x95, 0x22, 0x21, 0x84, 0x7f, 0xc8, 0x8f,
0x7b, 0xfd, 0x20, 0x2d, 0x0d, 0xf9, 0x02, 0xf1, 0xc1, 0xd4, 0xd3, 0x0c, 0xf7, 0xbc, 0x77, 0xa9,
0xbd, 0x5f, 0x26, 0xe5, 0x18, 0xcc, 0xb8, 0x8e, 0x14, 0x31, 0x6b, 0xcd, 0xb8, 0xce, 0xb3, 0x05,
0xa2, 0x78, 0x33, 0x98, 0x43, 0x0a, 0x62, 0x99, 0xc0, 0x25, 0xa8, 0xfa, 0x03, 0x45, 0x30, 0x5f,
0x98, 0xa8, 0xf8, 0x19, 0xb0, 0xd8, 0xcb, 0x5e, 0x10, 0xe2, 0xe7, 0x94, 0x14, 0x20, 0xdb, 0x21,
0xef, 0x06, 0xea, 0xd9, 0x90, 0x10, 0x02, 0xc5, 0xbe, 0xeb, 0x3b, 0xc6, 0x42, 0x82, 0x42, 0x7c,
0x93, 0xff, 0x20, 0x78, 0x79, 0x08, 0xf0, 0xb1, 0x46, 0x79, 0x2e, 0xd0, 0xe7, 0xae, 0xb1, 0x38,
0xd2, 0x35, 0x2a, 0x83, 0xae, 0xf1, 0x6f, 0x04, 0x2b, 0x43, 0x6e, 0x3c, 0xbe, 0xa4, 0x3c, 0x37,
0x57, 0x6e, 0xf1, 0xd0, 0x66, 0xc6, 0x62, 0xe2, 0x7f, 0x92, 0x10, 0xde, 0xca, 0xc3, 0x60, 0x8f,
0xfa, 0x46, 0x25, 0xf1, 0xd6, 0x84, 0x22, 0x7f, 0x41, 0x60, 0xa4, 0x37, 0xbc, 0x65, 0xcb, 0xfb,
0x76, 0xfd, 0xe7, 0xff, 0x92, 0xa7, 0x61, 0x81, 0x4a, 0xb4, 0xca, 0xb0, 0x8a, 0x22, 0xdf, 0x41,
0x70, 0xa6, 0x78, 0x9d, 0x68, 0xcb, 0x8d, 0xe2, 0xf4, 0x25, 0x86, 0x5b, 0xb0, 0x98, 0xec, 0x4c,
0x0a, 0x74, 0xad, 0xb9, 0x75, 0xd8, 0xb4, 0x5d, 0x50, 0x5d, 0xca, 0x9c, 0xbc, 0x02, 0x67, 0x86,
0x46, 0xbb, 0x82, 0x61, 0x42, 0x25, 0x2d, 0x55, 0x4a, 0xb9, 0x19, 0x4d, 0xfe, 0x38, 0x5b, 0xcc,
0x7e, 0xdc, 0xd9, 0xe2, 0xed, 0x92, 0x37, 0x73, 0xb9, 0x41, 0x0c, 0x58, 0x0c, 0xb8, 0xa3, 0x6c,
0x21, 0x5b, 0x10, 0x45, 0x8a, 0x73, 0x36, 0xf7, 0x63, 0x2a, 0x3a, 0x31, 0xd5, 0x60, 0xe4, 0x0b,
0xc2, 0x90, 0x91, 0xeb, 0xdb, 0x6c, 0x97, 0xd9, 0xdc, 0x77, 0x22, 0x69, 0x91, 0x59, 0xab, 0xb0,
0x86, 0xdf, 0x84, 0xaa, 0xa4, 0xef, 0xb9, 0x1d, 0x26, 0xfb, 0x8c, 0x5a, 0x73, 0xad, 0x9e, 0xb4,
0x79, 0x75, 0xbd, 0xcd, 0xcb, 0x75, 0x28, 0xda, 0xbc, 0x7a, 0xef, 0x7a, 0x5d, 0x9c, 0xb0, 0xf2,
0xc3, 0x02, 0x4b, 0x4c, 0x5d, 0x6f, 0xcb, 0xf5, 0xe5, 0xf3, 0x41, 0x88, 0xca, 0x17, 0x84, 0xb1,
0x5b, 0xdc, 0xf3, 0xf8, 0xa3, 0xd4, 0x77, 0x13, 0x4a, 0x9c, 0xea, 0xfa, 0xb1, 0xeb, 0x49, 0xf9,
0xd5, 0xe4, 0x06, 0xd9, 0x82, 0x3c, 0xe5, 0x7a, 0x31, 0x0b, 0x65, 0x81, 0xae, 0x5a, 0x8a, 0xca,
0xdc, 0xa9, 0x96, 0xf4, 0x3d, 0x69, 0xcc, 0x24, 0x8e, 0x77, 0x44, 0x77, 0xbc, 0x41, 0x67, 0x3e,
0x2a, 0x7f, 0x2c, 0x3a, 0xb3, 0x6c, 0xe4, 0x58, 0xcf, 0xe5, 0xdd, 0xc8, 0x38, 0x96, 0x94, 0xb1,
0x94, 0x26, 0xbf, 0x43, 0x50, 0xd9, 0xe2, 0xed, 0xdb, 0x7e, 0x1c, 0xf6, 0xe5, 0x7b, 0x93, 0xfb,
0x31, 0xf3, 0x53, 0x8b, 0xa7, 0xa4, 0x50, 0x63, 0xec, 0x76, 0xd8, 0x6e, 0x4c, 0x3b, 0x81, 0xaa,
0xb8, 0xcf, 0xa4, 0xc6, 0xec, 0xb0, 0xb8, 0x9a, 0x47, 0xa3, 0x58, 0x46, 0x5d, 0xc5, 0x92, 0xdf,
0xe2, 0x12, 0xd9, 0x86, 0xdd, 0x38, 0x54, 0x21, 0x57, 0x58, 0xd3, 0x9d, 0x64, 0x3e, 0xc1, 0xa6,
0x48, 0xd2, 0x80, 0x97, 0xb2, 0x47, 0xd8, 0x3d, 0x16, 0x76, 0x5c, 0x9f, 0x96, 0xe6, 0x40, 0x72,
0xbd, 0xe0, 0xf8, 0xe2, 0x55, 0xf2, 0xc0, 0xf5, 0x1d, 0xfe, 0x68, 0xb4, 0x03, 0x93, 0xbf, 0x15,
0x7b, 0x45, 0xed, 0x4c, 0x16, 0x2f, 0x6f, 0xc2, 0x51, 0x11, 0x59, 0x3d, 0xa6, 0x7e, 0x50, 0xc1,
0x4b, 0x0a, 0x41, 0x39, 0x94, 0x87, 0x55, 0x3c, 0x88, 0xb7, 0xe0, 0x38, 0x8d, 0x22, 0xb7, 0xed,
0x33, 0x27, 0xe5, 0x35, 0x33, 0x31, 0xaf, 0xc1, 0xa3, 0x49, 0x13, 0x21, 0x77, 0x28, 0x9d, 0xa7,
0x24, 0xf9, 0x36, 0x82, 0x53, 0x43, 0x99, 0x64, 0xfe, 0x87, 0xb4, 0x74, 0x26, 0x1a, 0x79, 0x7b,
0x8f, 0x39, 0x5d, 0x2f, 0x0d, 0xe1, 0x8c, 0x16, 0xbf, 0x39, 0xdd, 0xc4, 0x02, 0x2a, 0x9d, 0x66,
0x34, 0x5e, 0x06, 0xe8, 0x50, 0xbf, 0x4b, 0x3d, 0x09, 0x61, 0x4e, 0x42, 0xd0, 0x56, 0xc8, 0x12,
0x98, 0xc3, 0xcc, 0xa7, 0xda, 0xd2, 0x5f, 0x21, 0x38, 0x96, 0xa6, 0x26, 0x65, 0x9f, 0x55, 0x38,
0xae, 0xa9, 0x61, 0x27, 0x37, 0xd5, 0xe0, 0xf2, 0x60, 0xda, 0x41, 0xc5, 0xb4, 0x93, 0xda, 0x79,
0xb6, 0x38, 0x0d, 0xe9, 0x15, 0xe6, 0x19, 0x13, 0xe7, 0xfd, 0x2c, 0x50, 0xc9, 0xb7, 0xc0, 0xd8,
0xa6, 0x3e, 0x6d, 0x33, 0x27, 0x03, 0x9e, 0x39, 0xc9, 0x37, 0xf4, 0xd6, 0xeb, 0xd0, 0x8d, 0x4e,
0x56, 0xf6, 0xdd, 0x56, 0x4b, 0xb5, 0x71, 0xcd, 0x7f, 0x2e, 0x03, 0xd6, 0x8d, 0xca, 0xc2, 0x9e,
0x6b, 0x33, 0xfc, 0x03, 0x04, 0x73, 0xa2, 0xca, 0xe0, 0xb3, 0xa3, 0x7c, 0x48, 0x2a, 0xd7, 0x9c,
0xde, 0x3b, 0x5a, 0x48, 0x23, 0x4b, 0xef, 0xfd, 0xfd, 0x5f, 0x3f, 0x9c, 0x39, 0x8d, 0x5f, 0x94,
0x73, 0xb7, 0xde, 0x75, 0x7d, 0x06, 0x16, 0xe1, 0xef, 0x22, 0xc0, 0xaa, 0xf4, 0x69, 0xa3, 0x17,
0x7c, 0x65, 0x14, 0xc4, 0x21, 0x23, 0x1a, 0xf3, 0xac, 0x96, 0x86, 0xea, 0x36, 0x0f, 0x99, 0x48,
0x3a, 0x72, 0x83, 0x04, 0xb0, 0x26, 0x01, 0x9c, 0xc7, 0x64, 0x18, 0x80, 0xc6, 0x63, 0x61, 0xf4,
0x27, 0x0d, 0x96, 0xc8, 0xfd, 0x39, 0x82, 0xf9, 0x07, 0xf2, 0xf1, 0x35, 0x46, 0x49, 0xbb, 0x53,
0x53, 0x92, 0x14, 0x27, 0xd1, 0x92, 0x73, 0x12, 0xe9, 0x59, 0x7c, 0x26, 0x45, 0x1a, 0xc5, 0x21,
0xa3, 0x9d, 0x02, 0xe0, 0x6b, 0x08, 0x7f, 0x88, 0x60, 0x21, 0x19, 0xce, 0xe0, 0x0b, 0xa3, 0x50,
0x16, 0x86, 0x37, 0xe6, 0xf4, 0x26, 0x1d, 0xe4, 0xb2, 0xc4, 0x78, 0x8e, 0x0c, 0x35, 0xe7, 0x46,
0x61, 0x0e, 0xf2, 0x3e, 0x82, 0xd9, 0x4d, 0x36, 0xd6, 0xdf, 0xa6, 0x08, 0xee, 0x80, 0x02, 0x87,
0x98, 0x1a, 0x7f, 0x80, 0xe0, 0xa5, 0x4d, 0x16, 0x0f, 0xcf, 0xe5, 0x78, 0x75, 0x7c, 0x82, 0x55,
0x6e, 0x77, 0x65, 0x82, 0x9d, 0x59, 0x12, 0x6b, 0x48, 0x64, 0x97, 0xf1, 0xa5, 0x32, 0x27, 0x14,
0x0d, 0xf1, 0x23, 0x85, 0xe3, 0xcf, 0x08, 0x4e, 0x0c, 0x0e, 0x39, 0x71, 0x31, 0xfb, 0x0f, 0x9d,
0x81, 0x9a, 0x3b, 0x87, 0x4d, 0x28, 0x45, 0xa6, 0xe4, 0x96, 0x44, 0xfe, 0x2a, 0x7e, 0xa5, 0x0c,
0x79, 0x3a, 0xf7, 0x89, 0x1a, 0x8f, 0xd3, 0xcf, 0x27, 0x72, 0x5a, 0x2e, 0x61, 0xbf, 0x87, 0xe0,
0xc8, 0x26, 0x8b, 0xb7, 0xb3, 0xb1, 0xc7, 0x48, 0xb7, 0x2d, 0xcc, 0x35, 0xcd, 0xa5, 0xba, 0x36,
0xd4, 0x4e, 0x7f, 0xca, 0x54, 0xba, 0x2e, 0x81, 0x5d, 0xc2, 0x17, 0xca, 0x80, 0xe5, 0xa3, 0x96,
0xdf, 0x23, 0x58, 0x48, 0xc6, 0x0a, 0xa3, 0xc5, 0x17, 0x86, 0x86, 0xd3, 0x74, 0xcc, 0xdb, 0x12,
0xeb, 0xe7, 0xcd, 0x6b, 0xc3, 0xb1, 0xea, 0xe7, 0x53, 0xad, 0xd5, 0xe5, 0x05, 0x8a, 0x11, 0xf5,
0x11, 0x02, 0xc8, 0x47, 0x23, 0xf8, 0x72, 0xf9, 0x3d, 0xb4, 0xf1, 0x89, 0x39, 0xdd, 0xe1, 0x08,
0xa9, 0xcb, 0xfb, 0xac, 0x9a, 0x2b, 0xa5, 0xee, 0x1c, 0x30, 0x7b, 0x23, 0x19, 0xa3, 0xfc, 0x0c,
0xc1, 0xbc, 0xec, 0xc5, 0xf1, 0xf9, 0x51, 0x98, 0xf5, 0x56, 0x7d, 0x9a, 0xaa, 0xbf, 0x28, 0xa1,
0xae, 0x34, 0xcb, 0x72, 0xc2, 0x06, 0x5a, 0xc3, 0x3d, 0x58, 0x48, 0x7a, 0xe7, 0xd1, 0xee, 0x51,
0xe8, 0xad, 0xcd, 0x95, 0x92, 0x1a, 0x95, 0x78, 0xa8, 0x4a, 0x47, 0x6b, 0xe3, 0xd2, 0xd1, 0x9c,
0xc8, 0x18, 0xf8, 0x5c, 0x59, 0x3e, 0xf9, 0x18, 0x14, 0x73, 0x45, 0xa2, 0xbb, 0x40, 0x56, 0xc6,
0xa5, 0x24, 0xa1, 0x9d, 0x1f, 0x21, 0x38, 0x31, 0xf8, 0xa4, 0xc1, 0x67, 0x06, 0xd2, 0x91, 0xfe,
0x46, 0x33, 0x8b, 0x5a, 0x1c, 0xf5, 0x1c, 0x22, 0x5f, 0x90, 0x28, 0x36, 0xf0, 0xcd, 0xb1, 0x91,
0xb1, 0x93, 0x06, 0xb4, 0x60, 0xb4, 0x9e, 0x4f, 0x58, 0x7f, 0x83, 0xe0, 0x48, 0xca, 0xf7, 0x5e,
0xc8, 0x58, 0x39, 0xac, 0xe9, 0x05, 0x82, 0x90, 0x45, 0x3e, 0x2b, 0xe1, 0x7f, 0x06, 0xdf, 0x98,
0x10, 0x7e, 0x0a, 0x7b, 0x3d, 0x16, 0x48, 0xff, 0x80, 0xe0, 0xe4, 0x83, 0xc4, 0xef, 0x3f, 0x21,
0xfc, 0xaf, 0x4b, 0xfc, 0x9f, 0xc3, 0xaf, 0x96, 0x3c, 0x39, 0xc6, 0x5d, 0xe3, 0x1a, 0xc2, 0xbf,
0x44, 0x50, 0x49, 0xa7, 0x93, 0xf8, 0xd2, 0xc8, 0xc0, 0x28, 0xce, 0x2f, 0xa7, 0xe9, 0xcc, 0xaa,
0xbe, 0x92, 0xf3, 0xa5, 0x55, 0x4a, 0xc9, 0x17, 0x0e, 0xfd, 0x3e, 0x02, 0x9c, 0xf5, 0x1a, 0x59,
0xf7, 0x81, 0x2f, 0x16, 0x44, 0x8d, 0x6c, 0x2a, 0xcd, 0x4b, 0x63, 0xf7, 0x15, 0xab, 0xd4, 0x5a,
0x69, 0x95, 0xe2, 0x99, 0xfc, 0xef, 0x21, 0xa8, 0x6d, 0xb2, 0xec, 0x39, 0x5c, 0xa2, 0xcb, 0xe2,
0x68, 0xd6, 0x5c, 0x1d, 0xbf, 0x51, 0x21, 0xba, 0x2a, 0x11, 0x5d, 0xc4, 0xe5, 0xaa, 0x4a, 0x01,
0xfc, 0x04, 0xc1, 0xd1, 0xbb, 0xba, 0x8b, 0xe2, 0xab, 0xe3, 0x24, 0x15, 0x32, 0xf9, 0xe4, 0xb8,
0x3e, 0x2d, 0x71, 0xad, 0x93, 0x89, 0x70, 0x6d, 0xa8, 0x19, 0xe9, 0x4f, 0x11, 0xbc, 0xa0, 0xf7,
0x0f, 0x6a, 0x9a, 0xf6, 0xff, 0xea, 0xad, 0x64, 0x28, 0x47, 0x6e, 0x48, 0x7c, 0x75, 0x7c, 0x75,
0x12, 0x7c, 0x0d, 0x35, 0x62, 0xc3, 0x3f, 0x46, 0x70, 0x52, 0xce, 0x2a, 0x75, 0xc6, 0x03, 0x25,
0x66, 0xd4, 0x64, 0x73, 0x82, 0x12, 0xa3, 0xf2, 0x0f, 0x79, 0x26, 0x50, 0x1b, 0x6a, 0x0e, 0x89,
0xbf, 0x8f, 0xe0, 0x58, 0x5a, 0xd4, 0x94, 0x75, 0xd7, 0xc7, 0x29, 0xee, 0x59, 0x8b, 0xa0, 0x72,
0xb7, 0xb5, 0xc9, 0xdc, 0xed, 0x43, 0x04, 0x8b, 0x6a, 0x96, 0x58, 0xf2, 0x54, 0xd0, 0x86, 0x8d,
0xe6, 0xa9, 0xc2, 0xae, 0x74, 0x90, 0x45, 0xbe, 0x26, 0xc5, 0xde, 0xc7, 0x8d, 0x32, 0xb1, 0x01,
0x77, 0xa2, 0xc6, 0x63, 0x35, 0x45, 0x7a, 0xd2, 0xf0, 0x78, 0x3b, 0x7a, 0x87, 0xe0, 0xd2, 0x82,
0x28, 0xf6, 0x5c, 0x43, 0xaf, 0x7d, 0xf1, 0x4f, 0x4f, 0x97, 0xd1, 0x5f, 0x9f, 0x2e, 0xa3, 0x7f,
0x3c, 0x5d, 0x46, 0xef, 0xdc, 0x9c, 0xec, 0xff, 0x1f, 0xb6, 0xe7, 0x32, 0x3f, 0xd6, 0xd9, 0xfe,
0x2f, 0x00, 0x00, 0xff, 0xff, 0xef, 0x54, 0xd5, 0x40, 0xe5, 0x22, 0x00, 0x00,
// 2236 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x8f, 0x1b, 0x49,
0x15, 0x57, 0xcd, 0xa7, 0xfd, 0x9c, 0xcf, 0xda, 0x4d, 0xe8, 0xed, 0x4c, 0x66, 0x47, 0x95, 0xaf,
0xc9, 0x24, 0x63, 0x27, 0x26, 0x42, 0xd9, 0x59, 0x10, 0x64, 0x77, 0xc3, 0x6c, 0x96, 0x99, 0xd9,
0xd0, 0x93, 0x10, 0xb4, 0x1c, 0xa0, 0xb6, 0xbb, 0xec, 0x69, 0xc6, 0xee, 0xea, 0x74, 0xb7, 0x1d,
0x59, 0x21, 0x97, 0x45, 0xdc, 0x10, 0x48, 0xb0, 0x07, 0x84, 0x10, 0x42, 0xac, 0x56, 0xe2, 0x06,
0x5c, 0x56, 0x48, 0x5c, 0xe0, 0xc2, 0x87, 0xc4, 0x01, 0xc1, 0x3f, 0x00, 0x11, 0x27, 0x2e, 0x5c,
0x39, 0xa2, 0xaa, 0xae, 0x6a, 0x57, 0x7b, 0xec, 0xb6, 0xc3, 0x78, 0xb5, 0xb9, 0xf5, 0x2b, 0x57,
0xbd, 0xf7, 0xab, 0x57, 0xbf, 0x7a, 0xaf, 0xde, 0x93, 0xe1, 0x7c, 0xcc, 0xa2, 0x2e, 0x8b, 0x6a,
0x34, 0x0c, 0x5b, 0xbe, 0x4b, 0x13, 0x9f, 0x07, 0xe6, 0x77, 0x35, 0x8c, 0x78, 0xc2, 0x71, 0xc5,
0x18, 0xb2, 0x97, 0x9a, 0x9c, 0x37, 0x5b, 0xac, 0x46, 0x43, 0xbf, 0x46, 0x83, 0x80, 0x27, 0x72,
0x38, 0x4e, 0xa7, 0xda, 0x64, 0xff, 0x66, 0x5c, 0xf5, 0xb9, 0xfc, 0xd5, 0xe5, 0x11, 0xab, 0x75,
0xaf, 0xd7, 0x9a, 0x2c, 0x60, 0x11, 0x4d, 0x98, 0xa7, 0xe6, 0xdc, 0xe8, 0xcf, 0x69, 0x53, 0x77,
0xcf, 0x0f, 0x58, 0xd4, 0xab, 0x85, 0xfb, 0x4d, 0x31, 0x10, 0xd7, 0xda, 0x2c, 0xa1, 0xc3, 0x56,
0x6d, 0x35, 0xfd, 0x64, 0xaf, 0xf3, 0x6e, 0xd5, 0xe5, 0xed, 0x1a, 0x8d, 0x9a, 0x3c, 0x8c, 0xf8,
0x37, 0xe5, 0xc7, 0xba, 0xeb, 0xd5, 0xba, 0xf5, 0xbe, 0x02, 0x73, 0x2f, 0xdd, 0xeb, 0xb4, 0x15,
0xee, 0xd1, 0x83, 0xda, 0x6e, 0x8f, 0xd1, 0x16, 0xb1, 0x90, 0x2b, 0xdf, 0xc8, 0x4f, 0x3f, 0xe1,
0x51, 0xcf, 0xf8, 0x4c, 0xd5, 0x90, 0x8f, 0x10, 0x9c, 0xb8, 0xd5, 0xb7, 0xf7, 0xe5, 0x0e, 0x8b,
0x7a, 0x18, 0xc3, 0x5c, 0x40, 0xdb, 0xcc, 0x42, 0x2b, 0x68, 0xb5, 0xec, 0xc8, 0x6f, 0x6c, 0xc1,
0x62, 0xc4, 0x1a, 0x11, 0x8b, 0xf7, 0xac, 0x19, 0x39, 0xac, 0x45, 0x6c, 0x43, 0x49, 0x18, 0x67,
0x6e, 0x12, 0x5b, 0xb3, 0x2b, 0xb3, 0xab, 0x65, 0x27, 0x93, 0xf1, 0x2a, 0x1c, 0x8f, 0x58, 0xcc,
0x3b, 0x91, 0xcb, 0xbe, 0xc2, 0xa2, 0xd8, 0xe7, 0x81, 0x35, 0x27, 0x57, 0x0f, 0x0e, 0x0b, 0x2d,
0x31, 0x6b, 0x31, 0x37, 0xe1, 0x91, 0x35, 0x2f, 0xa7, 0x64, 0xb2, 0xc0, 0x23, 0x80, 0x5b, 0x0b,
0x29, 0x1e, 0xf1, 0x4d, 0x5e, 0x86, 0xf2, 0x0e, 0xf7, 0xd8, 0x48, 0xc0, 0x64, 0x13, 0x4e, 0x39,
0xac, 0xeb, 0x0b, 0xe5, 0xdb, 0x2c, 0xa1, 0x1e, 0x4d, 0xe8, 0xe0, 0xe4, 0x99, 0x6c, 0x77, 0x36,
0x94, 0x22, 0x35, 0xd9, 0x9a, 0x91, 0xe3, 0x99, 0x4c, 0x7e, 0x81, 0x60, 0xd9, 0x70, 0x91, 0xa3,
0x80, 0xdf, 0xee, 0xb2, 0x20, 0x89, 0x47, 0xab, 0xbc, 0x0a, 0x27, 0xf5, 0x1e, 0x77, 0x68, 0x9b,
0xc5, 0x21, 0x75, 0x99, 0x72, 0xdd, 0xc1, 0x1f, 0x30, 0x81, 0x23, 0xe6, 0xa0, 0x35, 0x2b, 0x27,
0xe6, 0xc6, 0xf0, 0x0a, 0x54, 0xb4, 0x7c, 0xff, 0xce, 0x1b, 0xca, 0x91, 0xe6, 0x10, 0x79, 0x0b,
0x2c, 0x03, 0xe9, 0x36, 0x0d, 0xfc, 0x06, 0x8b, 0x93, 0x49, 0xb7, 0x8d, 0x72, 0xdb, 0x3e, 0x05,
0x2f, 0xe4, 0x77, 0x1d, 0xf2, 0x20, 0x66, 0xe4, 0xb7, 0x28, 0x67, 0xe3, 0xf5, 0x88, 0xd1, 0x84,
0x39, 0xec, 0x61, 0x87, 0xc5, 0x09, 0xde, 0x07, 0xf3, 0xa6, 0x49, 0x53, 0x95, 0xfa, 0x9d, 0x6a,
0x9f, 0xaa, 0x55, 0x4d, 0x55, 0xf9, 0xf1, 0x75, 0xd7, 0xab, 0x76, 0xeb, 0xd5, 0x70, 0xbf, 0x59,
0x15, 0xc4, 0xaf, 0x9a, 0x17, 0x57, 0x13, 0xbf, 0x6a, 0x82, 0x30, 0xb5, 0xe3, 0xd3, 0xb0, 0xd0,
0x09, 0x63, 0x16, 0x25, 0x12, 0x7a, 0xc9, 0x51, 0x92, 0xd8, 0x54, 0x97, 0xb6, 0x7c, 0x8f, 0x26,
0xa9, 0x1b, 0x4b, 0x4e, 0x26, 0x93, 0x0f, 0xf2, 0xe8, 0xef, 0x87, 0xde, 0x27, 0x85, 0xde, 0x44,
0x39, 0x33, 0x80, 0xb2, 0x9b, 0x03, 0xf9, 0x06, 0x6b, 0xb1, 0x3e, 0xc8, 0x61, 0xc7, 0x68, 0xc1,
0xa2, 0x4b, 0x63, 0x97, 0x7a, 0x5a, 0x95, 0x16, 0x05, 0x09, 0xc3, 0x88, 0x87, 0xb4, 0x29, 0x35,
0xdd, 0xe5, 0x2d, 0xdf, 0xed, 0x29, 0x6e, 0x1d, 0xfc, 0x81, 0x9c, 0x83, 0xca, 0x6e, 0x2f, 0x70,
0xdf, 0x0e, 0x65, 0x40, 0xc4, 0x2f, 0xc2, 0xbc, 0x9f, 0xb0, 0x76, 0x6c, 0x21, 0x79, 0xab, 0x53,
0x81, 0xfc, 0x77, 0x0e, 0x4e, 0x1b, 0xe8, 0xc4, 0x82, 0x22, 0x6c, 0x05, 0x14, 0x13, 0x27, 0xe8,
0x45, 0x3d, 0xa7, 0x13, 0xa8, 0x73, 0x52, 0x92, 0x30, 0x1c, 0x46, 0x9d, 0x80, 0x49, 0x8a, 0x97,
0x9c, 0x54, 0xc0, 0x0d, 0x28, 0xc5, 0x89, 0x08, 0x81, 0xcd, 0x9e, 0x8c, 0x10, 0x95, 0xfa, 0x5b,
0x87, 0x3b, 0x1b, 0x01, 0x7d, 0x57, 0x69, 0x74, 0x32, 0xdd, 0xf8, 0x21, 0x94, 0xf5, 0x9d, 0x8a,
0xad, 0xc5, 0x95, 0xd9, 0xd5, 0x4a, 0x7d, 0xf7, 0xf0, 0x86, 0xde, 0x0e, 0x45, 0xf8, 0x36, 0xe2,
0x87, 0xd3, 0xb7, 0x82, 0x97, 0xa0, 0xdc, 0x56, 0x97, 0x35, 0xb6, 0x4a, 0xd2, 0xdb, 0xfd, 0x01,
0xfc, 0x55, 0x98, 0xf7, 0x83, 0x06, 0x8f, 0xad, 0xb2, 0x04, 0xf3, 0xda, 0xe1, 0xc0, 0xdc, 0x09,
0x1a, 0xdc, 0x49, 0x15, 0xe2, 0x87, 0x70, 0x34, 0x62, 0x49, 0xd4, 0xd3, 0x5e, 0xb0, 0x40, 0xfa,
0xf5, 0x4b, 0x87, 0xb3, 0xe0, 0x98, 0x2a, 0x9d, 0xbc, 0x05, 0xbc, 0x01, 0x95, 0xb8, 0xcf, 0x31,
0xab, 0x22, 0x0d, 0x5a, 0x39, 0x45, 0x06, 0x07, 0x1d, 0x73, 0x32, 0xf9, 0x35, 0x82, 0xa5, 0x03,
0xb7, 0x77, 0x37, 0x64, 0x85, 0x04, 0xa4, 0x30, 0x17, 0x87, 0xcc, 0x95, 0x61, 0xbd, 0x52, 0xdf,
0x9e, 0xda, 0x75, 0x96, 0x76, 0xa5, 0xea, 0xc2, 0x88, 0x43, 0xe1, 0x53, 0xc6, 0xa2, 0xbb, 0x34,
0x71, 0xf7, 0x8a, 0xd0, 0x0a, 0xea, 0x8b, 0x39, 0x2a, 0x0b, 0xa5, 0x82, 0xe0, 0x87, 0xfc, 0xb8,
0xd7, 0x0b, 0x85, 0x05, 0xf1, 0x4b, 0x7f, 0x80, 0x04, 0x60, 0x9b, 0x61, 0x86, 0xb7, 0x5a, 0xef,
0x52, 0x77, 0xbf, 0xc8, 0xca, 0x31, 0x98, 0xf1, 0x3d, 0x69, 0x62, 0xd6, 0x99, 0xf1, 0xbd, 0x67,
0xbb, 0x88, 0xe2, 0xcd, 0x60, 0x0f, 0x49, 0x88, 0x45, 0x06, 0x97, 0xa0, 0x1c, 0x0c, 0x24, 0xc1,
0xfe, 0xc0, 0x90, 0xe4, 0x37, 0x73, 0x20, 0xf9, 0x59, 0xb0, 0xd8, 0xcd, 0x5e, 0x10, 0xe2, 0x67,
0x2d, 0x0a, 0x90, 0xcd, 0x88, 0x77, 0x42, 0xf5, 0x6c, 0x48, 0x05, 0x81, 0x62, 0xdf, 0x0f, 0x3c,
0x6b, 0x21, 0x45, 0x21, 0xbe, 0xc9, 0x7f, 0x10, 0xbc, 0x3c, 0x04, 0xf8, 0xd8, 0x43, 0x79, 0x2e,
0xd0, 0xf7, 0xa9, 0xb1, 0x38, 0x92, 0x1a, 0xa5, 0x41, 0x6a, 0xfc, 0x1b, 0xc1, 0xca, 0x90, 0x1d,
0x8f, 0x4f, 0x29, 0xcf, 0xcd, 0x96, 0x1b, 0x3c, 0x72, 0x99, 0xb5, 0x98, 0xf2, 0x4f, 0x0a, 0x82,
0xad, 0x3c, 0x0a, 0xf7, 0x68, 0x60, 0x95, 0x52, 0xb6, 0xa6, 0x12, 0xf9, 0x0b, 0x02, 0x4b, 0xef,
0xf0, 0x96, 0x2b, 0xf7, 0xdb, 0x09, 0x9e, 0xff, 0x4d, 0x9e, 0x86, 0x05, 0x2a, 0xd1, 0xaa, 0x83,
0x55, 0x12, 0xf9, 0x0e, 0x82, 0x33, 0xf9, 0xed, 0xc4, 0x5b, 0x7e, 0x9c, 0xe8, 0x97, 0x18, 0x6e,
0xc0, 0x62, 0x3a, 0x33, 0x4d, 0xd0, 0x95, 0xfa, 0xd6, 0x61, 0xc3, 0x76, 0xce, 0x75, 0x5a, 0x39,
0x79, 0x05, 0xce, 0x0c, 0xbd, 0xed, 0x0a, 0x86, 0x0d, 0x25, 0x9d, 0xaa, 0x94, 0x73, 0x33, 0x99,
0xfc, 0x71, 0x36, 0x1f, 0xfd, 0xb8, 0xb7, 0xc5, 0x9b, 0x05, 0x6f, 0xe6, 0xe2, 0x03, 0xb1, 0x60,
0x31, 0xe4, 0x9e, 0xf1, 0x3c, 0xd6, 0xa2, 0x58, 0xe7, 0xf2, 0x20, 0xa1, 0xa2, 0x12, 0x53, 0xef,
0xe2, 0xfe, 0x80, 0x38, 0xc8, 0xd8, 0x0f, 0x5c, 0xb6, 0xcb, 0x5c, 0x1e, 0x78, 0xb1, 0x3c, 0x91,
0x59, 0x27, 0x37, 0x86, 0xdf, 0x84, 0xb2, 0x94, 0xef, 0xf9, 0x6d, 0x26, 0xeb, 0x8c, 0x4a, 0x7d,
0xad, 0x9a, 0x96, 0x79, 0x55, 0xb3, 0xcc, 0xeb, 0xfb, 0x50, 0x94, 0x79, 0xd5, 0xee, 0xf5, 0xaa,
0x58, 0xe1, 0xf4, 0x17, 0x0b, 0x2c, 0x09, 0xf5, 0x5b, 0x5b, 0x7e, 0x20, 0x9f, 0x0f, 0xc2, 0x54,
0x7f, 0x40, 0x1c, 0x76, 0x83, 0xb7, 0x5a, 0xfc, 0x91, 0xe6, 0x6e, 0x2a, 0x89, 0x55, 0x9d, 0x20,
0xf1, 0x5b, 0xd2, 0x7e, 0x39, 0xdd, 0x41, 0x36, 0x20, 0x57, 0xf9, 0xad, 0x84, 0x45, 0x32, 0x41,
0x97, 0x1d, 0x25, 0x65, 0x74, 0xaa, 0xa4, 0x75, 0x8f, 0xbe, 0x33, 0x29, 0xf1, 0x8e, 0x98, 0xc4,
0x1b, 0x24, 0xf3, 0xd1, 0x21, 0xf5, 0x85, 0x2c, 0xe4, 0x58, 0xd7, 0xe7, 0x9d, 0xd8, 0x3a, 0x96,
0xa6, 0x31, 0x2d, 0x93, 0xdf, 0x21, 0x28, 0x6d, 0xf1, 0xe6, 0xed, 0x20, 0x89, 0x7a, 0xf2, 0xbd,
0xc9, 0x83, 0x84, 0x05, 0xfa, 0xc4, 0xb5, 0x28, 0xdc, 0x98, 0xf8, 0x6d, 0xb6, 0x9b, 0xd0, 0x76,
0xa8, 0x32, 0xee, 0x33, 0xb9, 0x31, 0x5b, 0x2c, 0xb6, 0xd6, 0xa2, 0x71, 0x22, 0x6f, 0x5d, 0xc9,
0x91, 0xdf, 0x62, 0x13, 0xd9, 0x84, 0xdd, 0x24, 0x52, 0x57, 0x2e, 0x37, 0x66, 0x92, 0x64, 0x3e,
0xc5, 0xa6, 0x44, 0x52, 0x83, 0x97, 0xb2, 0x47, 0xd8, 0x3d, 0x16, 0xb5, 0xfd, 0x80, 0x16, 0xc6,
0x40, 0x72, 0x3d, 0x47, 0x7c, 0xf1, 0x2a, 0x79, 0xe0, 0x07, 0x1e, 0x7f, 0x34, 0x9a, 0xc0, 0xe4,
0x6f, 0xf9, 0x5a, 0xd1, 0x58, 0x93, 0xdd, 0x97, 0x37, 0xe1, 0xa8, 0xb8, 0x59, 0x5d, 0xa6, 0x7e,
0x50, 0x97, 0x97, 0xe4, 0x2e, 0xe5, 0x50, 0x1d, 0x4e, 0x7e, 0x21, 0xde, 0x82, 0xe3, 0x34, 0x8e,
0xfd, 0x66, 0xc0, 0x3c, 0xad, 0x6b, 0x66, 0x62, 0x5d, 0x83, 0x4b, 0xd3, 0x22, 0x42, 0xce, 0x50,
0x3e, 0xd7, 0x22, 0xf9, 0x36, 0x82, 0x53, 0x43, 0x95, 0x64, 0xfc, 0x43, 0x46, 0x38, 0x13, 0x85,
0xbc, 0xbb, 0xc7, 0xbc, 0x4e, 0x8b, 0xe9, 0x52, 0x5a, 0xcb, 0xe2, 0x37, 0xaf, 0x93, 0x9e, 0x80,
0x0a, 0xa7, 0x99, 0x8c, 0x97, 0x01, 0xda, 0x34, 0xe8, 0xd0, 0x96, 0x84, 0x30, 0x27, 0x21, 0x18,
0x23, 0x64, 0x09, 0xec, 0x61, 0xc7, 0xa7, 0xca, 0xd2, 0x5f, 0x21, 0x38, 0xa6, 0x43, 0x93, 0x3a,
0x9f, 0x55, 0x38, 0x6e, 0xb8, 0x61, 0xa7, 0x7f, 0x54, 0x83, 0xc3, 0x63, 0xc2, 0x8e, 0x3e, 0xe7,
0xd9, 0x7c, 0x37, 0xa4, 0x9b, 0xeb, 0x67, 0x4c, 0x1c, 0xf7, 0xb3, 0x8b, 0x4a, 0xbe, 0x05, 0xd6,
0x36, 0x0d, 0x68, 0x93, 0x79, 0x19, 0xf0, 0x8c, 0x24, 0xdf, 0x30, 0x4b, 0xaf, 0x43, 0x17, 0x3a,
0x59, 0xda, 0xf7, 0x1b, 0x0d, 0x55, 0xc6, 0xd5, 0xff, 0xb9, 0x0c, 0xd8, 0x3c, 0x54, 0x16, 0x75,
0x7d, 0x97, 0xe1, 0x1f, 0x20, 0x98, 0x13, 0x59, 0x06, 0x9f, 0x1d, 0xc5, 0x21, 0xe9, 0x5c, 0x7b,
0x7a, 0xef, 0x68, 0x61, 0x8d, 0x2c, 0xbd, 0xf7, 0xf7, 0x7f, 0xfd, 0x70, 0xe6, 0x34, 0x7e, 0x51,
0xf6, 0xdd, 0xba, 0xd7, 0xcd, 0x1e, 0x58, 0x8c, 0xbf, 0x8b, 0x00, 0xab, 0xd4, 0x67, 0xb4, 0x5e,
0xf0, 0x95, 0x51, 0x10, 0x87, 0xb4, 0x68, 0xec, 0xb3, 0x46, 0x18, 0xaa, 0xba, 0x3c, 0x62, 0x22,
0xe8, 0xc8, 0x09, 0x12, 0xc0, 0x9a, 0x04, 0x70, 0x1e, 0x93, 0x61, 0x00, 0x6a, 0x8f, 0xc5, 0xa1,
0x3f, 0xa9, 0xb1, 0xd4, 0xee, 0xcf, 0x11, 0xcc, 0x3f, 0x90, 0x8f, 0xaf, 0x31, 0x4e, 0xda, 0x9d,
0x9a, 0x93, 0xa4, 0x39, 0x89, 0x96, 0x9c, 0x93, 0x48, 0xcf, 0xe2, 0x33, 0x1a, 0x69, 0x9c, 0x44,
0x8c, 0xb6, 0x73, 0x80, 0xaf, 0x21, 0xfc, 0x21, 0x82, 0x85, 0xb4, 0x39, 0x83, 0x2f, 0x8c, 0x42,
0x99, 0x6b, 0xde, 0xd8, 0xd3, 0xeb, 0x74, 0x90, 0xcb, 0x12, 0xe3, 0x39, 0x32, 0xf4, 0x38, 0x37,
0x72, 0x7d, 0x90, 0xf7, 0x11, 0xcc, 0x6e, 0xb2, 0xb1, 0x7c, 0x9b, 0x22, 0xb8, 0x03, 0x0e, 0x1c,
0x72, 0xd4, 0xf8, 0x03, 0x04, 0x2f, 0x6d, 0xb2, 0x64, 0x78, 0x2c, 0xc7, 0xab, 0xe3, 0x03, 0xac,
0xa2, 0xdd, 0x95, 0x09, 0x66, 0x66, 0x41, 0xac, 0x26, 0x91, 0x5d, 0xc6, 0x97, 0x8a, 0x48, 0x28,
0x0a, 0xe2, 0x47, 0x0a, 0xc7, 0x9f, 0x11, 0x9c, 0x18, 0x6c, 0x72, 0xe2, 0x7c, 0xf4, 0x1f, 0xda,
0x03, 0xb5, 0x77, 0x0e, 0x1b, 0x50, 0xf2, 0x4a, 0xc9, 0x2d, 0x89, 0xfc, 0x55, 0xfc, 0x4a, 0x11,
0x72, 0xdd, 0xf7, 0x89, 0x6b, 0x8f, 0xf5, 0xe7, 0x13, 0xd9, 0x2d, 0x97, 0xb0, 0xdf, 0x43, 0x70,
0x64, 0x93, 0x25, 0xdb, 0x59, 0xdb, 0x63, 0x24, 0x6d, 0x73, 0x7d, 0x4d, 0x7b, 0xa9, 0x6a, 0x34,
0xb5, 0xf5, 0x4f, 0x99, 0x4b, 0xd7, 0x25, 0xb0, 0x4b, 0xf8, 0x42, 0x11, 0xb0, 0x7e, 0xab, 0xe5,
0xf7, 0x08, 0x16, 0xd2, 0xb6, 0xc2, 0x68, 0xf3, 0xb9, 0xa6, 0xe1, 0x34, 0x89, 0x79, 0x5b, 0x62,
0xfd, 0xbc, 0x7d, 0x6d, 0x38, 0x56, 0x73, 0xbd, 0xf6, 0x5a, 0x55, 0x6e, 0x20, 0x7f, 0xa3, 0x3e,
0x42, 0x00, 0xfd, 0xd6, 0x08, 0xbe, 0x5c, 0xbc, 0x0f, 0xa3, 0x7d, 0x62, 0x4f, 0xb7, 0x39, 0x42,
0xaa, 0x72, 0x3f, 0xab, 0xf6, 0x4a, 0x21, 0x9d, 0x43, 0xe6, 0x6e, 0xa4, 0x6d, 0x94, 0x9f, 0x21,
0x98, 0x97, 0xb5, 0x38, 0x3e, 0x3f, 0x0a, 0xb3, 0x59, 0xaa, 0x4f, 0xd3, 0xf5, 0x17, 0x25, 0xd4,
0x95, 0x7a, 0x51, 0x4c, 0xd8, 0x40, 0x6b, 0xb8, 0x0b, 0x0b, 0x69, 0xed, 0x3c, 0x9a, 0x1e, 0xb9,
0xda, 0xda, 0x5e, 0x29, 0xc8, 0x51, 0x29, 0x43, 0x55, 0x38, 0x5a, 0x1b, 0x17, 0x8e, 0xe6, 0x44,
0xc4, 0xc0, 0xe7, 0x8a, 0xe2, 0xc9, 0xc7, 0xe0, 0x98, 0x2b, 0x12, 0xdd, 0x05, 0xb2, 0x32, 0x2e,
0x24, 0x09, 0xef, 0xfc, 0x08, 0xc1, 0x89, 0xc1, 0x27, 0x0d, 0x3e, 0x33, 0x10, 0x8e, 0xcc, 0x37,
0x9a, 0x9d, 0xf7, 0xe2, 0xa8, 0xe7, 0x10, 0xf9, 0x82, 0x44, 0xb1, 0x81, 0x6f, 0x8e, 0xbd, 0x19,
0x3b, 0xfa, 0x42, 0x0b, 0x45, 0xeb, 0xfd, 0x0e, 0xeb, 0x6f, 0x10, 0x1c, 0xd1, 0x7a, 0xef, 0x45,
0x8c, 0x15, 0xc3, 0x9a, 0xde, 0x45, 0x10, 0xb6, 0xc8, 0x67, 0x25, 0xfc, 0xcf, 0xe0, 0x1b, 0x13,
0xc2, 0xd7, 0xb0, 0xd7, 0x13, 0x81, 0xf4, 0x0f, 0x08, 0x4e, 0x3e, 0x48, 0x79, 0xff, 0x09, 0xe1,
0x7f, 0x5d, 0xe2, 0xff, 0x1c, 0x7e, 0xb5, 0xe0, 0xc9, 0x31, 0x6e, 0x1b, 0xd7, 0x10, 0xfe, 0x25,
0x82, 0x92, 0xee, 0x4e, 0xe2, 0x4b, 0x23, 0x2f, 0x46, 0xbe, 0x7f, 0x39, 0x4d, 0x32, 0xab, 0xfc,
0x4a, 0xce, 0x17, 0x66, 0x29, 0x65, 0x5f, 0x10, 0xfa, 0x7d, 0x04, 0x38, 0xab, 0x35, 0xb2, 0xea,
0x03, 0x5f, 0xcc, 0x99, 0x1a, 0x59, 0x54, 0xda, 0x97, 0xc6, 0xce, 0xcb, 0x67, 0xa9, 0xb5, 0xc2,
0x2c, 0xc5, 0x33, 0xfb, 0xdf, 0x43, 0x50, 0xd9, 0x64, 0xd9, 0x73, 0xb8, 0xc0, 0x97, 0xf9, 0xd6,
0xac, 0xbd, 0x3a, 0x7e, 0xa2, 0x42, 0x74, 0x55, 0x22, 0xba, 0x88, 0x8b, 0x5d, 0xa5, 0x01, 0xfc,
0x04, 0xc1, 0xd1, 0xbb, 0x26, 0x45, 0xf1, 0xd5, 0x71, 0x96, 0x72, 0x91, 0x7c, 0x72, 0x5c, 0x9f,
0x96, 0xb8, 0xd6, 0xc9, 0x44, 0xb8, 0x36, 0x54, 0x8f, 0xf4, 0xa7, 0x08, 0x5e, 0x30, 0xeb, 0x07,
0xd5, 0x4d, 0xfb, 0x7f, 0xfd, 0x56, 0xd0, 0x94, 0x23, 0x37, 0x24, 0xbe, 0x2a, 0xbe, 0x3a, 0x09,
0xbe, 0x9a, 0x6a, 0xb1, 0xe1, 0x1f, 0x23, 0x38, 0x29, 0x7b, 0x95, 0xa6, 0xe2, 0x81, 0x14, 0x33,
0xaa, 0xb3, 0x39, 0x41, 0x8a, 0x51, 0xf1, 0x87, 0x3c, 0x13, 0xa8, 0x0d, 0xd5, 0x87, 0xc4, 0xdf,
0x47, 0x70, 0x4c, 0x27, 0x35, 0x75, 0xba, 0xeb, 0xe3, 0x1c, 0xf7, 0xac, 0x49, 0x50, 0xd1, 0x6d,
0x6d, 0x32, 0xba, 0x7d, 0x88, 0x60, 0x51, 0xf5, 0x12, 0x0b, 0x9e, 0x0a, 0x46, 0xb3, 0xd1, 0x3e,
0x95, 0x9b, 0xa5, 0x1b, 0x59, 0xe4, 0x6b, 0xd2, 0xec, 0x7d, 0x5c, 0x2b, 0x32, 0x1b, 0x72, 0x2f,
0xae, 0x3d, 0x56, 0x5d, 0xa4, 0x27, 0xb5, 0x16, 0x6f, 0xc6, 0xef, 0x10, 0x5c, 0x98, 0x10, 0xc5,
0x9c, 0x6b, 0xe8, 0xb5, 0x2f, 0xfe, 0xe9, 0xe9, 0x32, 0xfa, 0xeb, 0xd3, 0x65, 0xf4, 0x8f, 0xa7,
0xcb, 0xe8, 0x9d, 0x9b, 0x93, 0xfd, 0xff, 0xc3, 0x6d, 0xf9, 0x2c, 0x48, 0x4c, 0xb5, 0xff, 0x0b,
0x00, 0x00, 0xff, 0xff, 0xa3, 0x87, 0x84, 0x43, 0xe5, 0x22, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -3455,27 +3455,21 @@ func (m *ApplicationResourceEventsQuery) MarshalToSizedBuffer(dAtA []byte) (int,
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.ResourceUID == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceUID")
} else {
if m.ResourceUID != nil {
i -= len(*m.ResourceUID)
copy(dAtA[i:], *m.ResourceUID)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.ResourceUID)))
i--
dAtA[i] = 0x22
}
if m.ResourceName == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName")
} else {
if m.ResourceName != nil {
i -= len(*m.ResourceName)
copy(dAtA[i:], *m.ResourceName)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.ResourceName)))
i--
dAtA[i] = 0x1a
}
if m.ResourceNamespace == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceNamespace")
} else {
if m.ResourceNamespace != nil {
i -= len(*m.ResourceNamespace)
copy(dAtA[i:], *m.ResourceNamespace)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.ResourceNamespace)))
@@ -4136,9 +4130,7 @@ func (m *ApplicationResourceRequest) MarshalToSizedBuffer(dAtA []byte) (int, err
i--
dAtA[i] = 0x1a
}
if m.Namespace == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
} else {
if m.Namespace != nil {
i -= len(*m.Namespace)
copy(dAtA[i:], *m.Namespace)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.Namespace)))
@@ -4233,9 +4225,7 @@ func (m *ApplicationResourcePatchRequest) MarshalToSizedBuffer(dAtA []byte) (int
i--
dAtA[i] = 0x1a
}
if m.Namespace == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
} else {
if m.Namespace != nil {
i -= len(*m.Namespace)
copy(dAtA[i:], *m.Namespace)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.Namespace)))
@@ -4332,9 +4322,7 @@ func (m *ApplicationResourceDeleteRequest) MarshalToSizedBuffer(dAtA []byte) (in
i--
dAtA[i] = 0x1a
}
if m.Namespace == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
} else {
if m.Namespace != nil {
i -= len(*m.Namespace)
copy(dAtA[i:], *m.Namespace)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.Namespace)))
@@ -4420,9 +4408,7 @@ func (m *ResourceActionRunRequest) MarshalToSizedBuffer(dAtA []byte) (int, error
i--
dAtA[i] = 0x1a
}
if m.Namespace == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
} else {
if m.Namespace != nil {
i -= len(*m.Namespace)
copy(dAtA[i:], *m.Namespace)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.Namespace)))
@@ -4633,9 +4619,7 @@ func (m *ApplicationPodLogsQuery) MarshalToSizedBuffer(dAtA []byte) (int, error)
i--
dAtA[i] = 0x1a
}
if m.Namespace == nil {
return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
} else {
if m.Namespace != nil {
i -= len(*m.Namespace)
copy(dAtA[i:], *m.Namespace)
i = encodeVarintApplication(dAtA, i, uint64(len(*m.Namespace)))
@@ -6437,7 +6421,6 @@ func (m *ApplicationResourceEventsQuery) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.ResourceNamespace = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType)
@@ -6471,7 +6454,6 @@ func (m *ApplicationResourceEventsQuery) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.ResourceName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000004)
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResourceUID", wireType)
@@ -6505,7 +6487,6 @@ func (m *ApplicationResourceEventsQuery) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.ResourceUID = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000008)
default:
iNdEx = preIndex
skippy, err := skipApplication(dAtA[iNdEx:])
@@ -6525,15 +6506,6 @@ func (m *ApplicationResourceEventsQuery) Unmarshal(dAtA []byte) error {
if hasFields[0]&uint64(0x00000001) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceNamespace")
}
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName")
}
if hasFields[0]&uint64(0x00000008) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceUID")
}
if iNdEx > l {
return io.ErrUnexpectedEOF
@@ -8123,7 +8095,6 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Namespace = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType)
@@ -8157,7 +8128,7 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.ResourceName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000004)
hasFields[0] |= uint64(0x00000002)
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
@@ -8191,7 +8162,7 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Version = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000008)
hasFields[0] |= uint64(0x00000004)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType)
@@ -8258,7 +8229,7 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Kind = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000010)
hasFields[0] |= uint64(0x00000008)
default:
iNdEx = preIndex
skippy, err := skipApplication(dAtA[iNdEx:])
@@ -8279,15 +8250,12 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
}
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName")
}
if hasFields[0]&uint64(0x00000008) == 0 {
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("version")
}
if hasFields[0]&uint64(0x00000010) == 0 {
if hasFields[0]&uint64(0x00000008) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("kind")
}
@@ -8393,7 +8361,6 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Namespace = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType)
@@ -8427,7 +8394,7 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.ResourceName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000004)
hasFields[0] |= uint64(0x00000002)
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
@@ -8461,7 +8428,7 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Version = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000008)
hasFields[0] |= uint64(0x00000004)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType)
@@ -8528,7 +8495,7 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Kind = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000010)
hasFields[0] |= uint64(0x00000008)
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Patch", wireType)
@@ -8562,7 +8529,7 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Patch = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000020)
hasFields[0] |= uint64(0x00000010)
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PatchType", wireType)
@@ -8596,7 +8563,7 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.PatchType = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000040)
hasFields[0] |= uint64(0x00000020)
default:
iNdEx = preIndex
skippy, err := skipApplication(dAtA[iNdEx:])
@@ -8617,21 +8584,18 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
}
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName")
}
if hasFields[0]&uint64(0x00000008) == 0 {
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("version")
}
if hasFields[0]&uint64(0x00000010) == 0 {
if hasFields[0]&uint64(0x00000008) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("kind")
}
if hasFields[0]&uint64(0x00000020) == 0 {
if hasFields[0]&uint64(0x00000010) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("patch")
}
if hasFields[0]&uint64(0x00000040) == 0 {
if hasFields[0]&uint64(0x00000020) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("patchType")
}
@@ -8737,7 +8701,6 @@ func (m *ApplicationResourceDeleteRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Namespace = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType)
@@ -8771,7 +8734,7 @@ func (m *ApplicationResourceDeleteRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.ResourceName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000004)
hasFields[0] |= uint64(0x00000002)
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
@@ -8805,7 +8768,7 @@ func (m *ApplicationResourceDeleteRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Version = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000008)
hasFields[0] |= uint64(0x00000004)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType)
@@ -8872,7 +8835,7 @@ func (m *ApplicationResourceDeleteRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Kind = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000010)
hasFields[0] |= uint64(0x00000008)
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Force", wireType)
@@ -8935,15 +8898,12 @@ func (m *ApplicationResourceDeleteRequest) Unmarshal(dAtA []byte) error {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
}
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName")
}
if hasFields[0]&uint64(0x00000008) == 0 {
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("version")
}
if hasFields[0]&uint64(0x00000010) == 0 {
if hasFields[0]&uint64(0x00000008) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("kind")
}
@@ -9049,7 +9009,6 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Namespace = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType)
@@ -9083,7 +9042,7 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.ResourceName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000004)
hasFields[0] |= uint64(0x00000002)
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
@@ -9117,7 +9076,7 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Version = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000008)
hasFields[0] |= uint64(0x00000004)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType)
@@ -9184,7 +9143,7 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Kind = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000010)
hasFields[0] |= uint64(0x00000008)
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType)
@@ -9218,7 +9177,7 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Action = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000020)
hasFields[0] |= uint64(0x00000010)
default:
iNdEx = preIndex
skippy, err := skipApplication(dAtA[iNdEx:])
@@ -9239,18 +9198,15 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
}
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName")
}
if hasFields[0]&uint64(0x00000008) == 0 {
if hasFields[0]&uint64(0x00000004) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("version")
}
if hasFields[0]&uint64(0x00000010) == 0 {
if hasFields[0]&uint64(0x00000008) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("kind")
}
if hasFields[0]&uint64(0x00000020) == 0 {
if hasFields[0]&uint64(0x00000010) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("action")
}
@@ -9530,7 +9486,6 @@ func (m *ApplicationPodLogsQuery) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Namespace = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PodName", wireType)
@@ -9899,9 +9854,6 @@ func (m *ApplicationPodLogsQuery) Unmarshal(dAtA []byte) error {
if hasFields[0]&uint64(0x00000001) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace")
}
if iNdEx > l {
return io.ErrUnexpectedEOF

View File

@@ -100,7 +100,11 @@ func (c *client) executeRequest(fullMethodName string, msg []byte, md metadata.M
}
func (c *client) startGRPCProxy() (*grpc.Server, net.Listener, error) {
serverAddr := fmt.Sprintf("%s/argocd-%s.sock", os.TempDir(), rand.RandString(16))
randSuffix, err := rand.String(16)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate random socket filename: %w", err)
}
serverAddr := fmt.Sprintf("%s/argocd-%s.sock", os.TempDir(), randSuffix)
ln, err := net.Listen("unix", serverAddr)
if err != nil {

View File

@@ -1542,6 +1542,19 @@ func isValidAction(action string) bool {
return false
}
// TODO: same as validActions, refacotor to use rbacpolicy.ResourceApplications etc.
var validResources = map[string]bool{
"applications": true,
"repositories": true,
"clusters": true,
"exec": true,
"logs": true,
}
func isValidResource(resource string) bool {
return validResources[resource]
}
func validatePolicy(proj string, role string, policy string) error {
policyComponents := strings.Split(policy, ",")
if len(policyComponents) != 6 || strings.Trim(policyComponents[0], " ") != "p" {
@@ -1555,7 +1568,7 @@ func validatePolicy(proj string, role string, policy string) error {
}
// resource
resource := strings.Trim(policyComponents[2], " ")
if resource != "applications" && resource != "repositories" && resource != "clusters" {
if !isValidResource(resource) {
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', 'repositories' or 'clusters', not '%s'", policy, resource)
}
// action

View File

@@ -2546,10 +2546,19 @@ func Test_validatePolicy_projIsNotRegex(t *testing.T) {
}
func Test_validatePolicy_ValidResource(t *testing.T) {
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, applications, *, some-project/*, allow")
assert.NoError(t, err)
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
assert.NoError(t, err)
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, clusters, *, some-project/*, allow")
assert.NoError(t, err)
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, exec, *, some-project/*, allow")
assert.NoError(t, err)
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, logs, *, some-project/*, allow")
assert.NoError(t, err)
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, unknown, *, some-project/*, allow")
assert.Error(t, err)
}
func TestEnvsubst(t *testing.T) {

View File

@@ -8,6 +8,7 @@ import (
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
@@ -63,6 +64,8 @@ func NewConnection(address string, timeoutSeconds int, tlsConfig *TLSConfigurati
grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(retryOpts...)),
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(unaryInterceptors...)),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxGRPCMessageSize), grpc.MaxCallSendMsgSize(MaxGRPCMessageSize)),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),
}
tlsC := &tls.Config{}

View File

@@ -18,6 +18,12 @@ import (
"strings"
"time"
kubeyaml "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/apimachinery/pkg/api/resource"
"github.com/argoproj/argo-cd/v2/util/io/files"
"github.com/Masterminds/semver/v3"
"github.com/TomOnTime/utfutil"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
@@ -69,6 +75,8 @@ const (
ociPrefix = "oci://"
)
var ErrExceededMaxCombinedManifestFileSize = errors.New("exceeded max combined manifest file size")
// Service implements ManifestService interface
type Service struct {
gitCredsStore git.CredsStore
@@ -94,6 +102,8 @@ type RepoServerInitConstants struct {
PauseGenerationOnFailureForMinutes int
PauseGenerationOnFailureForRequests int
SubmoduleEnabled bool
MaxCombinedDirectoryManifestsSize resource.Quantity
CMPTarExcludedGlobs []string
}
// NewService returns a new instance of the Manifest service
@@ -204,7 +214,7 @@ func (s *Service) ListApps(ctx context.Context, q *apiclient.ListAppsRequest) (*
}
defer io.Close(closer)
apps, err := discovery.Discover(ctx, gitClient.Root(), q.EnabledSourceTypes)
apps, err := discovery.Discover(ctx, gitClient.Root(), q.EnabledSourceTypes, s.initConstants.CMPTarExcludedGlobs)
if err != nil {
return nil, err
}
@@ -448,10 +458,15 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
close(ch.errCh)
close(ch.responseCh)
}()
// GenerateManifests mutates the source (applies overrides). Those overrides shouldn't be reflected in the cache
// key. Overrides will break the cache anyway, because changes to overrides will change the revision.
appSourceCopy := q.ApplicationSource.DeepCopy()
var manifestGenResult *apiclient.ManifestResponse
opContext, err := opContextSrc()
if err == nil {
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, WithCMPTarDoneChannel(ch.tarDoneCh))
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs))
}
if err != nil {
// If manifest generation error caching is enabled
@@ -460,9 +475,9 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
// Retrieve a new copy (if available) of the cached response: this ensures we are updating the latest copy of the cache,
// rather than a copy of the cache that occurred before (a potentially lengthy) manifest generation.
innerRes := &cache.CachedManifestResponse{}
cacheErr := s.cache.GetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
cacheErr := s.cache.GetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
if cacheErr != nil && cacheErr != reposervercache.ErrCacheMiss {
log.Warnf("manifest cache set error %s: %v", q.ApplicationSource.String(), cacheErr)
log.Warnf("manifest cache set error %s: %v", appSourceCopy.String(), cacheErr)
ch.errCh <- cacheErr
return
}
@@ -476,9 +491,9 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
// Update the cache to include failure information
innerRes.NumberOfConsecutiveFailures++
innerRes.MostRecentError = err.Error()
cacheErr = s.cache.SetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
cacheErr = s.cache.SetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes)
if cacheErr != nil {
log.Warnf("manifest cache set error %s: %v", q.ApplicationSource.String(), cacheErr)
log.Warnf("manifest cache set error %s: %v", appSourceCopy.String(), cacheErr)
ch.errCh <- cacheErr
return
}
@@ -497,9 +512,9 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
}
manifestGenResult.Revision = commitSHA
manifestGenResult.VerifyResult = opContext.verificationResult
err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry)
err = s.cache.SetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry)
if err != nil {
log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err)
log.Warnf("manifest cache set error %s/%s: %v", appSourceCopy.String(), cacheKey, err)
}
ch.responseCh <- manifestGenCacheEntry.ManifestResponse
}
@@ -844,7 +859,8 @@ func getRepoCredential(repoCredentials []*v1alpha1.RepoCreds, repoURL string) *v
type GenerateManifestOpt func(*generateManifestOpt)
type generateManifestOpt struct {
cmpTarDoneCh chan<- bool
cmpTarDoneCh chan<- bool
cmpTarExcludedGlobs []string
}
func newGenerateManifestOpt(opts ...GenerateManifestOpt) *generateManifestOpt {
@@ -864,14 +880,23 @@ func WithCMPTarDoneChannel(ch chan<- bool) GenerateManifestOpt {
}
}
// GenerateManifests generates manifests from a path
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) {
// WithCMPTarExcludedGlobs defines globs for files to filter out when streaming the tarball
// to a CMP sidecar.
func WithCMPTarExcludedGlobs(excludedGlobs []string) GenerateManifestOpt {
return func(o *generateManifestOpt) {
o.cmpTarExcludedGlobs = excludedGlobs
}
}
// GenerateManifests generates manifests from a path. Overrides are applied as a side effect on the given ApplicationSource.
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) {
opt := newGenerateManifestOpt(opts...)
var targetObjs []*unstructured.Unstructured
var dest *v1alpha1.ApplicationDestination
resourceTracking := argo.NewResourceTracking()
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName, q.EnabledSourceTypes)
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName, q.EnabledSourceTypes, opt.cmpTarExcludedGlobs)
if err != nil {
return nil, err
}
@@ -895,7 +920,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
if q.ApplicationSource.Plugin != nil && q.ApplicationSource.Plugin.Name != "" {
targetObjs, err = runConfigManagementPlugin(appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore))
} else {
targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh)
targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs)
if err != nil {
err = fmt.Errorf("plugin sidecar failed. %s", err.Error())
}
@@ -905,7 +930,8 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
if directory = q.ApplicationSource.Directory; directory == nil {
directory = &v1alpha1.ApplicationSourceDirectory{}
}
targetObjs, err = findManifests(appPath, repoRoot, env, *directory, q.EnabledSourceTypes)
logCtx := log.WithField("application", q.AppName)
targetObjs, err = findManifests(logCtx, appPath, repoRoot, env, *directory, q.EnabledSourceTypes, maxCombinedManifestQuantity)
}
if err != nil {
return nil, err
@@ -982,7 +1008,7 @@ func mergeSourceParameters(source *v1alpha1.ApplicationSource, path, appName str
overrides = append(overrides, filepath.Join(path, fmt.Sprintf(appSourceFile, appName)))
}
var merged v1alpha1.ApplicationSource = *source.DeepCopy()
var merged = *source.DeepCopy()
for _, filename := range overrides {
info, err := os.Stat(filename)
@@ -1028,7 +1054,7 @@ func mergeSourceParameters(source *v1alpha1.ApplicationSource, path, appName str
}
// GetAppSourceType returns explicit application source type or examines a directory and determines its application source type
func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, path, appName string, enableGenerateManifests map[string]bool) (v1alpha1.ApplicationSourceType, error) {
func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, path, appName string, enableGenerateManifests map[string]bool, tarExcludedGlobs []string) (v1alpha1.ApplicationSourceType, error) {
err := mergeSourceParameters(source, path, appName)
if err != nil {
return "", fmt.Errorf("error while parsing source parameters: %v", err)
@@ -1045,7 +1071,7 @@ func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, p
}
return *appSourceType, nil
}
appType, err := discovery.AppType(ctx, path, enableGenerateManifests)
appType, err := discovery.AppType(ctx, path, enableGenerateManifests, tarExcludedGlobs)
if err != nil {
return "", err
}
@@ -1075,47 +1101,30 @@ func isNullList(obj *unstructured.Unstructured) bool {
var manifestFile = regexp.MustCompile(`^.*\.(yaml|yml|json|jsonnet)$`)
// findManifests looks at all yaml files in a directory and unmarshals them into a list of unstructured objects
func findManifests(appPath string, repoRoot string, env *v1alpha1.Env, directory v1alpha1.ApplicationSourceDirectory, enabledManifestGeneration map[string]bool) ([]*unstructured.Unstructured, error) {
func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1alpha1.Env, directory v1alpha1.ApplicationSourceDirectory, enabledManifestGeneration map[string]bool, maxCombinedManifestQuantity resource.Quantity) ([]*unstructured.Unstructured, error) {
// Validate the directory before loading any manifests to save memory.
potentiallyValidManifests, err := getPotentiallyValidManifests(logCtx, appPath, repoRoot, directory.Recurse, directory.Include, directory.Exclude, maxCombinedManifestQuantity)
if err != nil {
logCtx.Errorf("failed to get potentially valid manifests: %s", err)
return nil, fmt.Errorf("failed to get potentially valid manifests: %w", err)
}
var objs []*unstructured.Unstructured
err := filepath.Walk(appPath, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if f.IsDir() {
if path != appPath && !directory.Recurse {
return filepath.SkipDir
} else {
return nil
}
}
for _, potentiallyValidManifest := range potentiallyValidManifests {
manifestPath := potentiallyValidManifest.path
manifestFileInfo := potentiallyValidManifest.fileInfo
if !manifestFile.MatchString(f.Name()) {
return nil
}
relPath, err := filepath.Rel(appPath, path)
if err != nil {
return err
}
if directory.Exclude != "" && glob.Match(directory.Exclude, relPath) {
return nil
}
if directory.Include != "" && !glob.Match(directory.Include, relPath) {
return nil
}
if strings.HasSuffix(f.Name(), ".jsonnet") {
if strings.HasSuffix(manifestFileInfo.Name(), ".jsonnet") {
if !discovery.IsManifestGenerationEnabled(v1alpha1.ApplicationSourceTypeDirectory, enabledManifestGeneration) {
return nil
continue
}
vm, err := makeJsonnetVm(appPath, repoRoot, directory.Jsonnet, env)
if err != nil {
return err
return nil, err
}
jsonStr, err := vm.EvaluateFile(path)
jsonStr, err := vm.EvaluateFile(manifestPath)
if err != nil {
return status.Errorf(codes.FailedPrecondition, "Failed to evaluate jsonnet %q: %v", f.Name(), err)
return nil, status.Errorf(codes.FailedPrecondition, "Failed to evaluate jsonnet %q: %v", manifestFileInfo.Name(), err)
}
// attempt to unmarshal either array or single object
@@ -1127,49 +1136,207 @@ func findManifests(appPath string, repoRoot string, env *v1alpha1.Env, directory
var jsonObj unstructured.Unstructured
err = json.Unmarshal([]byte(jsonStr), &jsonObj)
if err != nil {
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal generated json %q: %v", f.Name(), err)
return nil, status.Errorf(codes.FailedPrecondition, "Failed to unmarshal generated json %q: %v", manifestFileInfo.Name(), err)
}
objs = append(objs, &jsonObj)
}
} else {
out, err := utfutil.ReadFile(path, utfutil.UTF8)
err := getObjsFromYAMLOrJson(logCtx, manifestPath, manifestFileInfo.Name(), &objs)
if err != nil {
return err
}
if strings.HasSuffix(f.Name(), ".json") {
var obj unstructured.Unstructured
err = json.Unmarshal(out, &obj)
if err != nil {
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
}
objs = append(objs, &obj)
} else {
yamlObjs, err := kube.SplitYAML(out)
if err != nil {
if len(yamlObjs) > 0 {
// If we get here, we had a multiple objects in a single YAML file which had some
// valid k8s objects, but errors parsing others (within the same file). It's very
// likely the user messed up a portion of the YAML, so report on that.
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
}
// Otherwise, let's see if it looks like a resource, if yes, we return error
if bytes.Contains(out, []byte("apiVersion:")) &&
bytes.Contains(out, []byte("kind:")) &&
bytes.Contains(out, []byte("metadata:")) {
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", f.Name(), err)
}
// Otherwise, it might be a unrelated YAML file which we will ignore
return nil
}
objs = append(objs, yamlObjs...)
return nil, err
}
}
}
return objs, nil
}
// getObjsFromYAMLOrJson unmarshals the given yaml or json file and appends it to the given list of objects.
func getObjsFromYAMLOrJson(logCtx *log.Entry, manifestPath string, filename string, objs *[]*unstructured.Unstructured) error {
reader, err := utfutil.OpenFile(manifestPath, utfutil.UTF8)
if err != nil {
return status.Errorf(codes.FailedPrecondition, "Failed to open %q", manifestPath)
}
defer func() {
err := reader.Close()
if err != nil {
logCtx.Errorf("failed to close %q - potential memory leak", manifestPath)
}
}()
if strings.HasSuffix(filename, ".json") {
var obj unstructured.Unstructured
decoder := json.NewDecoder(reader)
err = decoder.Decode(&obj)
if err != nil {
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", filename, err)
}
if decoder.More() {
return status.Errorf(codes.FailedPrecondition, "Found multiple objects in %q. Only single objects are allowed in JSON files.", filename)
}
*objs = append(*objs, &obj)
} else {
yamlObjs, err := splitYAMLOrJSON(reader)
if err != nil {
if len(yamlObjs) > 0 {
// If we get here, we had a multiple objects in a single YAML file which had some
// valid k8s objects, but errors parsing others (within the same file). It's very
// likely the user messed up a portion of the YAML, so report on that.
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", filename, err)
}
// Read the whole file to check whether it looks like a manifest.
out, err := utfutil.ReadFile(manifestPath, utfutil.UTF8)
// Otherwise, let's see if it looks like a resource, if yes, we return error
if bytes.Contains(out, []byte("apiVersion:")) &&
bytes.Contains(out, []byte("kind:")) &&
bytes.Contains(out, []byte("metadata:")) {
return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", filename, err)
}
// Otherwise, it might be an unrelated YAML file which we will ignore
}
*objs = append(*objs, yamlObjs...)
}
return nil
}
// splitYAMLOrJSON reads a YAML or JSON file and gets each document as an unstructured object. If the unmarshaller
// encounters an error, objects read up until the error are returned.
func splitYAMLOrJSON(reader goio.Reader) ([]*unstructured.Unstructured, error) {
d := kubeyaml.NewYAMLOrJSONDecoder(reader, 4096)
var objs []*unstructured.Unstructured
for {
u := &unstructured.Unstructured{}
if err := d.Decode(&u); err != nil {
if err == goio.EOF {
break
}
return objs, fmt.Errorf("failed to unmarshal manifest: %v", err)
}
if u == nil {
continue
}
objs = append(objs, u)
}
return objs, nil
}
// getPotentiallyValidManifestFile checks whether the given path/FileInfo may be a valid manifest file. Returns a non-nil error if
// there was an error that should not be handled by ignoring the file. Returns non-nil realFileInfo if the file is a
// potential manifest. Returns a non-empty ignoreMessage if there's a message that should be logged about why the file
// was skipped. If realFileInfo is nil and the ignoreMessage is empty, there's no need to log the ignoreMessage; the
// file was skipped for a mundane reason.
//
// The file is still only a "potentially" valid manifest file because it could be invalid JSON or YAML, or it might not
// be a valid Kubernetes resource. This function tests everything possible without actually reading the file.
//
// repoPath must be absolute.
func getPotentiallyValidManifestFile(path string, f os.FileInfo, appPath, repoRoot, include, exclude string) (realFileInfo os.FileInfo, warning string, err error) {
relPath, err := filepath.Rel(appPath, path)
if err != nil {
return nil, "", fmt.Errorf("failed to get relative path of %q: %w", path, err)
}
if !manifestFile.MatchString(f.Name()) {
return nil, "", nil
}
// If the file is a symlink, these will be overridden with the destination file's info.
var relRealPath = relPath
realFileInfo = f
if files.IsSymlink(f) {
realPath, err := filepath.EvalSymlinks(path)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Sprintf("destination of symlink %q is missing", relPath), nil
}
return nil, "", fmt.Errorf("failed to evaluate symlink at %q: %w", relPath, err)
}
if !files.Inbound(realPath, repoRoot) {
return nil, "", fmt.Errorf("illegal filepath in symlink at %q", relPath)
}
realFileInfo, err = os.Stat(realPath)
if err != nil {
if os.IsNotExist(err) {
// This should have been caught by filepath.EvalSymlinks, but check again since that function's docs
// don't promise to return this error.
return nil, fmt.Sprintf("destination of symlink %q is missing at %q", relPath, realPath), nil
}
return nil, "", fmt.Errorf("failed to get file info for symlink at %q to %q: %w", relPath, realPath, err)
}
relRealPath, err = filepath.Rel(repoRoot, realPath)
if err != nil {
return nil, "", fmt.Errorf("failed to get relative path of %q: %w", realPath, err)
}
}
// FileInfo.Size() behavior is platform-specific for non-regular files. Allow only regular files, so we guarantee
// accurate file sizes.
if !realFileInfo.Mode().IsRegular() {
return nil, fmt.Sprintf("ignoring symlink at %q to non-regular file %q", relPath, relRealPath), nil
}
if exclude != "" && glob.Match(exclude, relPath) {
return nil, "", nil
}
if include != "" && !glob.Match(include, relPath) {
return nil, "", nil
}
return realFileInfo, "", nil
}
type potentiallyValidManifest struct {
path string
fileInfo os.FileInfo
}
// getPotentiallyValidManifests ensures that 1) there are no errors while checking for potential manifest files in the given dir
// and 2) the combined file size of the potentially-valid manifest files does not exceed the limit.
func getPotentiallyValidManifests(logCtx *log.Entry, appPath string, repoRoot string, recurse bool, include string, exclude string, maxCombinedManifestQuantity resource.Quantity) ([]potentiallyValidManifest, error) {
maxCombinedManifestFileSize := maxCombinedManifestQuantity.Value()
var currentCombinedManifestFileSize = int64(0)
var potentiallyValidManifests []potentiallyValidManifest
err := filepath.Walk(appPath, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if f.IsDir() {
if path != appPath && !recurse {
return filepath.SkipDir
}
return nil
}
realFileInfo, warning, err := getPotentiallyValidManifestFile(path, f, appPath, repoRoot, include, exclude)
if err != nil {
return fmt.Errorf("invalid manifest file %q: %w", path, err)
}
if realFileInfo == nil {
if warning != "" {
logCtx.Warnf("skipping manifest file %q: %s", path, warning)
}
return nil
}
// Don't count jsonnet file size against max. It's jsonnet's responsibility to manage memory usage.
if !strings.HasSuffix(f.Name(), ".jsonnet") {
// We use the realFileInfo size (which is guaranteed to be a regular file instead of a symlink or other
// non-regular file) because .Size() behavior is platform-specific for non-regular files.
currentCombinedManifestFileSize += realFileInfo.Size()
if maxCombinedManifestFileSize != 0 && currentCombinedManifestFileSize > maxCombinedManifestFileSize {
return ErrExceededMaxCombinedManifestFileSize
}
}
potentiallyValidManifests = append(potentiallyValidManifests, potentiallyValidManifest{path: path, fileInfo: f})
return nil
})
if err != nil {
// Not wrapping, because this error should be wrapped by the caller.
return nil, err
}
return objs, nil
return potentiallyValidManifests, nil
}
func makeJsonnetVm(appPath string, repoRoot string, sourceJsonnet v1alpha1.ApplicationSourceJsonnet, env *v1alpha1.Env) (*jsonnet.VM, error) {
@@ -1252,7 +1419,7 @@ func runConfigManagementPlugin(appPath, repoRoot string, envVars *v1alpha1.Env,
}
}
env, err := getPluginEnvs(envVars, q, creds)
env, err := getPluginEnvs(envVars, q, creds, false)
if err != nil {
return nil, err
}
@@ -1270,8 +1437,14 @@ func runConfigManagementPlugin(appPath, repoRoot string, envVars *v1alpha1.Env,
return kube.SplitYAML([]byte(out))
}
func getPluginEnvs(envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds) ([]string, error) {
env := append(os.Environ(), envVars.Environ()...)
func getPluginEnvs(envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, remote bool) ([]string, error) {
env := envVars.Environ()
// Local plugins need also to have access to the local environment variables.
// Remote side car plugins will use the environment in the side car
// container.
if !remote {
env = append(os.Environ(), env...)
}
if creds != nil {
closer, environ, err := creds.Environ()
if err != nil {
@@ -1294,28 +1467,30 @@ func getPluginEnvs(envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds gi
if q.ApplicationSource.Plugin != nil {
pluginEnv := q.ApplicationSource.Plugin.Env
for i, j := range pluginEnv {
pluginEnv[i].Value = parsedEnv.Envsubst(j.Value)
for _, entry := range pluginEnv {
newValue := parsedEnv.Envsubst(entry.Value)
env = append(env, fmt.Sprintf("ARGOCD_ENV_%s=%s", entry.Name, newValue))
}
env = append(env, pluginEnv.Environ()...)
}
return env, nil
}
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool) ([]*unstructured.Unstructured, error) {
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string) ([]*unstructured.Unstructured, error) {
// compute variables.
env, err := getPluginEnvs(envVars, q, creds, true)
if err != nil {
return nil, err
}
// detect config management plugin server (sidecar)
conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath)
conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath, env, tarExcludedGlobs)
if err != nil {
return nil, err
}
defer io.Close(conn)
// generate manifests using commands provided in plugin config file in detected cmp-server sidecar
env, err := getPluginEnvs(envVars, q, creds)
if err != nil {
return nil, err
}
cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh)
cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh, tarExcludedGlobs)
if err != nil {
return nil, fmt.Errorf("error generating manifests in cmp: %s", err)
}
@@ -1333,7 +1508,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath st
// generateManifestsCMP will send the appPath files to the cmp-server over a gRPC stream.
// The cmp-server will generate the manifests. Returns a response object with the generated
// manifests.
func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool) (*pluginclient.ManifestResponse, error) {
func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool, tarExcludedGlobs []string) (*pluginclient.ManifestResponse, error) {
generateManifestStream, err := cmpClient.GenerateManifest(ctx, grpc_retry.Disable())
if err != nil {
return nil, fmt.Errorf("error getting generateManifestStream: %s", err)
@@ -1341,7 +1516,7 @@ func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []s
opts := []cmp.SenderOption{
cmp.WithTarDoneChan(tarDoneCh),
}
err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, opts...)
err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, tarExcludedGlobs, opts...)
if err != nil {
return nil, fmt.Errorf("error sending file to cmp-server: %s", err)
}
@@ -1359,7 +1534,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
return err
}
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName, q.EnabledSourceTypes)
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName, q.EnabledSourceTypes, s.initConstants.CMPTarExcludedGlobs)
if err != nil {
return err
}
@@ -1434,8 +1609,12 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
return err
}
if err := loadFileIntoIfExists(filepath.Join(appPath, "values.yaml"), &res.Helm.Values); err != nil {
return err
if resolvedValuesPath, _, err := pathutil.ResolveFilePath(appPath, repoRoot, "values.yaml", []string{}); err == nil {
if err := loadFileIntoIfExists(resolvedValuesPath, &res.Helm.Values); err != nil {
return err
}
} else {
log.Warnf("Values file %s is not allowed: %v", filepath.Join(appPath, "values.yaml"), err)
}
var resolvedSelectedValueFiles []pathutil.ResolvedFilePath
// drop not allowed values files
@@ -1443,10 +1622,10 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
if resolvedFile, _, err := pathutil.ResolveFilePath(appPath, repoRoot, file, q.GetValuesFileSchemes()); err == nil {
resolvedSelectedValueFiles = append(resolvedSelectedValueFiles, resolvedFile)
} else {
log.Debugf("Values file %s is not allowed: %v", file, err)
log.Warnf("Values file %s is not allowed: %v", file, err)
}
}
params, err := h.GetParameters(resolvedSelectedValueFiles)
params, err := h.GetParameters(resolvedSelectedValueFiles, appPath, repoRoot)
if err != nil {
return err
}
@@ -1465,15 +1644,16 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
return nil
}
func loadFileIntoIfExists(path string, destination *string) error {
info, err := os.Stat(path)
func loadFileIntoIfExists(path pathutil.ResolvedFilePath, destination *string) error {
stringPath := string(path)
info, err := os.Stat(stringPath)
if err == nil && !info.IsDir() {
if bytes, err := ioutil.ReadFile(path); err != nil {
*destination = string(bytes)
} else {
bytes, err := ioutil.ReadFile(stringPath)
if err != nil {
return err
}
*destination = string(bytes)
}
return nil

View File

@@ -1,47 +0,0 @@
//go:build !race
// +build !race
package repository
import (
"os"
"path/filepath"
"sync"
"testing"
"github.com/stretchr/testify/assert"
argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
)
func TestHelmDependencyWithConcurrency(t *testing.T) {
// !race:
// Un-synchronized use of a random source, will be fixed when this is merged:
// https://github.com/argoproj/argo-cd/issues/4728
cleanup := func() {
_ = os.Remove(filepath.Join("../../util/helm/testdata/dependency", helmDepUpMarkerFile))
_ = os.RemoveAll(filepath.Join("../../util/helm/testdata/dependency", "charts"))
}
cleanup()
defer cleanup()
helmRepo := argoappv1.Repository{Name: "bitnami", Type: "helm", Repo: "https://charts.bitnami.com/bitnami"}
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 3; i++ {
go func() {
res, err := helmTemplate("../../util/helm/testdata/dependency", "../..", nil, &apiclient.ManifestRequest{
ApplicationSource: &argoappv1.ApplicationSource{},
Repos: []*argoappv1.Repository{&helmRepo},
}, false)
assert.NoError(t, err)
assert.NotNil(t, res)
wg.Done()
}()
}
wg.Wait()
}

View File

@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
goio "io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
@@ -16,6 +17,9 @@ import (
"testing"
"time"
log "github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/api/resource"
"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -129,6 +133,31 @@ func newServiceWithCommitSHA(root, revision string) *Service {
return service
}
// createSymlink creates a symlink with name linkName to file destName in
// workingDir
func createSymlink(t *testing.T, workingDir, destName, linkName string) error {
oldWorkingDir, err := os.Getwd()
if err != nil {
return err
}
if workingDir != "" {
err = os.Chdir(workingDir)
if err != nil {
return err
}
defer func() {
if err := os.Chdir(oldWorkingDir); err != nil {
t.Fatal(err.Error())
}
}()
}
err = os.Symlink(destName, linkName)
if err != nil {
return err
}
return nil
}
func TestGenerateYamlManifestInDir(t *testing.T) {
service := newService("../..")
@@ -136,7 +165,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) {
q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src}
// update this value if we add/remove manifests
const countOfManifests = 46
const countOfManifests = 47
res1, err := service.GenerateManifest(context.Background(), &q)
@@ -144,11 +173,81 @@ func TestGenerateYamlManifestInDir(t *testing.T) {
assert.Equal(t, countOfManifests, len(res1.Manifests))
// this will test concatenated manifests to verify we split YAMLs correctly
res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{})
res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"))
assert.NoError(t, err)
assert.Equal(t, 3, len(res2.Manifests))
}
func Test_GenerateManifests_NoOutOfBoundsAccess(t *testing.T) {
testCases := []struct {
name string
outOfBoundsFilename string
outOfBoundsFileContents string
mustNotContain string // Optional string that must not appear in error or manifest output. If empty, use outOfBoundsFileContents.
}{
{
name: "out of bounds JSON file should not appear in error output",
outOfBoundsFilename: "test.json",
outOfBoundsFileContents: `{"some": "json"}`,
},
{
name: "malformed JSON file contents should not appear in error output",
outOfBoundsFilename: "test.json",
outOfBoundsFileContents: "$",
},
{
name: "out of bounds JSON manifest should not appear in manifest output",
outOfBoundsFilename: "test.json",
// JSON marshalling is deterministic. So if there's a leak, exactly this should appear in the manifests.
outOfBoundsFileContents: `{"apiVersion":"v1","kind":"Secret","metadata":{"name":"test","namespace":"default"},"type":"Opaque"}`,
},
{
name: "out of bounds YAML manifest should not appear in manifest output",
outOfBoundsFilename: "test.yaml",
outOfBoundsFileContents: "apiVersion: v1\nkind: Secret\nmetadata:\n name: test\n namespace: default\ntype: Opaque",
mustNotContain: `{"apiVersion":"v1","kind":"Secret","metadata":{"name":"test","namespace":"default"},"type":"Opaque"}`,
},
}
for _, testCase := range testCases {
testCaseCopy := testCase
t.Run(testCaseCopy.name, func(t *testing.T) {
t.Parallel()
outOfBoundsDir := t.TempDir()
outOfBoundsFile := path.Join(outOfBoundsDir, testCaseCopy.outOfBoundsFilename)
err := os.WriteFile(outOfBoundsFile, []byte(testCaseCopy.outOfBoundsFileContents), os.FileMode(0444))
require.NoError(t, err)
repoDir := t.TempDir()
err = os.Symlink(outOfBoundsFile, path.Join(repoDir, testCaseCopy.outOfBoundsFilename))
require.NoError(t, err)
var mustNotContain = testCaseCopy.outOfBoundsFileContents
if testCaseCopy.mustNotContain != "" {
mustNotContain = testCaseCopy.mustNotContain
}
q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}}
res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"))
require.Error(t, err)
assert.NotContains(t, err.Error(), mustNotContain)
assert.Contains(t, err.Error(), "illegal filepath")
assert.Nil(t, res)
})
}
}
func TestGenerateManifests_MissingSymlinkDestination(t *testing.T) {
repoDir := t.TempDir()
err := os.Symlink("/obviously/does/not/exist", path.Join(repoDir, "test.yaml"))
require.NoError(t, err)
q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}}
_, err = GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"))
require.NoError(t, err)
}
func TestGenerateManifests_K8SAPIResetCache(t *testing.T) {
service := newService("../..")
@@ -283,28 +382,6 @@ func TestGenerateJsonnetLibOutside(t *testing.T) {
require.Contains(t, err.Error(), "value file '../../../testdata/jsonnet/vendor' resolved to outside repository root")
}
func TestGenerateHelmChartWithDependencies(t *testing.T) {
service := newService("../..")
cleanup := func() {
_ = os.Remove(filepath.Join("../../util/helm/testdata/dependency", helmDepUpMarkerFile))
_ = os.RemoveAll(filepath.Join("../../util/helm/testdata/dependency", "charts"))
}
cleanup()
defer cleanup()
helmRepo := argoappv1.Repository{Name: "bitnami", Type: "helm", Repo: "https://charts.bitnami.com/bitnami"}
q := apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
ApplicationSource: &argoappv1.ApplicationSource{
Path: "./util/helm/testdata/dependency",
},
Repos: []*argoappv1.Repository{&helmRepo},
}
res1, err := service.GenerateManifest(context.Background(), &q)
assert.Nil(t, err)
assert.Len(t, res1.Manifests, 10)
}
func TestManifestGenErrorCacheByNumRequests(t *testing.T) {
// Returns the state of the manifest generation cache, by querying the cache for the previously set result
@@ -997,15 +1074,15 @@ func TestGenerateNullList(t *testing.T) {
}
func TestIdentifyAppSourceTypeByAppDirWithKustomizations(t *testing.T) {
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp", map[string]bool{})
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp", map[string]bool{}, []string{})
assert.Nil(t, err)
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp", map[string]bool{})
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp", map[string]bool{}, []string{})
assert.Nil(t, err)
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp", map[string]bool{})
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp", map[string]bool{}, []string{})
assert.Nil(t, err)
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
}
@@ -1031,7 +1108,7 @@ func TestRunCustomTool(t *testing.T) {
Name: "test",
Generate: argoappv1.Command{
Command: []string{"sh", "-c"},
Args: []string{`echo "{\"kind\": \"FakeObject\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"GIT_ASKPASS\": \"$GIT_ASKPASS\", \"GIT_USERNAME\": \"$GIT_USERNAME\", \"GIT_PASSWORD\": \"$GIT_PASSWORD\"}, \"labels\": {\"revision\": \"$TEST_REVISION\"}}}"`},
Args: []string{`echo "{\"kind\": \"FakeObject\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"GIT_ASKPASS\": \"$GIT_ASKPASS\", \"GIT_USERNAME\": \"$GIT_USERNAME\", \"GIT_PASSWORD\": \"$GIT_PASSWORD\"}, \"labels\": {\"revision\": \"$ARGOCD_ENV_TEST_REVISION\"}}}"`},
},
}},
Repo: &argoappv1.Repository{
@@ -1058,7 +1135,7 @@ func TestGenerateFromUTF16(t *testing.T) {
Repo: &argoappv1.Repository{},
ApplicationSource: &argoappv1.ApplicationSource{},
}
res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{})
res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"))
assert.Nil(t, err)
assert.Equal(t, 2, len(res1.Manifests))
}
@@ -1070,16 +1147,20 @@ func TestListApps(t *testing.T) {
assert.NoError(t, err)
expectedApps := map[string]string{
"Kustomization": "Kustomize",
"app-parameters/multi": "Kustomize",
"app-parameters/single-app-only": "Kustomize",
"app-parameters/single-global": "Kustomize",
"invalid-helm": "Helm",
"invalid-kustomize": "Kustomize",
"kustomization_yaml": "Kustomize",
"kustomization_yml": "Kustomize",
"my-chart": "Helm",
"my-chart-2": "Helm",
"Kustomization": "Kustomize",
"app-parameters/multi": "Kustomize",
"app-parameters/single-app-only": "Kustomize",
"app-parameters/single-global": "Kustomize",
"app-parameters/single-global-helm": "Helm",
"invalid-helm": "Helm",
"in-bounds-values-file-link": "Helm",
"invalid-kustomize": "Kustomize",
"kustomization_yaml": "Kustomize",
"kustomization_yml": "Kustomize",
"my-chart": "Helm",
"my-chart-2": "Helm",
"out-of-bounds-values-file-link": "Helm",
"values-files": "Helm",
}
assert.Equal(t, expectedApps, res.Apps)
}
@@ -1398,6 +1479,7 @@ func mkTempParameters(source string) string {
func runWithTempTestdata(t *testing.T, path string, runner func(t *testing.T, path string)) {
tempDir := mkTempParameters("./testdata/app-parameters")
runner(t, filepath.Join(tempDir, "app-parameters", path))
os.RemoveAll(tempDir)
}
func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
@@ -1430,6 +1512,35 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
})
})
t.Run("Single global override Helm", func(t *testing.T) {
runWithTempTestdata(t, "single-global-helm", func(t *testing.T, path string) {
service := newService(".")
manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
ApplicationSource: &argoappv1.ApplicationSource{
Path: path,
},
})
require.NoError(t, err)
resourceByKindName := make(map[string]*unstructured.Unstructured)
for _, manifest := range manifests.Manifests {
var un unstructured.Unstructured
err := yaml.Unmarshal([]byte(manifest), &un)
if !assert.NoError(t, err) {
return
}
resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un
}
deployment, ok := resourceByKindName["Deployment/guestbook-ui"]
require.True(t, ok)
containers, ok, _ := unstructured.NestedSlice(deployment.Object, "spec", "template", "spec", "containers")
require.True(t, ok)
image, ok, _ := unstructured.NestedString(containers[0].(map[string]interface{}), "image")
require.True(t, ok)
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.2", image)
})
})
t.Run("Application specific override", func(t *testing.T) {
service := newService(".")
runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) {
@@ -1489,6 +1600,28 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) {
assert.Equal(t, "gcr.io/heptio-images/ks-guestbook-demo:0.1", image)
})
})
t.Run("Override info does not appear in cache key", func(t *testing.T) {
service := newService(".")
runWithTempTestdata(t, "single-global", func(t *testing.T, path string) {
source := &argoappv1.ApplicationSource{
Path: path,
}
sourceCopy := source.DeepCopy() // make a copy in case GenerateManifest mutates it.
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
ApplicationSource: sourceCopy,
AppName: "test",
})
assert.NoError(t, err)
res := &cache.CachedManifestResponse{}
// Try to pull from the cache with a `source` that does not include any overrides. Overrides should not be
// part of the cache key, because you can't get the overrides without a repo operation. And avoiding repo
// operations is the point of the cache.
err = service.cache.GetManifests(mock.Anything, source, &argoappv1.ClusterInfo{}, "", "", "", "test", res)
assert.NoError(t, err)
})
})
}
func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) {
@@ -1599,11 +1732,11 @@ func TestFindResources(t *testing.T) {
for i := range testCases {
tc := testCases[i]
t.Run(tc.name, func(t *testing.T) {
objs, err := findManifests("testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
Recurse: true,
Include: tc.include,
Exclude: tc.exclude,
}, map[string]bool{})
}, map[string]bool{}, resource.MustParse("0"))
if !assert.NoError(t, err) {
return
}
@@ -1617,10 +1750,10 @@ func TestFindResources(t *testing.T) {
}
func TestFindManifests_Exclude(t *testing.T) {
objs, err := findManifests("testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
Recurse: true,
Exclude: "subdir/deploymentSub.yaml",
}, map[string]bool{})
}, map[string]bool{}, resource.MustParse("0"))
if !assert.NoError(t, err) || !assert.Len(t, objs, 1) {
return
@@ -1630,10 +1763,10 @@ func TestFindManifests_Exclude(t *testing.T) {
}
func TestFindManifests_Exclude_NothingMatches(t *testing.T) {
objs, err := findManifests("testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
objs, err := findManifests(&log.Entry{}, "testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
Recurse: true,
Exclude: "nothing.yaml",
}, map[string]bool{})
}, map[string]bool{}, resource.MustParse("0"))
if !assert.NoError(t, err) || !assert.Len(t, objs, 2) {
return
@@ -1643,6 +1776,477 @@ func TestFindManifests_Exclude_NothingMatches(t *testing.T) {
[]string{"nginx-deployment", "nginx-deployment-sub"}, []string{objs[0].GetName(), objs[1].GetName()})
}
func tempDir(t *testing.T) string {
dir, err := ioutil.TempDir(".", "")
require.NoError(t, err)
t.Cleanup(func() {
err = os.RemoveAll(dir)
if err != nil {
panic(err)
}
})
absDir, err := filepath.Abs(dir)
require.NoError(t, err)
return absDir
}
func walkFor(t *testing.T, root string, testPath string, run func(info fs.FileInfo)) {
var hitExpectedPath = false
err := filepath.Walk(root, func(path string, info fs.FileInfo, err error) error {
if path == testPath {
require.NoError(t, err)
hitExpectedPath = true
run(info)
}
return nil
})
require.NoError(t, err)
assert.True(t, hitExpectedPath, "did not hit expected path when walking directory")
}
func Test_getPotentiallyValidManifestFile(t *testing.T) {
// These tests use filepath.Walk instead of os.Stat to get file info, because FileInfo from os.Stat does not return
// true for IsSymlink like os.Walk does.
// These tests do not use t.TempDir() because those directories can contain symlinks which cause test to fail
// InBound checks.
t.Run("non-JSON/YAML is skipped with an empty ignore message", func(t *testing.T) {
appDir := tempDir(t)
filePath := filepath.Join(appDir, "not-json-or-yaml")
file, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
require.NoError(t, err)
err = file.Close()
require.NoError(t, err)
walkFor(t, appDir, filePath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "", "")
assert.Nil(t, realFileInfo)
assert.Empty(t, ignoreMessage)
assert.NoError(t, err)
})
})
t.Run("circular link should throw an error", func(t *testing.T) {
appDir := tempDir(t)
aPath := filepath.Join(appDir, "a.json")
bPath := filepath.Join(appDir, "b.json")
err := os.Symlink(bPath, aPath)
require.NoError(t, err)
err = os.Symlink(aPath, bPath)
require.NoError(t, err)
walkFor(t, appDir, aPath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(aPath, info, appDir, appDir, "", "")
assert.Nil(t, realFileInfo)
assert.Empty(t, ignoreMessage)
assert.ErrorContains(t, err, "too many links")
})
})
t.Run("symlink with missing destination should throw an error", func(t *testing.T) {
appDir := tempDir(t)
aPath := filepath.Join(appDir, "a.json")
bPath := filepath.Join(appDir, "b.json")
err := os.Symlink(bPath, aPath)
require.NoError(t, err)
walkFor(t, appDir, aPath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(aPath, info, appDir, appDir, "", "")
assert.Nil(t, realFileInfo)
assert.NotEmpty(t, ignoreMessage)
assert.NoError(t, err)
})
})
t.Run("out-of-bounds symlink should throw an error", func(t *testing.T) {
appDir := tempDir(t)
linkPath := filepath.Join(appDir, "a.json")
err := os.Symlink("..", linkPath)
require.NoError(t, err)
walkFor(t, appDir, linkPath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(linkPath, info, appDir, appDir, "", "")
assert.Nil(t, realFileInfo)
assert.Empty(t, ignoreMessage)
assert.ErrorContains(t, err, "illegal filepath in symlink")
})
})
t.Run("symlink to a non-regular file should be skipped with warning", func(t *testing.T) {
appDir := tempDir(t)
dirPath := filepath.Join(appDir, "test.dir")
err := os.MkdirAll(dirPath, 0644)
require.NoError(t, err)
linkPath := filepath.Join(appDir, "test.json")
err = os.Symlink(dirPath, linkPath)
require.NoError(t, err)
walkFor(t, appDir, linkPath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(linkPath, info, appDir, appDir, "", "")
assert.Nil(t, realFileInfo)
assert.Contains(t, ignoreMessage, "non-regular file")
assert.NoError(t, err)
})
})
t.Run("non-included file should be skipped with no message", func(t *testing.T) {
appDir := tempDir(t)
filePath := filepath.Join(appDir, "not-included.yaml")
file, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
require.NoError(t, err)
err = file.Close()
require.NoError(t, err)
walkFor(t, appDir, filePath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "*.json", "")
assert.Nil(t, realFileInfo)
assert.Empty(t, ignoreMessage)
assert.NoError(t, err)
})
})
t.Run("excluded file should be skipped with no message", func(t *testing.T) {
appDir := tempDir(t)
filePath := filepath.Join(appDir, "excluded.json")
file, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
require.NoError(t, err)
err = file.Close()
require.NoError(t, err)
walkFor(t, appDir, filePath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "", "excluded.*")
assert.Nil(t, realFileInfo)
assert.Empty(t, ignoreMessage)
assert.NoError(t, err)
})
})
t.Run("symlink to a regular file is potentially valid", func(t *testing.T) {
appDir := tempDir(t)
filePath := filepath.Join(appDir, "regular-file")
file, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
require.NoError(t, err)
err = file.Close()
require.NoError(t, err)
linkPath := filepath.Join(appDir, "link.json")
err = os.Symlink(filePath, linkPath)
require.NoError(t, err)
walkFor(t, appDir, linkPath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(linkPath, info, appDir, appDir, "", "")
assert.NotNil(t, realFileInfo)
assert.Empty(t, ignoreMessage)
assert.NoError(t, err)
})
})
t.Run("a regular file is potentially valid", func(t *testing.T) {
appDir := tempDir(t)
filePath := filepath.Join(appDir, "regular-file.json")
file, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
require.NoError(t, err)
err = file.Close()
require.NoError(t, err)
walkFor(t, appDir, filePath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "", "")
assert.NotNil(t, realFileInfo)
assert.Empty(t, ignoreMessage)
assert.NoError(t, err)
})
})
t.Run("realFileInfo is for the destination rather than the symlink", func(t *testing.T) {
appDir := tempDir(t)
filePath := filepath.Join(appDir, "regular-file")
file, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
require.NoError(t, err)
err = file.Close()
require.NoError(t, err)
linkPath := filepath.Join(appDir, "link.json")
err = os.Symlink(filePath, linkPath)
require.NoError(t, err)
walkFor(t, appDir, linkPath, func(info fs.FileInfo) {
realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(linkPath, info, appDir, appDir, "", "")
assert.NotNil(t, realFileInfo)
assert.Equal(t, filepath.Base(filePath), realFileInfo.Name())
assert.Empty(t, ignoreMessage)
assert.NoError(t, err)
})
})
}
func Test_getPotentiallyValidManifests(t *testing.T) {
// Tests which return no manifests and an error check to make sure the directory exists before running. A missing
// directory would produce those same results.
logCtx := log.WithField("test", "test")
t.Run("unreadable file throws error", func(t *testing.T) {
appDir := t.TempDir()
unreadablePath := filepath.Join(appDir, "unreadable.json")
err := os.WriteFile(unreadablePath, []byte{}, 0666)
require.NoError(t, err)
err = os.Chmod(appDir, 0000)
require.NoError(t, err)
manifests, err := getPotentiallyValidManifests(logCtx, appDir, appDir, false, "", "", resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
// allow cleanup
err = os.Chmod(appDir, 0777)
if err != nil {
panic(err)
}
})
t.Run("no recursion when recursion is disabled", func(t *testing.T) {
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/recurse", "./testdata/recurse", false, "", "", resource.MustParse("0"))
assert.Len(t, manifests, 1)
assert.NoError(t, err)
})
t.Run("recursion when recursion is enabled", func(t *testing.T) {
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/recurse", "./testdata/recurse", true, "", "", resource.MustParse("0"))
assert.Len(t, manifests, 2)
assert.NoError(t, err)
})
t.Run("non-JSON/YAML is skipped", func(t *testing.T) {
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/non-manifest-file", "./testdata/non-manifest-file", false, "", "", resource.MustParse("0"))
assert.Empty(t, manifests)
assert.NoError(t, err)
})
t.Run("circular link should throw an error", func(t *testing.T) {
const testDir = "./testdata/circular-link"
require.DirExists(t, testDir)
require.NoError(t, createSymlink(t, testDir, "a.json", "b.json"))
defer os.Remove(path.Join(testDir, "a.json"))
require.NoError(t, createSymlink(t, testDir, "b.json", "a.json"))
defer os.Remove(path.Join(testDir, "b.json"))
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", false, "", "", resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("out-of-bounds symlink should throw an error", func(t *testing.T) {
require.DirExists(t, "./testdata/out-of-bounds-link")
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/out-of-bounds-link", "./testdata/out-of-bounds-link", false, "", "", resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("symlink to a regular file works", func(t *testing.T) {
repoRoot, err := filepath.Abs("./testdata/in-bounds-link")
require.NoError(t, err)
appPath, err := filepath.Abs("./testdata/in-bounds-link/app")
require.NoError(t, err)
manifests, err := getPotentiallyValidManifests(logCtx, appPath, repoRoot, false, "", "", resource.MustParse("0"))
assert.Len(t, manifests, 1)
assert.NoError(t, err)
})
t.Run("symlink to nowhere should be ignored", func(t *testing.T) {
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/link-to-nowhere", "./testdata/link-to-nowhere", false, "", "", resource.MustParse("0"))
assert.Empty(t, manifests)
assert.NoError(t, err)
})
t.Run("link to over-sized manifest fails", func(t *testing.T) {
repoRoot, err := filepath.Abs("./testdata/in-bounds-link")
require.NoError(t, err)
appPath, err := filepath.Abs("./testdata/in-bounds-link/app")
require.NoError(t, err)
// The file is 35 bytes.
manifests, err := getPotentiallyValidManifests(logCtx, appPath, repoRoot, false, "", "", resource.MustParse("34"))
assert.Empty(t, manifests)
assert.ErrorIs(t, err, ErrExceededMaxCombinedManifestFileSize)
})
t.Run("group of files should be limited at precisely the sum of their size", func(t *testing.T) {
// There is a total of 10 files, ech file being 10 bytes.
manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/several-files", "./testdata/several-files", false, "", "", resource.MustParse("365"))
assert.Len(t, manifests, 10)
assert.NoError(t, err)
manifests, err = getPotentiallyValidManifests(logCtx, "./testdata/several-files", "./testdata/several-files", false, "", "", resource.MustParse("100"))
assert.Empty(t, manifests)
assert.ErrorIs(t, err, ErrExceededMaxCombinedManifestFileSize)
})
}
func Test_findManifests(t *testing.T) {
logCtx := log.WithField("test", "test")
noRecurse := argoappv1.ApplicationSourceDirectory{Recurse: false}
t.Run("unreadable file throws error", func(t *testing.T) {
appDir := t.TempDir()
unreadablePath := filepath.Join(appDir, "unreadable.json")
err := os.WriteFile(unreadablePath, []byte{}, 0666)
require.NoError(t, err)
err = os.Chmod(appDir, 0000)
require.NoError(t, err)
manifests, err := findManifests(logCtx, appDir, appDir, nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
// allow cleanup
err = os.Chmod(appDir, 0777)
if err != nil {
panic(err)
}
})
t.Run("no recursion when recursion is disabled", func(t *testing.T) {
manifests, err := findManifests(logCtx, "./testdata/recurse", "./testdata/recurse", nil, noRecurse, nil, resource.MustParse("0"))
assert.Len(t, manifests, 2)
assert.NoError(t, err)
})
t.Run("recursion when recursion is enabled", func(t *testing.T) {
recurse := argoappv1.ApplicationSourceDirectory{Recurse: true}
manifests, err := findManifests(logCtx, "./testdata/recurse", "./testdata/recurse", nil, recurse, nil, resource.MustParse("0"))
assert.Len(t, manifests, 4)
assert.NoError(t, err)
})
t.Run("non-JSON/YAML is skipped", func(t *testing.T) {
manifests, err := findManifests(logCtx, "./testdata/non-manifest-file", "./testdata/non-manifest-file", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.NoError(t, err)
})
t.Run("circular link should throw an error", func(t *testing.T) {
const testDir = "./testdata/circular-link"
require.DirExists(t, testDir)
require.NoError(t, createSymlink(t, testDir, "a.json", "b.json"))
defer os.Remove(path.Join(testDir, "a.json"))
require.NoError(t, createSymlink(t, testDir, "b.json", "a.json"))
defer os.Remove(path.Join(testDir, "b.json"))
manifests, err := findManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("out-of-bounds symlink should throw an error", func(t *testing.T) {
require.DirExists(t, "./testdata/out-of-bounds-link")
manifests, err := findManifests(logCtx, "./testdata/out-of-bounds-link", "./testdata/out-of-bounds-link", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("symlink to a regular file works", func(t *testing.T) {
repoRoot, err := filepath.Abs("./testdata/in-bounds-link")
require.NoError(t, err)
appPath, err := filepath.Abs("./testdata/in-bounds-link/app")
require.NoError(t, err)
manifests, err := findManifests(logCtx, appPath, repoRoot, nil, noRecurse, nil, resource.MustParse("0"))
assert.Len(t, manifests, 1)
assert.NoError(t, err)
})
t.Run("symlink to nowhere should be ignored", func(t *testing.T) {
manifests, err := findManifests(logCtx, "./testdata/link-to-nowhere", "./testdata/link-to-nowhere", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.NoError(t, err)
})
t.Run("link to over-sized manifest fails", func(t *testing.T) {
repoRoot, err := filepath.Abs("./testdata/in-bounds-link")
require.NoError(t, err)
appPath, err := filepath.Abs("./testdata/in-bounds-link/app")
require.NoError(t, err)
// The file is 35 bytes.
manifests, err := findManifests(logCtx, appPath, repoRoot, nil, noRecurse, nil, resource.MustParse("34"))
assert.Empty(t, manifests)
assert.ErrorIs(t, err, ErrExceededMaxCombinedManifestFileSize)
})
t.Run("group of files should be limited at precisely the sum of their size", func(t *testing.T) {
// There is a total of 10 files, each file being 10 bytes.
manifests, err := findManifests(logCtx, "./testdata/several-files", "./testdata/several-files", nil, noRecurse, nil, resource.MustParse("365"))
assert.Len(t, manifests, 10)
assert.NoError(t, err)
manifests, err = findManifests(logCtx, "./testdata/several-files", "./testdata/several-files", nil, noRecurse, nil, resource.MustParse("364"))
assert.Empty(t, manifests)
assert.ErrorIs(t, err, ErrExceededMaxCombinedManifestFileSize)
})
t.Run("jsonnet isn't counted against size limit", func(t *testing.T) {
// Each file is 36 bytes. Only the 36-byte json file should be counted against the limit.
manifests, err := findManifests(logCtx, "./testdata/jsonnet-and-json", "./testdata/jsonnet-and-json", nil, noRecurse, nil, resource.MustParse("36"))
assert.Len(t, manifests, 2)
assert.NoError(t, err)
manifests, err = findManifests(logCtx, "./testdata/jsonnet-and-json", "./testdata/jsonnet-and-json", nil, noRecurse, nil, resource.MustParse("35"))
assert.Empty(t, manifests)
assert.ErrorIs(t, err, ErrExceededMaxCombinedManifestFileSize)
})
t.Run("partially valid YAML file throws an error", func(t *testing.T) {
require.DirExists(t, "./testdata/partially-valid-yaml")
manifests, err := findManifests(logCtx, "./testdata/partially-valid-yaml", "./testdata/partially-valid-yaml", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("invalid manifest throws an error", func(t *testing.T) {
require.DirExists(t, "./testdata/invalid-manifests")
manifests, err := findManifests(logCtx, "./testdata/invalid-manifests", "./testdata/invalid-manifests", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("irrelevant YAML gets skipped, relevant YAML gets parsed", func(t *testing.T) {
manifests, err := findManifests(logCtx, "./testdata/irrelevant-yaml", "./testdata/irrelevant-yaml", nil, noRecurse, nil, resource.MustParse("0"))
assert.Len(t, manifests, 1)
assert.NoError(t, err)
})
t.Run("multiple JSON objects in one file throws an error", func(t *testing.T) {
require.DirExists(t, "./testdata/json-list")
manifests, err := findManifests(logCtx, "./testdata/json-list", "./testdata/json-list", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("invalid JSON throws an error", func(t *testing.T) {
require.DirExists(t, "./testdata/invalid-json")
manifests, err := findManifests(logCtx, "./testdata/invalid-json", "./testdata/invalid-json", nil, noRecurse, nil, resource.MustParse("0"))
assert.Empty(t, manifests)
assert.Error(t, err)
})
t.Run("valid JSON returns manifest and no error", func(t *testing.T) {
manifests, err := findManifests(logCtx, "./testdata/valid-json", "./testdata/valid-json", nil, noRecurse, nil, resource.MustParse("0"))
assert.Len(t, manifests, 1)
assert.NoError(t, err)
})
t.Run("YAML with an empty document doesn't throw an error", func(t *testing.T) {
manifests, err := findManifests(logCtx, "./testdata/yaml-with-empty-document", "./testdata/yaml-with-empty-document", nil, noRecurse, nil, resource.MustParse("0"))
assert.Len(t, manifests, 1)
assert.NoError(t, err)
})
}
func TestTestRepoOCI(t *testing.T) {
service := newService(".")
_, err := service.TestRepository(context.Background(), &apiclient.TestRepositoryRequest{
@@ -1825,3 +2429,52 @@ func runGit(t *testing.T, workDir string, args ...string) string {
require.NoError(t, err, stringOut)
return stringOut
}
func Test_findHelmValueFilesInPath(t *testing.T) {
t.Run("does not exist", func(t *testing.T) {
files, err := findHelmValueFilesInPath("/obviously/does/not/exist")
assert.Error(t, err)
assert.Empty(t, files)
})
t.Run("values files", func(t *testing.T) {
files, err := findHelmValueFilesInPath("./testdata/values-files")
assert.NoError(t, err)
assert.Len(t, files, 4)
})
}
func Test_populateHelmAppDetails(t *testing.T) {
res := apiclient.RepoAppDetailsResponse{}
q := apiclient.RepoServerAppDetailsQuery{
Repo: &argoappv1.Repository{},
Source: &argoappv1.ApplicationSource{
Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{"exclude.yaml", "has-the-word-values.yaml"}},
},
}
appPath, err := filepath.Abs("./testdata/values-files/")
require.NoError(t, err)
err = populateHelmAppDetails(&res, appPath, appPath, &q)
require.NoError(t, err)
assert.Len(t, res.Helm.Parameters, 3)
assert.Len(t, res.Helm.ValueFiles, 4)
}
func Test_populateHelmAppDetails_values_symlinks(t *testing.T) {
t.Run("inbound", func(t *testing.T) {
res := apiclient.RepoAppDetailsResponse{}
q := apiclient.RepoServerAppDetailsQuery{Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{}}
err := populateHelmAppDetails(&res, "./testdata/in-bounds-values-file-link/", "./testdata/in-bounds-values-file-link/", &q)
require.NoError(t, err)
assert.NotEmpty(t, res.Helm.Values)
assert.NotEmpty(t, res.Helm.Parameters)
})
t.Run("out of bounds", func(t *testing.T) {
res := apiclient.RepoAppDetailsResponse{}
q := apiclient.RepoServerAppDetailsQuery{Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{}}
err := populateHelmAppDetails(&res, "./testdata/out-of-bounds-values-file-link/", "./testdata/out-of-bounds-values-file-link/", &q)
require.NoError(t, err)
assert.Empty(t, res.Helm.Values)
assert.Empty(t, res.Helm.Parameters)
})
}

View File

@@ -0,0 +1,4 @@
helm:
parameters:
- name: image.tag
value: '0.2'

View File

@@ -0,0 +1,2 @@
name: my-chart
version: 1.1.0

View File

@@ -0,0 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: guestbook-ui
spec:
selector:
matchLabels:
app: guestbook-ui
template:
metadata:
labels:
app: guestbook-ui
spec:
containers:
- image: gcr.io/heptio-images/ks-guestbook-demo:{{.Values.image.tag}}
name: guestbook-ui
ports:
- containerPort: 81

View File

@@ -0,0 +1,2 @@
image:
tag: 0.1

View File

View File

@@ -0,0 +1 @@
../cm.yaml

View File

@@ -0,0 +1,2 @@
apiVersion: v1
kind: ServiceAccount

View File

@@ -0,0 +1,2 @@
name: my-chart
version: 1.1.0

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