Compare commits

...

68 Commits

Author SHA1 Message Date
argo-bot
fe42780229 Bump version to 2.3.0 2022-03-06 06:18:59 +00:00
argo-bot
057d95374d Bump version to 2.3.0 2022-03-06 06:18:41 +00:00
Yuan Tang
1546c1d314 fix: Health status bar button does not re-render properly. Fixes #8569 (#8668)
fix: Health status bar button does not re-render properly. Fixes #8569 (#8668)

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2022-03-04 10:41:25 -08:00
jannfis
31564c6067 fix: Allow quoted RBAC group names in API (#8650)
Signed-off-by: jannfis <jann@mistrust.net>
Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>

Co-authored-by: Michael Crenshaw <michael@crenshaw.dev>
2022-03-04 07:35:21 +00:00
Alexander Matyushentsev
6e54e59e82 fix: prevent file traversal using helm file values param and application details api (#8606)
* fix: prevent file traversal using helm file values param and application details api

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

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

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:43:03 -08:00
Alexander Matyushentsev
196dab98dc Unique repo path and permissions (#8517)
Unique repo path and permissions (#8517)

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:42:59 -08:00
Michael Crenshaw
9d4ed2847e chore: bump redoc vesion to avoid CVE-2021-23820 (#8604)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-02-25 15:42:52 -08:00
Yuan Tang
ffc6080060 build: Bump up network timeout during yarn install (#8601)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2022-02-25 15:42:46 -08:00
Alexander Matyushentsev
ca2e3041f1 refactor: use argocd-git-ask-pass to pass git credentials to git/kustomize (#8516)
refactor: use argocd-git-ask-pass to pass git credentials to git/kustomize  (#8516)

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:42:11 -08:00
Michael Crenshaw
31676e2aea fix: add labels to sidecar CMP manifests (#8243) (#8367)
fix: add labels to sidecar CMP manifests (#8243) (#8367)

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-02-25 15:42:05 -08:00
Michael Crenshaw
81f9bc20ec chore: pass submodulesEnabled explicitly to avoid implicit parameter (#8337)
* chore: pass submodulesEnabled explicitly to avoid implicit parameter

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

* fix: update mock

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

* chore: lint

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

* fix: mock checkout invocations w/ 2 params

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

* chore: remove unnecessary comment

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-02-25 15:40:20 -08:00
Jesse Suen
0b868bd221 fix!: enforce app create/update privileges when getting repo details (#8558)
Signed-off-by: Jesse Suen <jesse@akuity.io>
2022-02-25 15:39:26 -08:00
Yuan Tang
37c1585c2f feat(cli): Allow to view previously terminated container logs (#8582)
* feat(cli): Allow to view previously terminated container logs

This is useful when we want to see the snapshot of previously terminated container logs.

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

* chore: Generate docs

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2022-02-25 15:39:18 -08:00
pasha-codefresh
e095ef6e4c chore(deps): bump mkdocs from 1.1.2 to 1.2.3 in /docs (#8588)
chore(deps): bump mkdocs from 1.1.2 to 1.2.3 in /docs (#8588)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2022-02-25 15:39:04 -08:00
pasha-codefresh
8396e06121 fix: Upgrade monaco-editor from 0.15.6 to 0.27.0 (#8590)
fix: Upgrade monaco-editor from 0.15.6 to 0.27.0 (#8590)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2022-02-25 15:38:57 -08:00
Ben Ye
d4a6498d80 feat: expose cluster sync retry duration (#8481)
Signed-off-by: Ben Ye <ben.ye@bytedance.com>
2022-02-25 15:38:49 -08:00
Yi Cai
4fc814bc16 fix: UI: Favorite star icon is cut off (#8556)
* fix: UI: Favorite star icon is cut off

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

* fixed lint error

Signed-off-by: ciiay <yicai@redhat.com>
2022-02-25 15:38:39 -08:00
Michael Crenshaw
bf67d55f3f chore: upgrade redoc (#8573)
Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-02-25 15:38:33 -08:00
dependabot[bot]
87402fdc4c build(deps): bump url-parse from 1.5.3 to 1.5.7 in /ui (#8557)
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.3 to 1.5.7.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.3...1.5.7)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-25 15:38:19 -08:00
Alexander Matyushentsev
10b4c47aad feat: support custom helm values file schemes (#8535)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:37:45 -08:00
Alexander Matyushentsev
e6a9400c38 feat: support disabling manifest generation using config management tools (#8514)
* feat: support disabling manifest generation using config management tools

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

* rename EnableManifestGenerationForSourceType to EnableSourceTypes

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:36:27 -08:00
Alexander Matyushentsev
ebb21736df fix: build ui as part of 'make release-cli' command (#8536)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:36:21 -08:00
Alexander Matyushentsev
ea7ad844cb fix: refreshing label is hidden by resource tree (#8391)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:36:12 -08:00
jannfis
76c0b32887 fix: Return early on error when updating clusters (#8526)
Signed-off-by: jannfis <jann@mistrust.net>
2022-02-25 15:36:06 -08:00
Christian Roth
827096c195 docs: Using Dex with OIDC needs the config element in yaml (#8510)
In order to get Dex working with an OIDC provider, I had to structure the Dex config according to the [Dex Documentation](https://dexidp.io/docs/connectors/oidc/#configuration).
This means placing the OIDC configuration within their own `config` element in the `dex.config`, rather than listing them on the same level as the generic connector settings.
2022-02-25 15:35:48 -08:00
Yuan Tang
bca450f7aa docs: Clarify sync wave precedence by kind and add note on delay between waves (#8518)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
2022-02-25 15:35:33 -08:00
Yuan Tang
3c7d99f82c test: Support e2e tests and improve robustness on k8s v1.21-v1.23 (#8431)
Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
Co-authored-by: Jesse Suen <jesse@akuity.io>
2022-02-25 15:35:23 -08:00
Daniel Helfand
c5c25cd75b docs: update ApplicationSet controller getting started link (#8482)
Signed-off-by: Daniel Helfand <helfand.4@gmail.com>
2022-02-25 15:35:09 -08:00
Jesse Suen
f54d0a037f chore: update protoc to 3.17.3 and make install portable (#7932)
Signed-off-by: Jesse Suen <jesse@akuity.io>
2022-02-25 15:34:44 -08:00
Alexander Matyushentsev
6da138956a docs: update chagelog - add v2.3.0, v2.2.1 ~ v2.2.3 releases (#8310)
docs: update chagelog - add v2.3.0, v2.2.1 ~ v2.2.3 releases (#8310)

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:34:24 -08:00
Keith Chong
b3a181ea88 fix: Adjust z-index for newly added tree view toolbar (#8422) (#8423)
Signed-off-by: Keith Chong <kykchong@redhat.com>
2022-02-25 15:33:20 -08:00
Alexander Matyushentsev
2f5da24654 feat: add RespectIgnoreDifferences sync option to UI (#8390)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:32:59 -08:00
Soumya Ghosh Dastidar
cc572a5eb2 fix(cli): argo app diff passes --api-versions to helm template (#8371)
Signed-off-by: Soumya Ghosh Dastidar <soumya@akuity.io>
2022-02-25 15:32:37 -08:00
Alexander Matyushentsev
ae03c3b872 chore: fix broken TestHelmIgnoreMissingValueFiles test (#8368)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:31:31 -08:00
Jonah Back
79ac472382 fix: check for issuing condition on Certificate (#7217)
Signed-off-by: Jonah Back <jonah@jonahback.com>

Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:31:16 -08:00
Chetan Banavikalmutt
061ba811f1 chore: upgrade Helm to v3.8.0 (#8301)
Signed-off-by: Chetan Banavikalmutt <chetanrns1997@gmail.com>
2022-02-25 15:29:49 -08:00
Alexander Matyushentsev
b5909d59ec refactor: update gitops-engine version to v0.6.0
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-25 15:27:15 -08:00
jannfis
68f17dbe8e feat: Make cluster cache sync more robust (#8438)
* feat: Support retry for list operations in cluster cache sync

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

* Fix default retries

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

* Pull in latest gitops-engine

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

* Default retry limit should be 1

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

* Make type conversion earlier

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

* Rename limit to attempt

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

* Revert Makefile change

Signed-off-by: jannfis <jann@mistrust.net>
2022-02-16 11:56:22 +00:00
Jesse Suen
bc6b4950ba docs: add security documentation related to git repositories (#8463)
Signed-off-by: Jesse Suen <jesse@akuity.io>
2022-02-11 13:48:10 -08:00
jannfis
c2cf633bbc feat: Allow fine-tuning of K8s rest client connection properties (#8404)
* feat: Allow fine-tuning of K8s rest client connection properties

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

* Move initialization

Signed-off-by: jannfis <jann@mistrust.net>
2022-02-09 09:05:24 +00:00
Jonathan West
bdd05d5c7a Update Argo CD V2.3 to ApplicationSet v0.4.0 (#8416)
Signed-off-by: Jonathan West <jonwest@redhat.com>
2022-02-07 10:49:14 -08:00
Ishita Sequeira
4b04a39180 fix: fix deployment config health status (#8376)
Signed-off-by: ishitasequeira <isequeir@redhat.com>
2022-02-06 11:20:56 -08:00
argo-bot
aa54aa7eda Bump version to 2.3.0-rc5 2022-02-04 23:32:12 +00:00
argo-bot
4bbd0e57dd Bump version to 2.3.0-rc5 2022-02-04 23:32:00 +00:00
fredericfran-gds
2d6b619a86 fix: reload ArgoCD config if OIDC config changes (#8350)
fix: reload ArgoCD config if OIDC config changes (#8350)

Signed-off-by: Frederic Francois <frederic.francois@digital.cabinet-office.gov.uk>
2022-02-04 15:08:59 -08:00
Leonardo Luz Almeida
39487ef7c7 chore: Generate spdx for the UI project (#8385)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-02-04 15:08:54 -08:00
jannfis
fcc7c0b080 fix: Resolve symlinked value files correctly (#8387)
* fix: Resolve symlinked value files correctly

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

* fix: Resolve symlinked value files correctly

Signed-off-by: jannfis <jann@mistrust.net>
2022-02-04 15:08:32 -08:00
argo-bot
ed734fedbb Bump version to 2.3.0-rc4 2022-02-03 21:46:08 +00:00
argo-bot
7414f2d42c Bump version to 2.3.0-rc4 2022-02-03 21:45:50 +00:00
jannfis
8139df8983 Merge pull request from GHSA-63qx-x74g-jcr7
Signed-off-by: jannfis <jann@mistrust.net>
2022-02-03 20:37:46 +01:00
pasha-codefresh
f364330de2 fix: fix example in project scoped repositories (#8357)
fix: fix example in project scoped repositories (#8357)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2022-02-03 09:45:43 -08:00
pasha-codefresh
4ec67d8b08 fix: applications page is crashing if nothing marked as favorites (#8356)
fix: applications page is crashing if nothing marked as favorites (#8356)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2022-02-03 09:45:39 -08:00
Leonardo Luz Almeida
3d3f81df4a chore: update actions/setup-go to v2 (#8349)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-02-03 09:45:34 -08:00
argo-bot
37f01f6f32 Bump version to 2.3.0-rc2 2022-02-02 22:37:02 +00:00
argo-bot
36eab6b82c Bump version to 2.3.0-rc2 2022-02-02 22:36:47 +00:00
Leonardo Luz Almeida
793acc147f chore: Use go install to add spdx-sbom-generator (#8346)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-02-02 13:51:14 -08:00
Leonardo Luz Almeida
b50609c0e6 chore: generate sbom for the released docker image (#8338)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-02-02 13:51:10 -08:00
Michael Crenshaw
5f48ce96c6 chore: use go install instead of deprecated go get (#8333)
* chore: use go install instead of deprecated go get

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

* docs: readme fixes

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2022-02-02 13:30:43 -08:00
Alexander Matyushentsev
c32460a2bc chore: automate bundling argocd addons during release process (#8336)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-02 13:28:40 -08:00
Ben Ye
7eb1aba99b fix: register controller workqueue metrics correctly (#8318)
Signed-off-by: Ben Ye <ben.ye@bytedance.com>
2022-02-01 12:02:55 -08:00
Alexander Matyushentsev
1a8139f4d6 fix: make sure release workflow publish image with "v" in front of version (#8335)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-01 10:27:40 -08:00
Leonardo Luz Almeida
02c03c3b26 chore: generate and upload sbom during release (#8332)
Signed-off-by: Leonardo Luz Almeida <leonardo_almeida@intuit.com>
2022-02-01 10:27:34 -08:00
Alexander Matyushentsev
cdb20d5060 docs: mention argocd notifications and applicationset changes in upgrade instructions (#8312)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-02-01 10:27:27 -08:00
argo-bot
7d7eed4932 Bump version to 2.3.0-rc1 2022-01-30 21:42:54 +00:00
argo-bot
af8c5eb07a Bump version to 2.3.0-rc1 2022-01-30 21:42:41 +00:00
Alexander Matyushentsev
1a476f7564 fix: argocd build fails on windows (#8319)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-01-30 13:02:01 -08:00
Saumeya Katyal
7f15389c72 feat: favourite ui feature (#8210)
* feat: favourite ui feature (#8210)

Signed-off-by: saumeya <saumeyakatyal@gmail.com>
2022-01-28 12:55:23 -08:00
Alexander Matyushentsev
1a3556e1cc fix: add missing steps in release workflow to setup docker buildx (#8311)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-01-28 12:04:34 -08:00
160 changed files with 13890 additions and 1830 deletions

View File

@@ -331,7 +331,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
k3s-version: [v1.21.2, v1.20.2, v1.19.2, v1.18.9, v1.17.11]
k3s-version: [v1.23.3, v1.22.6, v1.21.2]
needs:
- build-go
env:
@@ -376,10 +376,13 @@ jobs:
- name: Add /usr/local/bin to PATH
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
- name: Add ./dist to PATH
run: |
echo "$(pwd)/dist" >> $GITHUB_PATH
- name: Download Go dependencies
run: |
go mod download
go get github.com/mattn/goreman
go install github.com/mattn/goreman@latest
- name: Install all tools required for building & testing
run: |
make install-test-tools-local

View File

@@ -95,7 +95,7 @@ jobs:
echo "=========== BEGIN COMMIT MESSAGE ============="
git show ${SOURCE_TAG}
echo "============ END COMMIT MESSAGE =============="
# Quite dirty hack to get the release notes from the annotated tag
# into a temporary file.
RELEASE_NOTES=$(mktemp -p /tmp release-notes.XXXXXX)
@@ -142,7 +142,7 @@ jobs:
echo "RELEASE_NOTES=${RELEASE_NOTES}" >> $GITHUB_ENV
- name: Setup Golang
uses: actions/setup-go@v1
uses: actions/setup-go@v2
with:
go-version: ${{ env.GOLANG_VERSION }}
@@ -197,12 +197,14 @@ jobs:
if: ${{ env.DRY_RUN != 'true' }}
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- name: Build and push Docker image for release
run: |
set -ue
git clean -fd
mkdir -p dist/
docker buildx build --platform linux/amd64,linux/arm64 --push -t ${IMAGE_NAMESPACE}/argocd:${TARGET_VERSION} -t argoproj/argocd:${TARGET_VERSION} .
docker buildx build --platform linux/amd64,linux/arm64 --push -t ${IMAGE_NAMESPACE}/argocd:v${TARGET_VERSION} -t argoproj/argocd:v${TARGET_VERSION} .
make release-cli
chmod +x ./dist/argocd-linux-amd64
./dist/argocd-linux-amd64 version --client
@@ -287,6 +289,48 @@ jobs:
asset_content_type: application/octet-stream
if: ${{ env.DRY_RUN != 'true' }}
- name: Generate SBOM (spdx)
id: spdx-builder
env:
# defines the spdx/spdx-sbom-generator version to use.
SPDX_GEN_VERSION: v0.0.13
# defines the sigs.k8s.io/bom version to use.
SIGS_BOM_VERSION: v0.2.1
# comma delimited list of project relative folders to inspect for package
# managers (gomod, yarn, npm).
PROJECT_FOLDERS: ".,./ui"
# full qualified name of the docker image to be inspected
DOCKER_IMAGE: ${{env.IMAGE_NAMESPACE}}/argocd:v${{env.TARGET_VERSION}}
run: |
yarn install --cwd ./ui
go install github.com/spdx/spdx-sbom-generator/cmd/generator@$SPDX_GEN_VERSION
go install sigs.k8s.io/bom/cmd/bom@$SIGS_BOM_VERSION
# Generate SPDX for project dependencies analyzing package managers
for folder in $(echo $PROJECT_FOLDERS | sed "s/,/ /g")
do
generator -p $folder -o /tmp
done
# Generate SPDX for binaries analyzing the docker image
if [[ ! -z $DOCKER_IMAGE ]]; then
bom generate -o /tmp/bom-docker-image.spdx -i $DOCKER_IMAGE
fi
cd /tmp && tar -zcf sbom.tar.gz *.spdx
if: ${{ env.DRY_RUN != 'true' }}
- name: Upload SBOM to release assets
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: /tmp/sbom.tar.gz
asset_name: sbom.tar.gz
asset_content_type: application/octet-stream
if: ${{ env.DRY_RUN != 'true' }}
- name: Update homebrew formula
env:
HOMEBREW_TOKEN: ${{ secrets.RELEASE_HOMEBREW_TOKEN }}
@@ -301,3 +345,4 @@ jobs:
set -ue
git push --delete origin ${SOURCE_TAG}
if: ${{ always() }}

2
.gitpod.Dockerfile vendored
View File

@@ -9,7 +9,7 @@ RUN curl -L https://go.kubebuilder.io/dl/2.3.1/$(go env GOOS)/$(go env GOARCH) |
tar -xz -C /tmp/ && mv /tmp/kubebuilder_2.3.1_$(go env GOOS)_$(go env GOARCH) /usr/local/kubebuilder
RUN apt-get install redis-server -y
RUN go get github.com/mattn/goreman
RUN go install github.com/mattn/goreman@latest
USER gitpod

View File

@@ -2,5 +2,5 @@ image:
file: .gitpod.Dockerfile
tasks:
- init: make mod-download-local dep-ui-local && GO111MODULE=off go get github.com/mattn/goreman
- init: make mod-download-local dep-ui-local && GO111MODULE=off go install github.com/mattn/goreman@latest
command: make start-test-k8s

View File

@@ -1,5 +1,154 @@
# Changelog
## v2.3.0 (Unreleased)
### Argo CD ApplicationSet and Notifications are now part of Argo CD
Two popular [Argoproj Labs](https://github.com/argoproj-labs) projects [Argo CD ApplicationSet](https://github.com/argoproj/applicationset) and
[Argo CD Notifications](https://github.com/argoproj-labs/argocd-notifications) are now part of Argo CD! The default Argo CD installation manifests now
bundle both projects out of the box. Going forward you can expect more tightened integration of these projects into Argo CD.
### New sync and diff strategies
Users can now configure the Application resource to instruct Argo CD to consider the ignore difference setup during the sync process.
In order to do so, add the new sync option RespectIgnoreDifferences=true in the Application resource. Once the sync option is added,
Argo CD won't change ignored fields during the syncing process.
Configuring ignored fields is also easier now. Instead of listing fields one by one users can now leverage the
managedFields metadata to instruct Argo CD about trusted managers and automatically ignore any fields owned by them. A new diff customization
(managedFieldsManagers) is now available allowing users to specify managers the application should trust and to ignore all fields owned by those managers.
Read more about these changes at [New sync and diff strategies in ArgoCD](https://blog.argoproj.io/new-sync-and-diff-strategies-in-argocd-44195d3f8b8c) blog post.
### ARM Images
An officially supported ARM 64 image is now available. Enjoy running Argo CD on your Raspberry Pi! Additionally, the image size was reduced by nearly ~50%
and is only 200MB now. The ARM version of `argocd` CLI is also available and published as a Github release artifact.
### Compact Tree View And Click Application Navigation
The application details page now supports compact application resources tree visualization. Using the "Group Nodes" button, you can collapse the similar resources
into a single group node to remove the clutter and make it easier to understand the state of application resources. You still can get detailed information about the collapsed resources by clicking on the group node. The list of collapsed resources will be available in a sliding panel. Compact resource tree is still too big?
You can use the zoom in and zoom out feature to make it smaller - or even larger!
You no longer need to move back and forth between the application details page and the application list page. Instead you can navigate directly to the required application by clicking the search icon in the application details page title.
### Upgraded Config Management Tools
Both bundled Helm and Kustomize binaries have been upgraded to the latest versions. Kustomize has been upgraded from 4.2.0 to 4.4.1 and Helm has been upgraded from 3.7.1 to 3.8.0.
### Bug Fixes and Performance Enhancements
* Config management tools enhancements:
* The skipCrds flag and ability to ignore missing values files for Helm (#8012, #8003)
* Additional environment variables for Kustomize (#8096)
* Argo CD CLI follows the XDG Base directory standard (#7638)
* Redis is no longer used during SSO login (#8241)
### Features
- feat: Add app list and details page views to navigation history (#7776) (#7937)
- feat: Add skipCrds flag for helm charts (#8012)
- feat: Add visual indicator for newly created pods (#8006)
- feat: Added a new Helm option ignoreMissingValueFiles (#7767) (#8003)
- feat: Allow configuring system wide ignore differences for all resources (#8224)
- feat: Allow escaping dollar in Envsubst (#7961)
- feat: Allow external links on Application (#3487) (#8231)
- feat: Allow selecting application on detail page (#8176)
- feat: Bundle applicationset-controller with argocd (#8148)
- feat: Enable specifying root ca for oidc (#6712)
- feat: Expose ARGOCD_APP_NAME to the `kustomize build` command (#8096)
- feat: Ignore differences owned by trusted managers from managedFields (#7869)
- feat: New sync option to use ignore diff configs during sync (#8078)
- feat: Provide address flag for admin dashboard command (#8095)
- feat: Store "Group Nodes" button state in application details preferences (#8036)
- feat: Support specifying cluster by name in addition to API server URL in Cluster API (#8077)
- feat: Support XDG Base directory standard (#7638) (#7791)
- feat: Use encrypted cookie to store OAuth2 state nonce (instead of redis) (#8241)
- feat: Build images on PR and conditionally build arm64 image on push (#8108)
### Bug Fixes
- fix: Add "Restarting MinIO" status to MiniO Tenant health check (#8191)
- fix: Add all resources in list view (#7295)
- fix: Adding pagination to grouped nodes sliding panel#7837 (#7915)
- fix: Allow all resources to add external links (#7923)
- fix: Always call ValidateDestination (#7976)
- fix: Application exist panic when execute api call (#8188)
- fix: Application-icons-alignment (#8054)
- fix: Controller panics if resource manifest has incorrect annotation (#8022)
- fix: Correctly handle project field during partial cluster update (#7994)
- fix: Default value for retry validation #8055 (#8064)
- fix: Fix a possible crash when parsing RBAC (#8165)
- fix: Grouped node list missing resources on Compact resources view #8014 (#8018)
- fix: Issue with headless installation (#7958)
- fix: Issue with project scoped resources (#8048)
- fix: Kubernetes labels normalization for Prometheus (#7925)
- fix: Nested Refresh dropdown does not work on Application Details page #1524 (#7950)
- fix: Network line colors and menu icon alignment (#8059)
- fix: Opening app details shows UI error on some apps (#8016) (#8019)
- fix: Parse to correct uint32 type (#8177)
- fix: Prevent possible nil-pointer deref in normalizer (#8185)
- fix: Prevent possible out-of-bounds access when loading policies (#8186)
- fix: Provide a semantic version parsed version for KUBE_VERSION (#8250)
- fix: Refreshing label toast (#7979)
- fix: Resource details page crashes when resource is not deployed and hide managed fields is selected (#7971)
- fix: Retry disabled text (#8004)
- fix: Route health check stuck in 'Progressing' (#8170)
- fix: Sync window panel is crashed if resource name not contain letters (#8053)
- fix: Targetervision compatible without prefix refs/heads or refs/tags (#7939)
- fix: Trailing line in Filter Dropdown Menus #7821 (#8001)
- fix: Webhook URL matching edge cases (#7981)
- fix(ui): Use consistent case for diff modes (#7945)
- fix: Use gRPC timeout for sidecar CMPs (#8131) (#8236)
### Other
- chore: Bump go-jsonnet to v0.18.0 (#8011)
- chore: Escape proj in regex (#7985)
- chore: Exclude argocd-server rbac for core-install (#8234)
- chore: Log out the resource triggering reconciliation (#8192)
- chore: Migrate to use golang-jwt/jwt v4.2.0 (#8136)
- chore: Move resolveRevision from api-server to repo-server (#7966)
- chore: Update notifications version (#8267)
- chore: Update slack version (#8299)
- chore: Update to Redis 6.2.4 (#8157)
- chore: Upgrade awscli to 2.4.6 and remove python deps (#7947)
- chore: Upgrade base image to ubuntu:21.10 (#8230)
- chore: Upgrade dex to v2.30.2 (https://github.com/dexidp/dex/issues/2326) (#8237)
- chore: Upgrade gitops engine (#8288)
- chore: Upgrade golang to 1.17.6 (#8229)
- chore: Upgrade helm to most recent version (v3.7.2) (#8226)
- chore: Upgrade k8s client to v1.23 (#8213)
- chore: Upgrade kustomize to most recent version (v4.4.1) (#8227)
- refactor: Introduce 'byClusterName' secret index to speedup cluster server URL lookup (#8133)
- refactor: Move project filtering to server side (#8102)
## v2.2.3 (2022-01-18)
- fix: Application exist panic when execute api call (#8188)
- fix: Route health check stuck in 'Progressing' (#8170)
- refactor: Introduce 'byClusterName' secret index to speedup cluster server URL lookup (#8133)
- chore: Update to Redis 6.2.4 (#8157) (#8158)
## v2.2.2 (2021-12-31)
- fix: Issue with project scoped resources (#8048)
- fix: Escape proj in regex (#7985)
- fix: Default value for retry validation #8055 (#8064)
- fix: Sync window panel is crashed if resource name not contain letters (#8053)
- fix: Upgrade github.com/argoproj/gitops-engine to v0.5.2
- fix: Retry disabled text (#8004)
- fix: Opening app details shows UI error on some apps (#8016) (#8019)
- fix: Correctly handle project field during partial cluster update (#7994)
- fix: Cluster API does not support updating labels and annotations (#7901)
## v2.2.1 (2021-12-16)
- fix: Resource details page crashes when resource is not deployed and hide managed fields is selected (#7971)
- fix: Issue with headless installation (#7958)
- fix: Nil pointer (#7905)
## v2.2.0 (2021-12-14)
> [Upgrade instructions](./docs/operator-manual/upgrading/2.1-2.2.md)

View File

@@ -54,7 +54,6 @@ RUN groupadd -g 999 argocd && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
COPY hack/git-ask-pass.sh /usr/local/bin/git-ask-pass.sh
COPY hack/gpg-wrapper.sh /usr/local/bin/gpg-wrapper.sh
COPY hack/git-verify-wrapper.sh /usr/local/bin/git-verify-wrapper.sh
COPY --from=builder /usr/local/bin/ks /usr/local/bin/ks
@@ -92,7 +91,7 @@ FROM docker.io/library/node:12.18.4 as argocd-ui
WORKDIR /src
ADD ["ui/package.json", "ui/yarn.lock", "./"]
RUN yarn install --network-timeout 100000
RUN yarn install --network-timeout 200000
ADD ["ui/", "."]

View File

@@ -179,7 +179,7 @@ gogen: ensure-gopath
go generate ./util/argo/...
.PHONY: protogen
protogen: ensure-gopath
protogen: ensure-gopath mod-vendor-local
export GO111MODULE=off
./hack/generate-proto.sh
@@ -229,7 +229,7 @@ gen-resources-cli-local: clean-debug
CGO_ENABLED=0 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/${GEN_RESOURCES_CLI_NAME} ./hack/gen-resources/cmd
.PHONY: release-cli
release-cli: clean-debug
release-cli: clean-debug build-ui
make BIN_NAME=argocd-darwin-amd64 GOOS=darwin argocd-all
make BIN_NAME=argocd-darwin-arm64 GOOS=darwin GOARCH=arm64 argocd-all
make BIN_NAME=argocd-linux-amd64 GOOS=linux argocd-all
@@ -266,17 +266,20 @@ repo-server:
controller:
CGO_ENABLED=0 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/argocd-application-controller ./cmd
.PHONY: build-ui
build-ui:
docker build -t argocd-ui --target argocd-ui .
find ./ui/dist -type f -not -name gitkeep -delete
docker run -v ${CURRENT_DIR}/ui/dist/app:/tmp/app --rm -t argocd-ui sh -c 'cp -r ./dist/app/* /tmp/app/'
.PHONY: image
ifeq ($(DEV_IMAGE), true)
# The "dev" image builds the binaries from the users desktop environment (instead of in Docker)
# which speeds up builds. Dockerfile.dev needs to be copied into dist to perform the build, since
# the dist directory is under .dockerignore.
IMAGE_TAG="dev-$(shell git describe --always --dirty)"
image:
image: build-ui
docker build -t argocd-base --target argocd-base .
docker build -t argocd-ui --target argocd-ui .
find ./ui/dist -type f -not -name gitkeep -delete
docker run -v ${CURRENT_DIR}/ui/dist/app:/tmp/app --rm -t argocd-ui sh -c 'cp -r ./dist/app/* /tmp/app/'
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/argocd ./cmd
ln -sfn ${DIST_DIR}/argocd ${DIST_DIR}/argocd-server
ln -sfn ${DIST_DIR}/argocd ${DIST_DIR}/argocd-application-controller

View File

@@ -2744,6 +2744,16 @@
"type": "string",
"name": "revision",
"in": "query"
},
{
"type": "string",
"name": "appName",
"in": "query"
},
{
"type": "string",
"name": "appProject",
"in": "query"
}
],
"responses": {
@@ -4105,6 +4115,9 @@
"appName": {
"type": "string"
},
"appProject": {
"type": "string"
},
"source": {
"$ref": "#/definitions/v1alpha1ApplicationSource"
}

View File

@@ -0,0 +1,57 @@
package commands
import (
"context"
"fmt"
"os"
"strings"
"github.com/argoproj/argo-cd/v2/util/git"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"github.com/argoproj/argo-cd/v2/reposerver/askpass"
"github.com/argoproj/argo-cd/v2/util/errors"
grpc_util "github.com/argoproj/argo-cd/v2/util/grpc"
"github.com/argoproj/argo-cd/v2/util/io"
)
const (
// cliName is the name of the CLI
cliName = "argocd-git-ask-pass"
)
func NewCommand() *cobra.Command {
var command = cobra.Command{
Use: cliName,
Short: "Argo CD git credential helper",
DisableAutoGenTag: true,
Run: func(c *cobra.Command, args []string) {
if len(os.Args) != 2 {
errors.CheckError(fmt.Errorf("expected 1 argument, got %d", len(os.Args)-1))
}
nonce := os.Getenv(git.ASKPASS_NONCE_ENV)
if nonce == "" {
errors.CheckError(fmt.Errorf("%s is not set", git.ASKPASS_NONCE_ENV))
}
conn, err := grpc_util.BlockingDial(context.Background(), "unix", askpass.SocketPath, nil, grpc.WithInsecure())
errors.CheckError(err)
defer io.Close(conn)
client := askpass.NewAskPassServiceClient(conn)
creds, err := client.GetCredentials(context.Background(), &askpass.CredentialsRequest{Nonce: nonce})
errors.CheckError(err)
switch {
case strings.HasPrefix(os.Args[1], "Username"):
fmt.Println(creds.Username)
case strings.HasPrefix(os.Args[1], "Password"):
fmt.Println(creds.Password)
default:
errors.CheckError(fmt.Errorf("unknown credential type '%s'", os.Args[1]))
}
},
}
return &command
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/reposerver"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/reposerver/askpass"
reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache"
"github.com/argoproj/argo-cd/v2/reposerver/metrics"
"github.com/argoproj/argo-cd/v2/reposerver/repository"
@@ -61,6 +62,10 @@ func getPauseGenerationOnFailureForRequests() int {
return env.ParseNumFromEnv(common.EnvPauseGenerationRequests, defaultPauseGenerationOnFailureForRequests, 0, math.MaxInt32)
}
func getSubmoduleEnabled() bool {
return env.ParseBoolFromEnv(common.EnvGitSubmoduleEnabled, true)
}
func NewCommand() *cobra.Command {
var (
parallelismLimit int64
@@ -90,6 +95,7 @@ func NewCommand() *cobra.Command {
cache, err := cacheSrc()
errors.CheckError(err)
askPassServer := askpass.NewServer()
metricsServer := metrics.NewMetricsServer()
cacheutil.CollectMetrics(redisClient, metricsServer)
server, err := reposerver.NewServer(metricsServer, cache, tlsConfigCustomizer, repository.RepoServerInitConstants{
@@ -97,7 +103,8 @@ func NewCommand() *cobra.Command {
PauseGenerationAfterFailedGenerationAttempts: getPauseGenerationAfterFailedGenerationAttempts(),
PauseGenerationOnFailureForMinutes: getPauseGenerationOnFailureForMinutes(),
PauseGenerationOnFailureForRequests: getPauseGenerationOnFailureForRequests(),
})
SubmoduleEnabled: getSubmoduleEnabled(),
}, askPassServer)
errors.CheckError(err)
grpc := server.CreateGRPC()
@@ -128,6 +135,7 @@ func NewCommand() *cobra.Command {
})
http.Handle("/metrics", metricsServer.GetHandler())
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf(":%d", metricsPort), nil)) }()
go func() { errors.CheckError(askPassServer.Run(askpass.SocketPath)) }()
if gpg.IsGPGEnabled() {
log.Infof("Initializing GnuPG keyring at %s", common.GetGnuPGHomePath())

View File

@@ -283,6 +283,7 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
untilTime string
filter string
container string
previous bool
)
var command = &cobra.Command{
Use: "logs APPNAME",
@@ -312,6 +313,7 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
UntilTime: &untilTime,
Filter: &filter,
Container: container,
Previous: previous,
})
if err != nil {
log.Fatalf("failed to get pod logs: %v", err)
@@ -353,6 +355,7 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
command.Flags().StringVar(&untilTime, "until-time", "", "Show logs until this time")
command.Flags().StringVar(&filter, "filter", "", "Show logs contain this string")
command.Flags().StringVar(&container, "container", "", "Optional container name")
command.Flags().BoolVarP(&previous, "previous", "p", false, "Specify if the previously terminated container logs should be returned")
return command
}
@@ -746,9 +749,9 @@ func liveObjects(resources []*argoappv1.ResourceDiff) ([]*unstructured.Unstructu
return objs, nil
}
func getLocalObjects(app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, kustomizeOptions *argoappv1.KustomizeOptions,
func getLocalObjects(app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, apiVersions []string, kustomizeOptions *argoappv1.KustomizeOptions,
configManagementPlugins []*argoappv1.ConfigManagementPlugin, trackingMethod string) []*unstructured.Unstructured {
manifestStrings := getLocalObjectsString(app, local, localRepoRoot, appLabelKey, kubeVersion, kustomizeOptions, configManagementPlugins, trackingMethod)
manifestStrings := getLocalObjectsString(app, local, localRepoRoot, appLabelKey, kubeVersion, apiVersions, kustomizeOptions, configManagementPlugins, trackingMethod)
objs := make([]*unstructured.Unstructured, len(manifestStrings))
for i := range manifestStrings {
obj := unstructured.Unstructured{}
@@ -759,7 +762,7 @@ func getLocalObjects(app *argoappv1.Application, local, localRepoRoot, appLabelK
return objs
}
func getLocalObjectsString(app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, kustomizeOptions *argoappv1.KustomizeOptions,
func getLocalObjectsString(app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, apiVersions []string, kustomizeOptions *argoappv1.KustomizeOptions,
configManagementPlugins []*argoappv1.ConfigManagementPlugin, trackingMethod string) []string {
res, err := repository.GenerateManifests(context.Background(), local, localRepoRoot, app.Spec.Source.TargetRevision, &repoapiclient.ManifestRequest{
@@ -770,9 +773,10 @@ func getLocalObjectsString(app *argoappv1.Application, local, localRepoRoot, app
ApplicationSource: &app.Spec.Source,
KustomizeOptions: kustomizeOptions,
KubeVersion: kubeVersion,
ApiVersions: apiVersions,
Plugins: configManagementPlugins,
TrackingMethod: trackingMethod,
}, true)
}, true, &git.NoopCredsStore{})
errors.CheckError(err)
return res.Manifests
@@ -857,7 +861,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
defer argoio.Close(conn)
cluster, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server})
errors.CheckError(err)
localObjs := groupObjsByKey(getLocalObjects(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod), liveObjs, app.Spec.Destination.Namespace)
localObjs := groupObjsByKey(getLocalObjects(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.Info.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod), liveObjs, app.Spec.Destination.Namespace)
items = groupObjsForDiff(resources, localObjs, items, argoSettings, appName)
} else if revision != "" {
var unstructureds []*unstructured.Unstructured
@@ -1402,7 +1406,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
cluster, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server})
errors.CheckError(err)
argoio.Close(conn)
localObjsStrings = getLocalObjectsString(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod)
localObjsStrings = getLocalObjectsString(app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.Info.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod)
}
syncOptionsFactory := func() *applicationpkg.SyncOptions {

View File

@@ -10,6 +10,7 @@ import (
appcontroller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands"
cmpserver "github.com/argoproj/argo-cd/v2/cmd/argocd-cmp-server/commands"
dex "github.com/argoproj/argo-cd/v2/cmd/argocd-dex/commands"
gitaskpass "github.com/argoproj/argo-cd/v2/cmd/argocd-git-ask-pass/commands"
notification "github.com/argoproj/argo-cd/v2/cmd/argocd-notification/commands"
reposerver "github.com/argoproj/argo-cd/v2/cmd/argocd-repo-server/commands"
apiserver "github.com/argoproj/argo-cd/v2/cmd/argocd-server/commands"
@@ -42,6 +43,8 @@ func main() {
command = dex.NewCommand()
case "argocd-notifications":
command = notification.NewCommand()
case "argocd-git-ask-pass":
command = gitaskpass.NewCommand()
default:
command = cli.NewCommand()
}

View File

@@ -9,7 +9,6 @@ import (
"os/exec"
"path/filepath"
"strings"
"syscall"
"time"
"github.com/argoproj/pkg/rand"
@@ -68,7 +67,7 @@ func runCommand(ctx context.Context, command Command, path string, env []string)
cmd.Stderr = &stderr
// Make sure the command is killed immediately on timeout. https://stackoverflow.com/a/38133948/684776
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
cmd.SysProcAttr = newSysProcAttr(true)
start := time.Now()
err = cmd.Start()
@@ -80,7 +79,7 @@ func runCommand(ctx context.Context, command Command, path string, env []string)
<-ctx.Done()
// Kill by group ID to make sure child processes are killed. The - tells `kill` that it's a group ID.
// Since we didn't set Pgid in SysProcAttr, the group ID is the same as the process ID. https://pkg.go.dev/syscall#SysProcAttr
_ = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
_ = sysCallKill(-cmd.Process.Pid)
}()
err = cmd.Wait()

View File

@@ -0,0 +1,16 @@
//go:build !windows
// +build !windows
package plugin
import (
"syscall"
)
func newSysProcAttr(setpgid bool) *syscall.SysProcAttr {
return &syscall.SysProcAttr{Setpgid: setpgid}
}
func sysCallKill(pid int) error {
return syscall.Kill(pid, syscall.SIGKILL)
}

View File

@@ -0,0 +1,16 @@
//go:build windows
// +build windows
package plugin
import (
"syscall"
)
func newSysProcAttr(setpgid bool) *syscall.SysProcAttr {
return &syscall.SysProcAttr{}
}
func sysCallKill(pid int) error {
return nil
}

View File

@@ -36,9 +36,6 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
// make sure to register workqueue prometheus metrics
_ "k8s.io/component-base/metrics/prometheus/workqueue"
statecache "github.com/argoproj/argo-cd/v2/controller/cache"
"github.com/argoproj/argo-cd/v2/controller/metrics"
"github.com/argoproj/argo-cd/v2/pkg/apis/application"

View File

@@ -2,10 +2,12 @@ package cache
import (
"context"
"errors"
"fmt"
"math"
"reflect"
"sync"
"syscall"
"time"
clustercache "github.com/argoproj/gitops-engine/pkg/cache"
@@ -14,6 +16,7 @@ import (
log "github.com/sirupsen/logrus"
"golang.org/x/sync/semaphore"
v1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -37,6 +40,9 @@ const (
// EnvClusterCacheWatchResyncDuration is the env variable that holds cluster cache watch re-sync duration
EnvClusterCacheWatchResyncDuration = "ARGOCD_CLUSTER_CACHE_WATCH_RESYNC_DURATION"
// EnvClusterRetryTimeoutDuration is the env variable that holds cluster retry duration when sync error happens
EnvClusterSyncRetryTimeoutDuration = "ARGOCD_CLUSTER_SYNC_RETRY_TIMEOUT_DURATION"
// EnvClusterCacheListPageSize is the env variable to control size of the list page size when making K8s queries
EnvClusterCacheListPageSize = "ARGOCD_CLUSTER_CACHE_LIST_PAGE_SIZE"
@@ -44,6 +50,12 @@ const (
// This is used to limit the number of concurrent memory consuming operations on the
// k8s list queries results across all clusters to avoid memory spikes during cache initialization.
EnvClusterCacheListSemaphore = "ARGOCD_CLUSTER_CACHE_LIST_SEMAPHORE"
// EnvClusterCacheRetryLimit is the env variable to control the retry limit for listing resources during cluster cache sync
EnvClusterCacheAttemptLimit = "ARGOCD_CLUSTER_CACHE_ATTEMPT_LIMIT"
// EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync
EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF"
)
// GitOps engine cluster cache tuning options
@@ -56,19 +68,32 @@ var (
// for before relisting & restarting the watch
clusterCacheWatchResyncDuration = 10 * time.Minute
// clusterSyncRetryTimeoutDuration controls the sync retry duration when cluster sync error happens
clusterSyncRetryTimeoutDuration = 10 * time.Second
// The default limit of 50 is chosen based on experiments.
clusterCacheListSemaphoreSize int64 = 50
// clusterCacheListPageSize is the page size when performing K8s list requests.
// 500 is equal to kubectl's size
clusterCacheListPageSize int64 = 500
// clusterCacheRetryLimit sets a retry limit for failed requests during cluster cache sync
// If set to 1, retries are disabled.
clusterCacheAttemptLimit int32 = 1
// clusterCacheRetryUseBackoff specifies whether to use a backoff strategy on cluster cache sync, if retry is enabled
clusterCacheRetryUseBackoff bool = false
)
func init() {
clusterCacheResyncDuration = env.ParseDurationFromEnv(EnvClusterCacheResyncDuration, clusterCacheResyncDuration, 0, math.MaxInt64)
clusterCacheWatchResyncDuration = env.ParseDurationFromEnv(EnvClusterCacheWatchResyncDuration, clusterCacheWatchResyncDuration, 0, math.MaxInt64)
clusterSyncRetryTimeoutDuration = env.ParseDurationFromEnv(EnvClusterSyncRetryTimeoutDuration, clusterSyncRetryTimeoutDuration, 0, math.MaxInt64)
clusterCacheListPageSize = env.ParseInt64FromEnv(EnvClusterCacheListPageSize, clusterCacheListPageSize, 0, math.MaxInt64)
clusterCacheListSemaphoreSize = env.ParseInt64FromEnv(EnvClusterCacheListSemaphore, clusterCacheListSemaphoreSize, 0, math.MaxInt64)
clusterCacheAttemptLimit = int32(env.ParseInt64FromEnv(EnvClusterCacheAttemptLimit, 1, 1, math.MaxInt32))
clusterCacheRetryUseBackoff = env.ParseBoolFromEnv(EnvClusterCacheRetryUseBackoff, false)
}
type LiveStateCache interface {
@@ -278,6 +303,19 @@ func skipAppRequeuing(key kube.ResourceKey) bool {
return ignoredRefreshResources[key.Group+"/"+key.Kind]
}
// isRetryableError is a helper method to see whether an error
// returned from the dynamic client is potentially retryable.
func isRetryableError(err error) bool {
return kerrors.IsInternalError(err) ||
kerrors.IsInvalid(err) ||
kerrors.IsServerTimeout(err) ||
kerrors.IsServiceUnavailable(err) ||
kerrors.IsTimeout(err) ||
kerrors.IsUnexpectedObjectError(err) ||
kerrors.IsUnexpectedServerError(err) ||
errors.Is(err, syscall.ECONNRESET)
}
func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, error) {
c.lock.RLock()
clusterCache, ok := c.clusters[server]
@@ -310,6 +348,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
clustercache.SetListSemaphore(semaphore.NewWeighted(clusterCacheListSemaphoreSize)),
clustercache.SetListPageSize(clusterCacheListPageSize),
clustercache.SetWatchResyncTimeout(clusterCacheWatchResyncDuration),
clustercache.SetClusterSyncRetryTimeout(clusterSyncRetryTimeoutDuration),
clustercache.SetResyncTimeout(clusterCacheResyncDuration),
clustercache.SetSettings(cacheSettings.clusterSettings),
clustercache.SetNamespaces(cluster.Namespaces),
@@ -330,6 +369,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
return res, res.AppName != "" || gvk.Kind == kube.CustomResourceDefinitionKind
}),
clustercache.SetLogr(logutils.NewLogrusLogger(log.WithField("server", cluster.Server))),
clustercache.SetRetryOptions(clusterCacheAttemptLimit, clusterCacheRetryUseBackoff, isRetryableError),
}
clusterCache = clustercache.NewClusterCache(cluster.RESTConfig(), clusterCacheOpts...)

View File

@@ -64,6 +64,7 @@ func (c *clusterInfoUpdater) updateClusters() {
clusters, err := c.db.ListClusters(context.Background())
if err != nil {
log.Warnf("Failed to save clusters info: %v", err)
return
}
var clustersFiltered []appv1.Cluster
if c.clusterFilter == nil {

View File

@@ -159,6 +159,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil
mux := http.NewServeMux()
registry := NewAppRegistry(appLister, appFilter, appLabels)
registry.MustRegister(depth, adds, latency, workDuration, unfinished, longestRunningProcessor, retries)
mux.Handle(MetricsPath, promhttp.HandlerFor(prometheus.Gatherers{
// contains app controller specific metrics
registry,

View File

@@ -0,0 +1,101 @@
package metrics
import (
"github.com/prometheus/client_golang/prometheus"
"k8s.io/client-go/util/workqueue"
)
const (
WorkQueueSubsystem = "workqueue"
DepthKey = "depth"
AddsKey = "adds_total"
QueueLatencyKey = "queue_duration_seconds"
WorkDurationKey = "work_duration_seconds"
UnfinishedWorkKey = "unfinished_work_seconds"
LongestRunningProcessorKey = "longest_running_processor_seconds"
RetriesKey = "retries_total"
)
var (
depth = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Subsystem: WorkQueueSubsystem,
Name: DepthKey,
Help: "Current depth of workqueue",
}, []string{"name"})
adds = prometheus.NewCounterVec(prometheus.CounterOpts{
Subsystem: WorkQueueSubsystem,
Name: AddsKey,
Help: "Total number of adds handled by workqueue",
}, []string{"name"})
latency = prometheus.NewHistogramVec(prometheus.HistogramOpts{
Subsystem: WorkQueueSubsystem,
Name: QueueLatencyKey,
Help: "How long in seconds an item stays in workqueue before being requested",
Buckets: []float64{1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1, 5, 10, 15, 30, 60, 120, 180},
}, []string{"name"})
workDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
Subsystem: WorkQueueSubsystem,
Name: WorkDurationKey,
Help: "How long in seconds processing an item from workqueue takes.",
Buckets: []float64{1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1, 5, 10, 15, 30, 60, 120, 180},
}, []string{"name"})
unfinished = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Subsystem: WorkQueueSubsystem,
Name: UnfinishedWorkKey,
Help: "How many seconds of work has been done that " +
"is in progress and hasn't been observed by work_duration. Large " +
"values indicate stuck threads. One can deduce the number of stuck " +
"threads by observing the rate at which this increases.",
}, []string{"name"})
longestRunningProcessor = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Subsystem: WorkQueueSubsystem,
Name: LongestRunningProcessorKey,
Help: "How many seconds has the longest running " +
"processor for workqueue been running.",
}, []string{"name"})
retries = prometheus.NewCounterVec(prometheus.CounterOpts{
Subsystem: WorkQueueSubsystem,
Name: RetriesKey,
Help: "Total number of retries handled by workqueue",
}, []string{"name"})
)
func init() {
workqueue.SetProvider(workqueueMetricsProvider{})
}
type workqueueMetricsProvider struct{}
func (workqueueMetricsProvider) NewDepthMetric(name string) workqueue.GaugeMetric {
return depth.WithLabelValues(name)
}
func (workqueueMetricsProvider) NewAddsMetric(name string) workqueue.CounterMetric {
return adds.WithLabelValues(name)
}
func (workqueueMetricsProvider) NewLatencyMetric(name string) workqueue.HistogramMetric {
return latency.WithLabelValues(name)
}
func (workqueueMetricsProvider) NewWorkDurationMetric(name string) workqueue.HistogramMetric {
return workDuration.WithLabelValues(name)
}
func (workqueueMetricsProvider) NewUnfinishedWorkSecondsMetric(name string) workqueue.SettableGaugeMetric {
return unfinished.WithLabelValues(name)
}
func (workqueueMetricsProvider) NewLongestRunningProcessorSecondsMetric(name string) workqueue.SettableGaugeMetric {
return longestRunningProcessor.WithLabelValues(name)
}
func (workqueueMetricsProvider) NewRetriesMetric(name string) workqueue.CounterMetric {
return retries.WithLabelValues(name)
}

View File

@@ -140,6 +140,10 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1
if err != nil {
return nil, nil, err
}
enabledSourceTypes, err := m.settingsMgr.GetEnabledSourceTypes()
if err != nil {
return nil, nil, err
}
ts.AddCheckpoint("plugins_ms")
tools := make([]*appv1.ConfigManagementPlugin, len(plugins))
for i := range plugins {
@@ -155,6 +159,11 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1
if err != nil {
return nil, nil, err
}
helmOptions, err := m.settingsMgr.GetHelmSettings()
if err != nil {
return nil, nil, err
}
ts.AddCheckpoint("build_options_ms")
serverVersion, apiResources, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server)
if err != nil {
@@ -162,22 +171,24 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1
}
ts.AddCheckpoint("version_ms")
manifestInfo, err := repoClient.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: repo,
Repos: permittedHelmRepos,
Revision: revision,
NoCache: noCache,
NoRevisionCache: noRevisionCache,
AppLabelKey: appLabelKey,
AppName: app.Name,
Namespace: app.Spec.Destination.Namespace,
ApplicationSource: &source,
Plugins: tools,
KustomizeOptions: kustomizeOptions,
KubeVersion: serverVersion,
ApiVersions: argo.APIResourcesToStrings(apiResources, true),
VerifySignature: verifySignature,
HelmRepoCreds: permittedHelmCredentials,
TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)),
Repo: repo,
Repos: permittedHelmRepos,
Revision: revision,
NoCache: noCache,
NoRevisionCache: noRevisionCache,
AppLabelKey: appLabelKey,
AppName: app.Name,
Namespace: app.Spec.Destination.Namespace,
ApplicationSource: &source,
Plugins: tools,
KustomizeOptions: kustomizeOptions,
KubeVersion: serverVersion,
ApiVersions: argo.APIResourcesToStrings(apiResources, true),
VerifySignature: verifySignature,
HelmRepoCreds: permittedHelmCredentials,
TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)),
EnabledSourceTypes: enabledSourceTypes,
HelmOptions: helmOptions,
})
if err != nil {
return nil, nil, err

View File

@@ -199,6 +199,13 @@ data:
generate:
command: [kasane, show]
# A set of settings that allow enabling or disabling the config management tool.
# If unset, each defaults to "true".
kustomize.enabled: true
jsonnet.enabled: true
helm.enabled: true
ksonnet.enabled: true
# Build options/parameters to use with `kustomize build` (optional)
kustomize.buildOptions: --load_restrictor none
@@ -210,6 +217,10 @@ data:
kustomize.version.v3.5.1: /custom-tools/kustomize_3_5_1
kustomize.version.v3.5.4: /custom-tools/kustomize_3_5_4
# Comma delimited list of additional custom remote values file schemes (http are https are allowed by default).
# Change to empty value if you want to disable remote values files altogether.
helm.valuesFileSchemes: http, https
# The metadata.label key name where Argo CD injects the app name as a tracking label (optional).
# Tracking labels are used to determine which resources need to be deleted when pruning.
# If omitted, Argo CD injects the app name into the label: 'app.kubernetes.io/instance'

View File

@@ -40,6 +40,53 @@ the three components (argocd-server, argocd-repo-server, argocd-application-cont
API server can enforce the use of TLS 1.2 using the flag: `--tlsminversion 1.2`.
Communication with Redis is performed over plain HTTP by default. TLS can be setup with command line arguments.
## Git & Helm Repositories
Git and helm repositories are managed by a stand-alone service, called the repo-server. The
repo-server does not carry any Kubernetes privileges and does not store credentials to any services
(including git). The repo-server is responsible for cloning repositories which have been permitted
and trusted by Argo CD operators, and generating kubernetes manifests at a given path in the
repository. For performance and bandwidth efficiency, the repo-server maintains local clones of
these repositories so that subsequent commits to the repository are efficiently downloaded.
There are security considerations when configuring git repositories that Argo CD is permitted to
deploy from. In short, gaining unauthorized write access to a git repository trusted by Argo CD
will have serious security implications outlined below.
### Unauthorized Deployments
Since Argo CD deploys the Kubernetes resources defined in git, an attacker with access to a trusted
git repo would be able to affect the Kubernetes resources which are deployed. For example, an
attacker could update the deployment manifest deploy malicious container images to the environment,
or delete resources in git causing them to be pruned in the live environment.
### Tool command invocation
In addition to raw YAML, Argo CD natively supports two popular Kubernetes config management tools,
helm and kustomize. When rendering manifests, Argo CD executes these config management tools
(i.e. `helm template`, `kustomize build`) to generate the manifests. It is possible that an attacker
with write access to a trusted git repository may construct malicious helm charts or kustomizations
that attempt to read files out-of-tree. This includes adjacent git repos, as well as files on the
repo-server itself. Whether or not this is a risk to your organization depends on if the contents
in the git repos are sensitive in nature. By default, the repo-server itself does not contain
sensitive information, but might be configured with Config Management Plugins which do
(e.g. decryption keys). If such plugins are used, extreme care must be taken to ensure the
repository contents can be trusted at all times.
Optionally the built-in config management tools might be individually disabled.
If you know that your users will not need a certain config management tool, it's advisable
to disable that tool.
See [Tool Detection](../user-guide/tool_detection.md) for more information.
### Remote bases and helm chart dependencies
Argo CD's repository allow-list only restricts the initial repository which is cloned. However, both
kustomize and helm contain features to reference and follow *additional* repositories
(e.g. kustomize remote bases, helm chart dependencies), of which might not be in the repository
allow-list. Argo CD operators must understand that users with write access to trusted git
repositories could reference other remote git repositories containing Kubernetes resources not
easily searchable or auditable in the configured git repositories.
## Sensitive Information
### Secrets

View File

@@ -1,5 +1,14 @@
# v2.2 to 2.3
## Argo CD Notifications and ApplicationSet Are Bundled into Argo CD
The Argo CD Notifications and ApplicationSet are part of Argo CD now. You no longer need to install them separately.
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`.
## Configure Additional ArgoCD Binaries
We have removed non-Linux ArgoCD binaries (Darwin amd64 and Windows amd64) from the image ([#7668](https://github.com/argoproj/argo-cd/pull/7668)) and the associated download buttons in the help page in the UI.
@@ -24,4 +33,8 @@ data:
## Upgraded Kustomize Version
Note that bundled Kustomize version has been upgraded from 4.2.0 to 4.4.1.
Note that bundled Kustomize version has been upgraded from 4.2.0 to 4.4.1.
## Upgrade Helm Version
Note that bundled Helm version has been upgraded from 3.7.1 to 3.8.0.

View File

@@ -222,9 +222,10 @@ data:
- type: OIDC
id: oidc
name: OIDC
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
config:
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
```
### Requesting additional ID token claims
@@ -243,14 +244,15 @@ data:
- type: OIDC
id: oidc
name: OIDC
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
config:
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
```
!!! warning
@@ -272,15 +274,16 @@ data:
- type: OIDC
id: oidc
name: OIDC
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
getUserInfo: true
config:
issuer: https://example-OIDC-provider.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
getUserInfo: true
```
## Existing OIDC Provider

View File

@@ -1,4 +1,4 @@
mkdocs==1.1.2
mkdocs==1.2.3
mkdocs-material==7.1.7
markdown_include==0.6.0
pygments==2.7.4

View File

@@ -42,6 +42,6 @@ Likewise, changes made to the ApplicationSet `template` fields will automaticall
Within ApplicationSet there exist other more powerful generators in addition to the List generator, including the Cluster generator (which automatically uses Argo CD-defined clusters to template Applications), and the Git generator (which uses the files/directories of a Git repository to template applications).
To learn more about the ApplicationSet controller, check out [ApplicationSet documentation](https://argocd-applicationset.readthedocs.io/en/stable/) and [Getting Started](https://argocd-applicationset.readthedocs.io/en/stable/Geting-Started/) to install the ApplicationSet controller alongside Argo CD.
To learn more about the ApplicationSet controller, check out [ApplicationSet documentation](https://argocd-applicationset.readthedocs.io/en/stable/) and [Getting Started](https://argocd-applicationset.readthedocs.io/en/stable/Getting-Started/) to install the ApplicationSet controller alongside Argo CD.
**Note:** Starting `v2.3` of Argo CD, we don't need to install ApplicationSet Controller separately. It would be instead as part of Argo CD installation.

View File

@@ -17,6 +17,7 @@ argocd app logs APPNAME [flags]
--kind string Resource kind
--name string Resource name
--namespace string Resource namespace
-p, --previous Specify if the previously terminated container logs should be returned
--since-seconds int A relative time in seconds before the current time from which to show logs
--tail int The number of lines from the end of the logs to show
--until-time string Show logs until this time

View File

@@ -235,7 +235,7 @@ p, proj:my-project:admin, repositories, update, my-project/*, allow
This provides extra flexibility so that admins can have stricter rules. e.g.:
```
p, proj:my-project:admin, repositories, update, my-project/"https://github.my-company.com/*", allow
p, proj:my-project:admin, repositories, update, my-project/https://github.my-company.com/*, allow
```
Once the appropriate RBAC rules are in place, developers can create their own Git repositories and (assuming

View File

@@ -38,7 +38,7 @@ When Argo CD starts a sync, it orders the resources in the following precedence:
* The phase
* The wave they are in (lower values first)
* By kind (e.g. namespaces first)
* By kind (e.g. [namespaces first and then other Kubernetes resources, followed by custom resources](https://github.com/argoproj/gitops-engine/blob/bc9ce5764fa306f58cf59199a94f6c968c775a2d/pkg/sync/sync_tasks.go#L27-L66))
* By name
It then determines the number of the next wave to apply. This is the first number where any resource is out-of-sync or unhealthy.
@@ -48,3 +48,8 @@ It applies resources in that wave.
It repeats this process until all phases and waves are in-sync and healthy.
Because an application can have resources that are unhealthy in the first wave, it may be that the app can never get to healthy.
Note that there's currently a delay between each sync wave in order give other controllers a chance to react to the spec change
that we just applied. This also prevent Argo CD from assessing resource health too quickly (against the stale object), causing
hooks to fire prematurely. The current delay between each sync wave is 2 seconds and can be configured via environment
variable `ARGOCD_SYNC_WAVE_DELAY`.

View File

@@ -32,6 +32,12 @@ If not, then the tool is detected implicitly as follows:
Otherwise it is assumed to be a plain **directory** application.
## Disable built-in tools
Optionally built-in config management tools might be disabled. In order to disable the tool add one of the following
keys to the `argocd-cm` ConfigMap: `kustomize.enable`, `helm.enable`, `ksonnet.enable` or `jsonnet.enable`. Once the
tool is disabled Argo CD will assume the application target directory contains plain Kubernetes YAML manifests.
## References
* [reposerver/repository/repository.go/GetAppSourceType](https://github.com/argoproj/argo-cd/blob/master/reposerver/repository/repository.go#L286)

9
go.mod
View File

@@ -8,7 +8,7 @@ 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.5.1-0.20220126184517-b0c5e00ccfa5
github.com/argoproj/gitops-engine v0.6.0
github.com/argoproj/notifications-engine v0.3.1-0.20220127183449-91deed20b998
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0
github.com/bombsimon/logrusr/v2 v2.0.1
@@ -74,6 +74,7 @@ require (
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2
google.golang.org/grpc v1.40.0
google.golang.org/protobuf v1.27.1
gopkg.in/go-playground/webhooks.v5 v5.11.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.23.1
@@ -81,7 +82,6 @@ require (
k8s.io/apimachinery v0.23.1
k8s.io/client-go v0.23.1
k8s.io/code-generator v0.23.1
k8s.io/component-base v0.23.1
k8s.io/klog/v2 v2.30.0
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65
k8s.io/kubectl v0.23.1
@@ -112,7 +112,6 @@ require (
github.com/antonmedv/expr v1.8.9 // indirect
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -199,7 +198,6 @@ require (
gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect
gomodules.xyz/notify v0.1.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
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
@@ -208,8 +206,9 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/apiserver v0.23.1 // indirect
k8s.io/cli-runtime v0.23.1 // indirect
k8s.io/component-base v0.23.1 // indirect
k8s.io/component-helpers v0.23.1 // indirect
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
k8s.io/kube-aggregator v0.23.1 // indirect
k8s.io/kubernetes v1.23.1 // indirect
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect

8
go.sum
View File

@@ -125,8 +125,8 @@ 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.5.1-0.20220126184517-b0c5e00ccfa5 h1:oMRXPoMzlonjHMUE/dcdimFLiWUTieitanXlCIQf+a8=
github.com/argoproj/gitops-engine v0.5.1-0.20220126184517-b0c5e00ccfa5/go.mod h1:UJrK2YMBUbwJZue68mXhSDw+T52egdZWAU1F5cK34ko=
github.com/argoproj/gitops-engine v0.6.0 h1:Tnh6kUUVuBV0m3gueYIymAeErWl9XNN9O9JcOoNM0vU=
github.com/argoproj/gitops-engine v0.6.0/go.mod h1:pRgVpLW7pZqf7n3COJ7UcDepk4cI61LAcJd64Q3Jq/c=
github.com/argoproj/notifications-engine v0.3.1-0.20220127183449-91deed20b998 h1:V9RDg+IZeebnm3XjkfkbN07VM21Fu1Cy/RJNoHO++VM=
github.com/argoproj/notifications-engine v0.3.1-0.20220127183449-91deed20b998/go.mod h1:5mKv7zEgI3NO0L+fsuRSwBSY9EIXSuyIsDND8O8TTIw=
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc=
@@ -160,7 +160,6 @@ github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM=
@@ -1590,8 +1589,9 @@ k8s.io/controller-manager v0.23.1/go.mod h1:AFE4qIllvTh+nRwGr3SRSUt7F+xVSzXCeb0h
k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4=
k8s.io/csi-translation-lib v0.23.1/go.mod h1:0ZyB0cZBV4ZkqibwilEhKnxOne28rq5FDSjO+0MUVio=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI=
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=

View File

@@ -38,11 +38,21 @@ APIMACHINERY_PKGS=(
export GO111MODULE=on
[ -e ./v2 ] || ln -s . v2
# protoc_include is the include directory containing the .proto files distributed with protoc binary
if [ -d /dist/protoc-include ]; then
# containerized codegen build
protoc_include=/dist/protoc-include
else
# local codegen build
protoc_include=${PROJECT_ROOT}/dist/protoc-include
fi
go-to-protobuf \
--go-header-file=${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \
--packages=$(IFS=, ; echo "${PACKAGES[*]}") \
--apimachinery-packages=$(IFS=, ; echo "${APIMACHINERY_PKGS[*]}") \
--proto-import=./vendor
--proto-import=./vendor \
--proto-import=${protoc_include}
# Either protoc-gen-go, protoc-gen-gofast, or protoc-gen-gogofast can be used to build
# server/*/<service>.pb.go from .proto files. golang/protobuf and gogo/protobuf can be used
@@ -64,7 +74,7 @@ PROTO_FILES=$(find $PROJECT_ROOT \( -name "*.proto" -and -path '*/server/*' -or
for i in ${PROTO_FILES}; do
protoc \
-I${PROJECT_ROOT} \
-I/usr/local/include \
-I${protoc_include} \
-I./vendor \
-I$GOPATH/src \
-I${GOOGLE_PROTO_API_PATH} \

View File

@@ -0,0 +1 @@
8408c91e846c5b9ba15eb6b1a5a79fc22dd4d33ac6ea63388e5698d1b2320c8b helm-v3.8.0-linux-amd64.tar.gz

View File

@@ -0,0 +1 @@
23e08035dc0106fe4e0bd85800fd795b2b9ecd9f32187aa16c49b0a917105161 helm-v3.8.0-linux-arm64.tar.gz

View File

@@ -0,0 +1 @@
68901eb7ef5b55d7f2df3241ab0b8d97ee5192d3902c59e7adf461adc058e9f1 protoc_3.17.3_darwin_amd64.zip

View File

@@ -0,0 +1 @@
68901eb7ef5b55d7f2df3241ab0b8d97ee5192d3902c59e7adf461adc058e9f1 protoc_3.17.3_darwin_arm64.zip

View File

@@ -0,0 +1 @@
d4246a5136cf9cd1abc851c521a1ad6b8884df4feded8b9cbd5e2a2226d4b357 protoc_3.17.3_linux_amd64.zip

View File

@@ -0,0 +1 @@
ceb29d4890a31ba871829d22c2b7fa28f237d2b91ce4ea2a53e893d60a1cd502 protoc_3.17.3_linux_arm64.zip

View File

@@ -1 +0,0 @@
24ea6924faaf94d4a0c5850fdb278290a326eff9a68f36ee5809654faccd0e10 protoc_3.7.1_linux_amd64.zip

View File

@@ -1 +0,0 @@
020d82fd48c95b2da0daed250305390927237768523e22f8dd7fac534d8379b9 protoc_3.7.1_linux_arm64.zip

View File

@@ -1,4 +1,4 @@
#!/bin/bash
set -eux -o pipefail
KUSTOMIZE_VERSION=4.2.0 "$(dirname $0)/../install.sh" helm2-linux kustomize-linux protoc-linux
KUSTOMIZE_VERSION=4.2.0 "$(dirname $0)/../install.sh" helm2-linux kustomize-linux protoc

View File

@@ -1,27 +0,0 @@
#!/bin/bash
set -eux -o pipefail
. $(dirname $0)/../tool-versions.sh
case $ARCHITECTURE in
arm64|arm)
export TARGET_FILE=protoc_${protoc_version}_linux_${ARCHITECTURE}.zip
[ -e $DOWNLOADS/${TARGET_FILE} ] || curl -sLf --retry 3 -o $DOWNLOADS/${TARGET_FILE} https://github.com/protocolbuffers/protobuf/releases/download/v${protoc_version}/protoc-${protoc_version}-linux-aarch_64.zip
$(dirname $0)/compare-chksum.sh
mkdir -p /tmp/protoc-${protoc_version}
unzip $DOWNLOADS/${TARGET_FILE} -d /tmp/protoc-${protoc_version}
sudo install -m 0755 /tmp/protoc-${protoc_version}/bin/protoc /usr/local/bin/protoc
sudo cp -a /tmp/protoc-${protoc_version}/include/* /usr/local/include
protoc --version
;;
*)
export TARGET_FILE=protoc_${protoc_version}_linux_${ARCHITECTURE}.zip
[ -e $DOWNLOADS/${TARGET_FILE} ] || curl -sLf --retry 3 -o $DOWNLOADS/${TARGET_FILE} https://github.com/protocolbuffers/protobuf/releases/download/v${protoc_version}/protoc-${protoc_version}-linux-x86_64.zip
$(dirname $0)/compare-chksum.sh
mkdir -p /tmp/protoc-${protoc_version}
unzip $DOWNLOADS/${TARGET_FILE} -d /tmp/protoc-${protoc_version}
sudo install -m 0755 /tmp/protoc-${protoc_version}/bin/protoc /usr/local/bin/protoc
sudo cp -a /tmp/protoc-${protoc_version}/include/* /usr/local/include
protoc --version
;;
esac

View File

@@ -0,0 +1,42 @@
#!/bin/bash
set -eux -o pipefail
PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE})/../..; pwd)
DIST_PATH="${PROJECT_ROOT}/dist"
PATH="${DIST_PATH}:${PATH}"
. $(dirname $0)/../tool-versions.sh
OS=$(go env GOOS)
case $OS in
darwin)
# For macOS, the x86_64 binary is used even on Apple Silicon (it is run through rosetta), so
# we download and install the x86_64 version. See: https://github.com/protocolbuffers/protobuf/pull/8557
protoc_os=osx
protoc_arch=x86_64
;;
*)
protoc_os=linux
case $ARCHITECTURE in
arm64|arm)
protoc_arch=aarch_64
;;
*)
protoc_arch=x86_64
;;
esac
;;
esac
export TARGET_FILE=protoc_${protoc_version}_${OS}_${ARCHITECTURE}.zip
url=https://github.com/protocolbuffers/protobuf/releases/download/v${protoc_version}/protoc-${protoc_version}-${protoc_os}-${protoc_arch}.zip
[ -e $DOWNLOADS/${TARGET_FILE} ] || curl -sLf --retry 3 -o $DOWNLOADS/${TARGET_FILE} ${url}
$(dirname $0)/compare-chksum.sh
mkdir -p /tmp/protoc-${protoc_version}
unzip -o $DOWNLOADS/${TARGET_FILE} -d /tmp/protoc-${protoc_version}
mkdir -p ${DIST_PATH}/protoc-include
cp /tmp/protoc-${protoc_version}/bin/protoc ${DIST_PATH}/protoc
chmod +x ${DIST_PATH}/protoc
cp -a /tmp/protoc-${protoc_version}/include/* ${DIST_PATH}/protoc-include
chmod -R +rx ${DIST_PATH}/protoc-include
protoc --version

View File

@@ -1,7 +1,7 @@
#!/bin/bash
set -eux -o pipefail
which go-junit-report || go get github.com/jstemmer/go-junit-report
which go-junit-report || go install github.com/jstemmer/go-junit-report@latest
TEST_RESULTS=${TEST_RESULTS:-test-results}
TEST_FLAGS=

View File

@@ -10,9 +10,9 @@
###############################################################################
awscliv2_version=2.4.6
helm2_version=2.17.0
helm3_version=3.7.2
helm3_version=3.8.0
ksonnet_version=0.13.1
kubectl_version=1.17.8
kubectx_version=0.6.3
kustomize4_version=4.4.1
protoc_version=3.7.1
protoc_version=3.17.3

View File

@@ -27,23 +27,35 @@ if [ "$IMAGE_TAG" = "" ]; then
IMAGE_TAG=latest
fi
# bundle_with_addons bundles given kustomize base with either stable or latest version of addons
function bundle_with_addons() {
for addon in $(ls $SRCROOT/manifests/addons | grep -v README.md); do
ADDON_BASE="latest"
branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $branch = release-* ]]; then
ADDON_BASE="stable"
fi
rm -rf $SRCROOT/manifests/_tmp-bundle && mkdir -p $SRCROOT/manifests/_tmp-bundle
cat << EOF >> $SRCROOT/manifests/_tmp-bundle/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../$1
- ../addons/$addon/$ADDON_BASE
EOF
echo "${AUTOGENMSG}" > $2
$KUSTOMIZE build $SRCROOT/manifests/_tmp-bundle >> $2
done
}
$KUSTOMIZE version
cd ${SRCROOT}/manifests/base && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
cd ${SRCROOT}/manifests/ha/base && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
cd ${SRCROOT}/manifests/core-install && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/install.yaml"
$KUSTOMIZE build "${SRCROOT}/manifests/cluster-install" >> "${SRCROOT}/manifests/install.yaml"
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/namespace-install.yaml"
$KUSTOMIZE build "${SRCROOT}/manifests/namespace-install" >> "${SRCROOT}/manifests/namespace-install.yaml"
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/ha/install.yaml"
$KUSTOMIZE build "${SRCROOT}/manifests/ha/cluster-install" >> "${SRCROOT}/manifests/ha/install.yaml"
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/ha/namespace-install.yaml"
$KUSTOMIZE build "${SRCROOT}/manifests/ha/namespace-install" >> "${SRCROOT}/manifests/ha/namespace-install.yaml"
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/core-install.yaml"
$KUSTOMIZE build "${SRCROOT}/manifests/core-install" >> "${SRCROOT}/manifests/core-install.yaml"
bundle_with_addons "cluster-install" "${SRCROOT}/manifests/install.yaml"
bundle_with_addons "namespace-install" "${SRCROOT}/manifests/namespace-install.yaml"
bundle_with_addons "ha/cluster-install" "${SRCROOT}/manifests/ha/install.yaml"
bundle_with_addons "ha/namespace-install" "${SRCROOT}/manifests/ha/namespace-install.yaml"
bundle_with_addons "core-install" "${SRCROOT}/manifests/core-install.yaml"

1
manifests/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
_tmp-bundle

View File

@@ -0,0 +1,5 @@
# Addons
Directory contains Kustomize manifests of bundled Argo CD addons. Each directory must include the latest and stable versions
of the installation manifests in the directories named accordingly. The stable version should point to a particular git
tag and must be updated prior to each release.

View File

@@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://raw.githubusercontent.com/argoproj/applicationset/v0.4.0/manifests/install.yaml

View File

@@ -5,13 +5,12 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: latest
newTag: v2.3.0
resources:
- ./application-controller
- ./dex
- ./repo-server
- ./server
- ./applicationset
- ./config
- ./redis
- ./notification

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -11,13 +11,12 @@ patchesStrategicMerge:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: latest
newTag: v2.3.0
resources:
- ../../base/application-controller
- ../../base/dex
- ../../base/repo-server
- ../../base/server
- ../../base/applicationset
- ../../base/config
- ../../base/notification
- ./redis-ha

View File

@@ -2418,6 +2418,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2502,6 +2506,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2517,6 +2523,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2716,6 +2724,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2800,6 +2812,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2815,6 +2829,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3016,6 +3032,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3100,6 +3120,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3115,6 +3137,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3292,6 +3316,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3376,6 +3404,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3391,6 +3421,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3598,6 +3630,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3682,6 +3718,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3697,6 +3735,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3896,6 +3936,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3980,6 +4024,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3995,6 +4041,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4196,6 +4244,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4280,6 +4332,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4295,6 +4349,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4472,6 +4528,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4556,6 +4616,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4571,6 +4633,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4776,6 +4840,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4860,6 +4928,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4875,6 +4945,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5109,6 +5181,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5193,6 +5269,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5208,6 +5286,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5378,6 +5458,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5462,6 +5546,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5477,6 +5563,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5684,6 +5772,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5768,6 +5860,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5783,6 +5877,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5982,6 +6078,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6066,6 +6166,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6081,6 +6183,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6282,6 +6386,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6366,6 +6474,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6381,6 +6491,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6558,6 +6670,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6642,6 +6758,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6657,6 +6775,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6862,6 +6982,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6946,6 +7070,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6961,6 +7087,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -7195,6 +7323,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -7279,6 +7411,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -7294,6 +7428,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -7468,6 +7604,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -7552,6 +7692,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -7567,6 +7709,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -7769,6 +7913,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -7853,6 +8001,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -7868,6 +8018,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -8102,6 +8254,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -8186,6 +8342,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -8201,6 +8359,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -8376,6 +8536,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -8460,6 +8624,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -8475,6 +8641,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -10267,7 +10435,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd-applicationset:latest
image: quay.io/argoproj/argocd-applicationset:v0.4.0
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -10348,7 +10516,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -10381,7 +10549,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -10614,7 +10782,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -10663,7 +10831,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.3.0
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -10890,7 +11058,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -11086,7 +11254,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -112,6 +112,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -196,6 +200,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -211,6 +217,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -410,6 +418,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -494,6 +506,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -509,6 +523,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -710,6 +726,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -794,6 +814,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -809,6 +831,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -986,6 +1010,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1070,6 +1098,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1085,6 +1115,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -1292,6 +1324,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1376,6 +1412,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1391,6 +1429,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -1590,6 +1630,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1674,6 +1718,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1689,6 +1735,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -1890,6 +1938,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1974,6 +2026,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1989,6 +2043,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2166,6 +2222,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2250,6 +2310,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2265,6 +2327,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2470,6 +2534,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2554,6 +2622,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2569,6 +2639,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2803,6 +2875,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2887,6 +2963,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2902,6 +2980,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3072,6 +3152,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3156,6 +3240,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3171,6 +3257,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3378,6 +3466,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3462,6 +3554,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3477,6 +3571,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3676,6 +3772,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3760,6 +3860,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3775,6 +3877,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3976,6 +4080,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4060,6 +4168,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4075,6 +4185,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4252,6 +4364,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4336,6 +4452,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4351,6 +4469,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4556,6 +4676,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4640,6 +4764,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4655,6 +4781,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4889,6 +5017,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4973,6 +5105,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4988,6 +5122,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5162,6 +5298,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5246,6 +5386,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5261,6 +5403,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5463,6 +5607,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5547,6 +5695,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5562,6 +5712,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5796,6 +5948,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5880,6 +6036,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5895,6 +6053,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6070,6 +6230,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6154,6 +6318,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6169,6 +6335,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -7563,7 +7731,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd-applicationset:latest
image: quay.io/argoproj/argocd-applicationset:v0.4.0
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -7644,7 +7812,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -7677,7 +7845,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -7910,7 +8078,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -7959,7 +8127,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.3.0
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -8186,7 +8354,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -8382,7 +8550,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -2418,6 +2418,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2502,6 +2506,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2517,6 +2523,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2716,6 +2724,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2800,6 +2812,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2815,6 +2829,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3016,6 +3032,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3100,6 +3120,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3115,6 +3137,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3292,6 +3316,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3376,6 +3404,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3391,6 +3421,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3598,6 +3630,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3682,6 +3718,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3697,6 +3735,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3896,6 +3936,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3980,6 +4024,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3995,6 +4041,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4196,6 +4244,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4280,6 +4332,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4295,6 +4349,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4472,6 +4528,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4556,6 +4616,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4571,6 +4633,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4776,6 +4840,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4860,6 +4928,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4875,6 +4945,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5109,6 +5181,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5193,6 +5269,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5208,6 +5286,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5378,6 +5458,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5462,6 +5546,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5477,6 +5563,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5684,6 +5772,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5768,6 +5860,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5783,6 +5877,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5982,6 +6078,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6066,6 +6166,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6081,6 +6183,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6282,6 +6386,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6366,6 +6474,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6381,6 +6491,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6558,6 +6670,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6642,6 +6758,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6657,6 +6775,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6862,6 +6982,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6946,6 +7070,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6961,6 +7087,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -7195,6 +7323,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -7279,6 +7411,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -7294,6 +7428,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -7468,6 +7604,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -7552,6 +7692,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -7567,6 +7709,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -7769,6 +7913,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -7853,6 +8001,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -7868,6 +8018,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -8102,6 +8254,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -8186,6 +8342,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -8201,6 +8359,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -8376,6 +8536,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -8460,6 +8624,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -8475,6 +8641,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -9637,7 +9805,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd-applicationset:latest
image: quay.io/argoproj/argocd-applicationset:v0.4.0
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -9718,7 +9886,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -9751,7 +9919,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -9948,7 +10116,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -9997,7 +10165,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.3.0
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -10220,7 +10388,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -10410,7 +10578,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -112,6 +112,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -196,6 +200,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -211,6 +217,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -410,6 +418,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -494,6 +506,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -509,6 +523,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -710,6 +726,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -794,6 +814,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -809,6 +831,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -986,6 +1010,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1070,6 +1098,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1085,6 +1115,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -1292,6 +1324,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1376,6 +1412,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1391,6 +1429,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -1590,6 +1630,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1674,6 +1718,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1689,6 +1735,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -1890,6 +1938,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -1974,6 +2026,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -1989,6 +2043,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2166,6 +2222,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2250,6 +2310,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2265,6 +2327,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2470,6 +2534,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2554,6 +2622,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2569,6 +2639,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -2803,6 +2875,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -2887,6 +2963,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -2902,6 +2980,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3072,6 +3152,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3156,6 +3240,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3171,6 +3257,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3378,6 +3466,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3462,6 +3554,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3477,6 +3571,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3676,6 +3772,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -3760,6 +3860,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -3775,6 +3877,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -3976,6 +4080,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4060,6 +4168,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4075,6 +4185,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4252,6 +4364,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4336,6 +4452,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4351,6 +4469,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4556,6 +4676,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4640,6 +4764,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4655,6 +4781,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -4889,6 +5017,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -4973,6 +5105,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -4988,6 +5122,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5162,6 +5298,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5246,6 +5386,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5261,6 +5403,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5463,6 +5607,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5547,6 +5695,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5562,6 +5712,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -5796,6 +5948,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -5880,6 +6036,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -5895,6 +6053,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6070,6 +6230,10 @@ spec:
type: array
kind:
type: string
managedFieldsManagers:
items:
type: string
type: array
name:
type: string
namespace:
@@ -6154,6 +6318,8 @@ spec:
type: string
type: object
type: array
ignoreMissingValueFiles:
type: boolean
parameters:
items:
properties:
@@ -6169,6 +6335,8 @@ spec:
type: boolean
releaseName:
type: string
skipCrds:
type: boolean
valueFiles:
items:
type: string
@@ -6933,7 +7101,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/argoproj/argocd-applicationset:latest
image: quay.io/argoproj/argocd-applicationset:v0.4.0
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -7014,7 +7182,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -7047,7 +7215,7 @@ spec:
containers:
- command:
- argocd-notifications
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -7244,7 +7412,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -7293,7 +7461,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.3.0
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -7516,7 +7684,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -7706,7 +7874,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.3.0
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -39,6 +39,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type RepoAppsQuery struct {
Repo string `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"`
Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"`
AppName string `protobuf:"bytes,3,opt,name=appName,proto3" json:"appName,omitempty"`
AppProject string `protobuf:"bytes,4,opt,name=appProject,proto3" json:"appProject,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -91,6 +93,20 @@ func (m *RepoAppsQuery) GetRevision() string {
return ""
}
func (m *RepoAppsQuery) GetAppName() string {
if m != nil {
return m.AppName
}
return ""
}
func (m *RepoAppsQuery) GetAppProject() string {
if m != nil {
return m.AppProject
}
return ""
}
// AppInfo contains application type and app file path
type AppInfo struct {
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
@@ -151,6 +167,7 @@ func (m *AppInfo) GetPath() string {
type RepoAppDetailsQuery struct {
Source *v1alpha1.ApplicationSource `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"`
AppName string `protobuf:"bytes,2,opt,name=appName,proto3" json:"appName,omitempty"`
AppProject string `protobuf:"bytes,3,opt,name=appProject,proto3" json:"appProject,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -203,6 +220,13 @@ func (m *RepoAppDetailsQuery) GetAppName() string {
return ""
}
func (m *RepoAppDetailsQuery) GetAppProject() string {
if m != nil {
return m.AppProject
}
return ""
}
// RepoAppsResponse contains applications of specified repository
type RepoAppsResponse struct {
Items []*AppInfo `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
@@ -663,77 +687,78 @@ func init() {
}
var fileDescriptor_8d38260443475705 = []byte{
// 1105 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x5f, 0x6f, 0x1b, 0x45,
0x10, 0xd7, 0xe5, 0x8f, 0x93, 0x6c, 0xfe, 0xd4, 0xd9, 0x84, 0x72, 0xb8, 0x69, 0x1a, 0x6d, 0x4b,
0x15, 0xa2, 0x72, 0xd7, 0x18, 0x21, 0xaa, 0x22, 0x40, 0x69, 0x12, 0xb5, 0x11, 0x11, 0x81, 0xab,
0xc2, 0x03, 0x02, 0xa1, 0xcd, 0x79, 0x62, 0x1f, 0x39, 0xdf, 0x6e, 0x77, 0xd7, 0x06, 0xab, 0xea,
0x0b, 0x4f, 0x48, 0xf0, 0x82, 0x10, 0x52, 0xdf, 0x78, 0x41, 0xe2, 0x81, 0xcf, 0xc0, 0x3b, 0x8f,
0x48, 0x7c, 0x01, 0x14, 0xf1, 0x39, 0x10, 0xda, 0xdd, 0xf3, 0xdd, 0x39, 0xb1, 0x9d, 0x54, 0x84,
0xbc, 0xed, 0xfc, 0x66, 0x76, 0xe6, 0x37, 0xe3, 0x99, 0x59, 0x1f, 0x22, 0x12, 0x44, 0x1b, 0x84,
0x2f, 0x80, 0x33, 0x19, 0x29, 0x26, 0x3a, 0x85, 0xa3, 0xc7, 0x05, 0x53, 0x0c, 0xa3, 0x1c, 0xa9,
0x2c, 0xd6, 0x59, 0x9d, 0x19, 0xd8, 0xd7, 0x27, 0x6b, 0x51, 0x59, 0xaa, 0x33, 0x56, 0x8f, 0xc1,
0xa7, 0x3c, 0xf2, 0x69, 0x92, 0x30, 0x45, 0x55, 0xc4, 0x12, 0x99, 0x6a, 0xc9, 0xd1, 0x3d, 0xe9,
0x45, 0xcc, 0x68, 0x43, 0x26, 0xc0, 0x6f, 0xaf, 0xfb, 0x75, 0x48, 0x40, 0x50, 0x05, 0xb5, 0xd4,
0x66, 0xb7, 0x1e, 0xa9, 0x46, 0xeb, 0xc0, 0x0b, 0x59, 0xd3, 0xa7, 0xc2, 0x84, 0xf8, 0xc2, 0x1c,
0x5e, 0x0f, 0x6b, 0x7e, 0xbb, 0xea, 0xf3, 0xa3, 0xba, 0xbe, 0x2f, 0x7d, 0xca, 0x79, 0x1c, 0x85,
0xc6, 0xbf, 0xdf, 0x5e, 0xa7, 0x31, 0x6f, 0xd0, 0xd3, 0xde, 0xb6, 0xcf, 0xf0, 0x66, 0x12, 0x3a,
0x33, 0x71, 0xf2, 0x1e, 0x9a, 0x0d, 0x80, 0xb3, 0x0d, 0xce, 0xe5, 0x47, 0x2d, 0x10, 0x1d, 0x8c,
0xd1, 0x98, 0x36, 0x72, 0x9d, 0x15, 0x67, 0x75, 0x2a, 0x30, 0x67, 0x5c, 0x41, 0x93, 0x02, 0xda,
0x91, 0x8c, 0x58, 0xe2, 0x8e, 0x18, 0x3c, 0x93, 0xc9, 0x3a, 0x9a, 0xd8, 0xe0, 0x7c, 0x27, 0x39,
0x64, 0xfa, 0xaa, 0xea, 0x70, 0xe8, 0x5e, 0xd5, 0x67, 0x8d, 0x71, 0xaa, 0x1a, 0xe9, 0x35, 0x73,
0x26, 0xcf, 0x1d, 0xb4, 0x90, 0x06, 0xdd, 0x02, 0x45, 0xa3, 0x38, 0x0d, 0x5d, 0x47, 0x25, 0xc9,
0x5a, 0x22, 0xb4, 0x1e, 0xa6, 0xab, 0x7b, 0x5e, 0x9e, 0xa3, 0xd7, 0xcd, 0xd1, 0x1c, 0x3e, 0x0f,
0x6b, 0x5e, 0xbb, 0xea, 0xf1, 0xa3, 0xba, 0xa7, 0x2b, 0xe6, 0x15, 0x2a, 0xe6, 0x75, 0x2b, 0xe6,
0x6d, 0xe4, 0xe0, 0x63, 0xe3, 0x36, 0x48, 0xdd, 0x63, 0x17, 0x4d, 0x50, 0xce, 0x3f, 0xa0, 0x4d,
0x48, 0x79, 0x75, 0x45, 0xf2, 0x0e, 0x2a, 0x77, 0xcb, 0x11, 0x80, 0xe4, 0x2c, 0x91, 0x80, 0x5f,
0x43, 0xe3, 0x91, 0x82, 0xa6, 0x74, 0x9d, 0x95, 0xd1, 0xd5, 0xe9, 0xea, 0x82, 0x57, 0x28, 0x62,
0x9a, 0x7a, 0x60, 0x2d, 0xc8, 0x26, 0x9a, 0xd2, 0xd7, 0x07, 0x57, 0x92, 0xa0, 0x99, 0x43, 0xa6,
0xa9, 0xc0, 0xa1, 0x00, 0x69, 0xcb, 0x32, 0x19, 0xf4, 0x60, 0xe4, 0xb7, 0x31, 0x74, 0xc5, 0x90,
0x08, 0x43, 0x90, 0xc3, 0x7f, 0x95, 0x96, 0x04, 0x91, 0xe4, 0x69, 0x64, 0xb2, 0xd6, 0x71, 0x2a,
0xe5, 0x97, 0x4c, 0xd4, 0xdc, 0x51, 0xab, 0xeb, 0xca, 0xf8, 0x16, 0x9a, 0x95, 0xb2, 0xf1, 0xa1,
0x88, 0xda, 0x54, 0xc1, 0xfb, 0xd0, 0x71, 0xc7, 0x8c, 0x41, 0x2f, 0xa8, 0x3d, 0x44, 0x89, 0x84,
0xb0, 0x25, 0xc0, 0x1d, 0x37, 0x2c, 0x33, 0x19, 0xdf, 0x41, 0xf3, 0x2a, 0x96, 0x9b, 0x71, 0x04,
0x89, 0xda, 0x04, 0xa1, 0xb6, 0xa8, 0xa2, 0x6e, 0xc9, 0x78, 0x39, 0xad, 0xc0, 0x6b, 0xa8, 0xdc,
0x03, 0xea, 0x90, 0x13, 0xc6, 0xf8, 0x14, 0x9e, 0xb5, 0xd0, 0x54, 0x6f, 0x0b, 0x99, 0x1c, 0x91,
0xc5, 0x4c, 0x7e, 0x4b, 0x68, 0x0a, 0x12, 0x7a, 0x10, 0xc3, 0x5e, 0x18, 0xb9, 0xd3, 0x86, 0x5e,
0x0e, 0xe0, 0xbb, 0x68, 0xc1, 0x76, 0xce, 0x06, 0xe7, 0x85, 0x3c, 0x67, 0x8c, 0x83, 0x7e, 0x2a,
0xbc, 0x82, 0xa6, 0x33, 0x78, 0x67, 0xcb, 0x9d, 0x5d, 0x71, 0x56, 0x47, 0x83, 0x22, 0x84, 0xef,
0xa1, 0x97, 0x73, 0x31, 0x91, 0x8a, 0xc6, 0xb1, 0x69, 0xad, 0x9d, 0x2d, 0x77, 0xce, 0x58, 0x0f,
0x52, 0xe3, 0x77, 0x51, 0x25, 0x53, 0x6d, 0x27, 0x0a, 0x04, 0x17, 0x91, 0x84, 0x07, 0x54, 0xc2,
0xbe, 0x88, 0xdd, 0x2b, 0x86, 0xd4, 0x10, 0x0b, 0xbc, 0x88, 0xc6, 0xb9, 0x60, 0x5f, 0x75, 0xdc,
0xb2, 0x31, 0xb5, 0x82, 0xee, 0x61, 0x3d, 0x0e, 0x10, 0x2a, 0x77, 0xde, 0xf6, 0x70, 0x2a, 0x92,
0x39, 0x34, 0xa3, 0xdb, 0xa7, 0xdb, 0xbf, 0xe4, 0x17, 0x07, 0xcd, 0x6b, 0x60, 0x53, 0x00, 0x55,
0x10, 0xc0, 0x93, 0x16, 0x48, 0x85, 0x3f, 0x2d, 0x74, 0xd4, 0x74, 0xf5, 0xd1, 0x7f, 0x1b, 0xb5,
0x20, 0x9b, 0x88, 0xb4, 0x37, 0xaf, 0xa2, 0x52, 0x8b, 0x4b, 0x10, 0x2a, 0xed, 0xf0, 0x54, 0xd2,
0xbf, 0x5b, 0x28, 0xa0, 0x26, 0xf7, 0x92, 0xb8, 0x63, 0x1a, 0x73, 0x32, 0xc8, 0x01, 0xf2, 0xc4,
0x12, 0xdd, 0xe7, 0xb5, 0xcb, 0x22, 0x5a, 0xfd, 0x67, 0xce, 0xc6, 0xb4, 0xe0, 0x63, 0x10, 0xed,
0x28, 0x04, 0xfc, 0x9d, 0x83, 0xc6, 0x76, 0x23, 0xa9, 0xf0, 0x4b, 0xc5, 0x61, 0xcf, 0x46, 0xbb,
0xb2, 0x7b, 0x51, 0x2c, 0x74, 0x10, 0x72, 0xe3, 0xeb, 0x3f, 0xff, 0xfe, 0x61, 0xe4, 0x2a, 0x5e,
0x34, 0xcf, 0x47, 0x7b, 0x3d, 0xdf, 0xd2, 0x11, 0xc8, 0x6f, 0x46, 0x1c, 0xfc, 0xad, 0x83, 0x46,
0x1f, 0xc2, 0x40, 0x36, 0x17, 0x56, 0x13, 0x72, 0xd3, 0x30, 0xb9, 0x8e, 0xaf, 0xf5, 0x63, 0xe2,
0x3f, 0xd5, 0xd2, 0x33, 0xfc, 0xa3, 0x83, 0xca, 0x9a, 0x77, 0x50, 0xd0, 0x5d, 0x4e, 0xa1, 0x96,
0x86, 0x15, 0x0a, 0x7f, 0x86, 0x26, 0x2d, 0xad, 0xc3, 0x81, 0x74, 0xca, 0xbd, 0xf0, 0xa1, 0x24,
0xab, 0xc6, 0x25, 0xc1, 0x2b, 0x43, 0x32, 0xf6, 0x85, 0x76, 0xd9, 0xb4, 0xee, 0xf5, 0xd3, 0x80,
0x5f, 0x39, 0xe9, 0x3e, 0x7b, 0x3f, 0x2b, 0x4b, 0xfd, 0x54, 0xd9, 0x2c, 0x9e, 0x2b, 0x1c, 0xd5,
0x21, 0xbe, 0x77, 0xd0, 0xec, 0x43, 0x50, 0xf9, 0x1b, 0x89, 0x6f, 0xf4, 0xf1, 0x5c, 0x7c, 0x3f,
0x2b, 0x64, 0xb0, 0x41, 0x46, 0xe0, 0x6d, 0x43, 0xe0, 0x4d, 0x72, 0xb7, 0x3f, 0x01, 0xfb, 0x40,
0x1a, 0x3f, 0xfb, 0xc1, 0xae, 0xa1, 0x52, 0xb3, 0x1e, 0xee, 0x3b, 0x6b, 0xb8, 0x6d, 0x28, 0x3d,
0x82, 0xb8, 0xb9, 0xd9, 0xa0, 0x42, 0x0d, 0x2c, 0xf3, 0x72, 0x11, 0xce, 0xcd, 0x33, 0x12, 0x9e,
0x21, 0xb1, 0x8a, 0x6f, 0x0f, 0xab, 0x42, 0x03, 0xe2, 0x66, 0x68, 0xc3, 0x3c, 0x77, 0x50, 0xc9,
0x6e, 0x2f, 0x7c, 0xfd, 0x64, 0xc4, 0x9e, 0xad, 0x76, 0x81, 0xa3, 0xf0, 0xaa, 0xe1, 0xb8, 0x44,
0xfa, 0xf6, 0xda, 0x7d, 0xb3, 0x3c, 0xf4, 0x68, 0xfe, 0xe4, 0xa0, 0x72, 0x97, 0x42, 0xf7, 0xee,
0xe5, 0x91, 0x24, 0x67, 0x93, 0xc4, 0x3f, 0x3b, 0xa8, 0x64, 0x37, 0xea, 0x69, 0x5e, 0x3d, 0x9b,
0xf6, 0x02, 0x79, 0xad, 0xdb, 0x1f, 0xb8, 0x32, 0xa4, 0xcd, 0x0d, 0x95, 0x67, 0x79, 0x21, 0x7f,
0x75, 0x50, 0xb9, 0x4b, 0x67, 0x70, 0x21, 0xff, 0x2f, 0xc2, 0xde, 0x8b, 0x11, 0xc6, 0x14, 0x95,
0xb6, 0x20, 0x06, 0x05, 0x83, 0x46, 0xc0, 0x3d, 0x09, 0x67, 0xcd, 0x7f, 0xdb, 0xee, 0xd8, 0xb5,
0x61, 0x3b, 0x56, 0x17, 0xa4, 0x81, 0xca, 0x36, 0x44, 0xa1, 0x1e, 0x2f, 0x1c, 0xec, 0xe6, 0x39,
0x82, 0xe1, 0xa7, 0x68, 0xee, 0x63, 0x1a, 0x47, 0xba, 0xb2, 0xf6, 0x3f, 0x27, 0xbe, 0x76, 0x6a,
0x93, 0xe4, 0xff, 0x45, 0x87, 0x44, 0xab, 0x9a, 0x68, 0x77, 0xc8, 0xad, 0x61, 0x73, 0xdd, 0x4e,
0x43, 0xd9, 0x4a, 0x3e, 0xd8, 0xfe, 0xfd, 0x78, 0xd9, 0xf9, 0xe3, 0x78, 0xd9, 0xf9, 0xeb, 0x78,
0xd9, 0xf9, 0xe4, 0xad, 0xf3, 0x7d, 0x23, 0x85, 0xe6, 0x4f, 0x63, 0xe1, 0x6b, 0xe6, 0xa0, 0x64,
0x3e, 0x67, 0xde, 0xf8, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0x35, 0xe9, 0x0a, 0xed, 0x0d, 0x00,
0x00,
// 1129 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4d, 0x6f, 0x1c, 0x45,
0x13, 0xd6, 0xf8, 0x63, 0x6d, 0xb7, 0x3f, 0xb2, 0x6e, 0xfb, 0xcd, 0x3b, 0x6c, 0x1c, 0xc7, 0x9a,
0x84, 0xc8, 0x58, 0x61, 0x26, 0x5e, 0x84, 0x88, 0x82, 0x40, 0x72, 0x6c, 0x2b, 0xb1, 0xb0, 0x70,
0x98, 0xc8, 0x1c, 0x10, 0x08, 0xb5, 0x67, 0x6b, 0x77, 0x27, 0x9e, 0x9d, 0xee, 0x74, 0xf7, 0x0e,
0xac, 0xa2, 0x5c, 0x38, 0x21, 0xc1, 0x05, 0x21, 0x24, 0x6e, 0x5c, 0x90, 0x38, 0xf0, 0x07, 0xb8,
0x70, 0xe7, 0x88, 0xc4, 0x1f, 0x40, 0x16, 0xbf, 0x03, 0xa1, 0xee, 0x9e, 0x9d, 0x99, 0xf5, 0x7e,
0xd8, 0x11, 0xc6, 0xb7, 0xae, 0xa7, 0x6a, 0xab, 0x9e, 0x7a, 0xba, 0xba, 0x7b, 0x07, 0x39, 0x02,
0x78, 0x02, 0xdc, 0xe3, 0xc0, 0xa8, 0x08, 0x25, 0xe5, 0x9d, 0xc2, 0xd2, 0x65, 0x9c, 0x4a, 0x8a,
0x51, 0x8e, 0x54, 0x96, 0x1b, 0xb4, 0x41, 0x35, 0xec, 0xa9, 0x95, 0x89, 0xa8, 0xac, 0x34, 0x28,
0x6d, 0x44, 0xe0, 0x11, 0x16, 0x7a, 0x24, 0x8e, 0xa9, 0x24, 0x32, 0xa4, 0xb1, 0x48, 0xbd, 0xce,
0xf1, 0x3d, 0xe1, 0x86, 0x54, 0x7b, 0x03, 0xca, 0xc1, 0x4b, 0x36, 0xbd, 0x06, 0xc4, 0xc0, 0x89,
0x84, 0x5a, 0x1a, 0xb3, 0xdf, 0x08, 0x65, 0xb3, 0x7d, 0xe4, 0x06, 0xb4, 0xe5, 0x11, 0xae, 0x4b,
0x3c, 0xd5, 0x8b, 0xd7, 0x83, 0x9a, 0x97, 0x54, 0x3d, 0x76, 0xdc, 0x50, 0xbf, 0x17, 0x1e, 0x61,
0x2c, 0x0a, 0x03, 0x9d, 0xdf, 0x4b, 0x36, 0x49, 0xc4, 0x9a, 0xa4, 0x3f, 0xdb, 0xee, 0x19, 0xd9,
0x74, 0x43, 0x67, 0x36, 0xee, 0x74, 0xd0, 0xbc, 0x0f, 0x8c, 0x6e, 0x31, 0x26, 0x3e, 0x68, 0x03,
0xef, 0x60, 0x8c, 0x26, 0x54, 0x90, 0x6d, 0xad, 0x59, 0xeb, 0x33, 0xbe, 0x5e, 0xe3, 0x0a, 0x9a,
0xe6, 0x90, 0x84, 0x22, 0xa4, 0xb1, 0x3d, 0xa6, 0xf1, 0xcc, 0xc6, 0x36, 0x9a, 0x22, 0x8c, 0xbd,
0x4f, 0x5a, 0x60, 0x8f, 0x6b, 0x57, 0xd7, 0xc4, 0xab, 0x08, 0x11, 0xc6, 0x1e, 0x73, 0xfa, 0x14,
0x02, 0x69, 0x4f, 0x68, 0x67, 0x01, 0x71, 0x36, 0xd1, 0xd4, 0x16, 0x63, 0x7b, 0x71, 0x9d, 0xaa,
0xa2, 0xb2, 0xc3, 0xa0, 0x5b, 0x54, 0xad, 0x15, 0xc6, 0x88, 0x6c, 0xa6, 0x05, 0xf5, 0xda, 0xf9,
0xc5, 0x42, 0x4b, 0x29, 0xdd, 0x1d, 0x90, 0x24, 0x8c, 0x52, 0xd2, 0x0d, 0x54, 0x12, 0xb4, 0xcd,
0x03, 0x93, 0x61, 0xb6, 0x7a, 0xe0, 0xe6, 0xea, 0xb8, 0x5d, 0x75, 0xf4, 0xe2, 0xd3, 0xa0, 0xe6,
0x26, 0x55, 0x97, 0x1d, 0x37, 0x5c, 0xa5, 0xb5, 0x5b, 0xd0, 0xda, 0xed, 0x6a, 0xed, 0x6e, 0xe5,
0xe0, 0x13, 0x9d, 0xd6, 0x4f, 0xd3, 0x17, 0xbb, 0x1d, 0x1b, 0xd5, 0xed, 0x78, 0x5f, 0xb7, 0xef,
0xa0, 0x72, 0x57, 0x68, 0x1f, 0x04, 0xa3, 0xb1, 0x00, 0xfc, 0x1a, 0x9a, 0x0c, 0x25, 0xb4, 0x84,
0x6d, 0xad, 0x8d, 0xaf, 0xcf, 0x56, 0x97, 0xdc, 0xc2, 0xf6, 0xa4, 0xd2, 0xf8, 0x26, 0xc2, 0xd9,
0x46, 0x33, 0xea, 0xe7, 0xc3, 0xf7, 0xc8, 0x41, 0x73, 0x75, 0xaa, 0xa8, 0x42, 0x9d, 0x83, 0x30,
0xb2, 0x4d, 0xfb, 0x3d, 0x98, 0xf3, 0xeb, 0x04, 0xba, 0xa2, 0x49, 0x04, 0x01, 0x88, 0xd1, 0xfb,
0xdd, 0x16, 0xc0, 0xe3, 0xbc, 0xcd, 0xcc, 0x56, 0x3e, 0x46, 0x84, 0xf8, 0x8c, 0xf2, 0x5a, 0xda,
0x65, 0x66, 0xe3, 0x5b, 0x68, 0x5e, 0x88, 0xe6, 0x63, 0x1e, 0x26, 0x44, 0xc2, 0x7b, 0xd0, 0x49,
0x37, 0xbd, 0x17, 0x54, 0x19, 0xc2, 0x58, 0x40, 0xd0, 0xe6, 0x60, 0x4f, 0x6a, 0x96, 0x99, 0x8d,
0xef, 0xa0, 0x45, 0x19, 0x89, 0xed, 0x28, 0x84, 0x58, 0x6e, 0x03, 0x97, 0x3b, 0x44, 0x12, 0xbb,
0xa4, 0xb3, 0xf4, 0x3b, 0xf0, 0x06, 0x2a, 0xf7, 0x80, 0xaa, 0xe4, 0x94, 0x0e, 0xee, 0xc3, 0xb3,
0x11, 0x9b, 0xe9, 0x1d, 0x31, 0xdd, 0x23, 0x32, 0x98, 0xee, 0x6f, 0x05, 0xcd, 0x40, 0x4c, 0x8e,
0x22, 0x38, 0x08, 0x42, 0x7b, 0x56, 0xd3, 0xcb, 0x01, 0x7c, 0x17, 0x2d, 0x99, 0xc9, 0xda, 0x52,
0x3b, 0x9b, 0xf5, 0x39, 0xa7, 0x13, 0x0c, 0x72, 0xe1, 0x35, 0x34, 0x9b, 0xc1, 0x7b, 0x3b, 0xf6,
0xfc, 0x9a, 0xb5, 0x3e, 0xee, 0x17, 0x21, 0x7c, 0x0f, 0xfd, 0x3f, 0x37, 0x63, 0x21, 0x49, 0x14,
0xe9, 0xd1, 0xdb, 0xdb, 0xb1, 0x17, 0x74, 0xf4, 0x30, 0x37, 0x7e, 0x17, 0x55, 0x32, 0xd7, 0x6e,
0x2c, 0x81, 0x33, 0x1e, 0x0a, 0x78, 0x40, 0x04, 0x1c, 0xf2, 0xc8, 0xbe, 0xa2, 0x49, 0x8d, 0x88,
0xc0, 0xcb, 0x68, 0x92, 0x71, 0xfa, 0x79, 0xc7, 0x2e, 0xeb, 0x50, 0x63, 0xa8, 0x19, 0x67, 0xe9,
0x18, 0x2f, 0x9a, 0x19, 0x4f, 0x4d, 0x67, 0x01, 0xcd, 0xa9, 0xf1, 0xe9, 0xce, 0xaf, 0xf3, 0x93,
0x85, 0x16, 0x15, 0xb0, 0xcd, 0x81, 0x48, 0xf0, 0xe1, 0x59, 0x1b, 0x84, 0xc4, 0x1f, 0x17, 0x26,
0x6a, 0xb6, 0xfa, 0xe8, 0xdf, 0x1d, 0x45, 0x3f, 0x3b, 0x11, 0xe9, 0x6c, 0x5e, 0x45, 0xa5, 0x36,
0x13, 0xc0, 0x65, 0x3a, 0xe1, 0xa9, 0xa5, 0xf6, 0x2d, 0xe0, 0x50, 0x13, 0x07, 0x71, 0xd4, 0xd1,
0x83, 0x39, 0xed, 0xe7, 0x80, 0xf3, 0xcc, 0x10, 0x3d, 0x64, 0xb5, 0xcb, 0x22, 0x5a, 0xfd, 0x7b,
0xc1, 0xd4, 0x34, 0xe0, 0x13, 0xe0, 0x49, 0x18, 0x00, 0xfe, 0xda, 0x42, 0x13, 0xfb, 0xa1, 0x90,
0xf8, 0x7f, 0xc5, 0xc3, 0x9e, 0x1d, 0xed, 0xca, 0xfe, 0x45, 0xb1, 0x50, 0x45, 0x9c, 0x1b, 0x5f,
0xfc, 0xf1, 0xd7, 0xb7, 0x63, 0x57, 0xf1, 0xb2, 0x7e, 0x98, 0x92, 0xcd, 0xfc, 0xfe, 0x0f, 0x41,
0x7c, 0x39, 0x66, 0xe1, 0xaf, 0x2c, 0x34, 0xfe, 0x10, 0x86, 0xb2, 0xb9, 0x30, 0x4d, 0x9c, 0x9b,
0x9a, 0xc9, 0x75, 0x7c, 0x6d, 0x10, 0x13, 0xef, 0xb9, 0xb2, 0x5e, 0xe0, 0xef, 0x2c, 0x54, 0x56,
0xbc, 0xfd, 0x82, 0xef, 0x72, 0x84, 0x5a, 0x19, 0x25, 0x14, 0xfe, 0x04, 0x4d, 0x1b, 0x5a, 0xf5,
0xa1, 0x74, 0xca, 0xbd, 0x70, 0x5d, 0x38, 0xeb, 0x3a, 0xa5, 0x83, 0xd7, 0x46, 0x74, 0xec, 0x71,
0x95, 0xb2, 0x65, 0xd2, 0xab, 0xa7, 0x01, 0xbf, 0x72, 0x3a, 0x7d, 0xf6, 0x32, 0x57, 0x56, 0x06,
0xb9, 0xb2, 0xb3, 0x78, 0xae, 0x72, 0x44, 0x95, 0xf8, 0xc6, 0x42, 0xf3, 0x0f, 0x41, 0xe6, 0x6f,
0x28, 0xbe, 0x31, 0x20, 0x73, 0xf1, 0x7d, 0xad, 0x38, 0xc3, 0x03, 0x32, 0x02, 0x6f, 0x6b, 0x02,
0x6f, 0x3a, 0x77, 0x07, 0x13, 0x30, 0x0f, 0xa8, 0xce, 0x73, 0xe8, 0xef, 0x6b, 0x2a, 0x35, 0x93,
0xe1, 0xbe, 0xb5, 0x81, 0x13, 0x4d, 0xe9, 0x11, 0x44, 0xad, 0xed, 0x26, 0xe1, 0x72, 0xa8, 0xcc,
0xab, 0x45, 0x38, 0x0f, 0xcf, 0x48, 0xb8, 0x9a, 0xc4, 0x3a, 0xbe, 0x3d, 0x4a, 0x85, 0x26, 0x44,
0xad, 0xc0, 0x94, 0xf9, 0xde, 0x42, 0x25, 0x73, 0x7b, 0xe1, 0xeb, 0xa7, 0x2b, 0xf6, 0xdc, 0x6a,
0x17, 0x78, 0x14, 0x5e, 0xd5, 0x1c, 0x57, 0x9c, 0x81, 0xb3, 0x76, 0x5f, 0x5f, 0x1e, 0xea, 0x68,
0xfe, 0x60, 0xa1, 0x72, 0x97, 0x42, 0xf7, 0xb7, 0x97, 0x47, 0xd2, 0x39, 0x9b, 0x24, 0xfe, 0xd1,
0x42, 0x25, 0x73, 0xa3, 0xf6, 0xf3, 0xea, 0xb9, 0x69, 0x2f, 0x90, 0xd7, 0xa6, 0xd9, 0xe0, 0xca,
0x88, 0x31, 0xd7, 0x54, 0x5e, 0xe4, 0x42, 0xfe, 0x6c, 0xa1, 0x72, 0x97, 0xce, 0x70, 0x21, 0xff,
0x2b, 0xc2, 0xee, 0xcb, 0x11, 0xc6, 0x04, 0x95, 0x76, 0x20, 0x02, 0x09, 0xc3, 0x8e, 0x80, 0x7d,
0x1a, 0xce, 0x86, 0xff, 0xb6, 0xb9, 0x63, 0x37, 0x46, 0xdd, 0xb1, 0x4a, 0x90, 0x26, 0x2a, 0x9b,
0x12, 0x05, 0x3d, 0x5e, 0xba, 0xd8, 0xcd, 0x73, 0x14, 0xc3, 0xcf, 0xd1, 0xc2, 0x87, 0x24, 0x0a,
0x95, 0xb2, 0xe6, 0x3f, 0x27, 0xbe, 0xd6, 0x77, 0x93, 0xe4, 0xff, 0x45, 0x47, 0x54, 0xab, 0xea,
0x6a, 0x77, 0x9c, 0x5b, 0xa3, 0xce, 0x75, 0x92, 0x96, 0x32, 0x4a, 0x3e, 0xd8, 0xfd, 0xed, 0x64,
0xd5, 0xfa, 0xfd, 0x64, 0xd5, 0xfa, 0xf3, 0x64, 0xd5, 0xfa, 0xe8, 0xad, 0xf3, 0x7d, 0x7d, 0x05,
0xfa, 0x4f, 0x63, 0xe1, 0x3b, 0xe9, 0xa8, 0xa4, 0x3f, 0x94, 0xde, 0xf8, 0x27, 0x00, 0x00, 0xff,
0xff, 0x52, 0x69, 0xb3, 0xbe, 0x47, 0x0e, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -1338,6 +1363,20 @@ func (m *RepoAppsQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.AppProject) > 0 {
i -= len(m.AppProject)
copy(dAtA[i:], m.AppProject)
i = encodeVarintRepository(dAtA, i, uint64(len(m.AppProject)))
i--
dAtA[i] = 0x22
}
if len(m.AppName) > 0 {
i -= len(m.AppName)
copy(dAtA[i:], m.AppName)
i = encodeVarintRepository(dAtA, i, uint64(len(m.AppName)))
i--
dAtA[i] = 0x1a
}
if len(m.Revision) > 0 {
i -= len(m.Revision)
copy(dAtA[i:], m.Revision)
@@ -1420,6 +1459,13 @@ func (m *RepoAppDetailsQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.AppProject) > 0 {
i -= len(m.AppProject)
copy(dAtA[i:], m.AppProject)
i = encodeVarintRepository(dAtA, i, uint64(len(m.AppProject)))
i--
dAtA[i] = 0x1a
}
if len(m.AppName) > 0 {
i -= len(m.AppName)
copy(dAtA[i:], m.AppName)
@@ -1822,6 +1868,14 @@ func (m *RepoAppsQuery) Size() (n int) {
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
l = len(m.AppName)
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
l = len(m.AppProject)
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -1862,6 +1916,10 @@ func (m *RepoAppDetailsQuery) Size() (n int) {
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
l = len(m.AppProject)
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -2126,6 +2184,70 @@ func (m *RepoAppsQuery) Unmarshal(dAtA []byte) error {
}
m.Revision = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AppName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppProject", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AppProject = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])
@@ -2360,6 +2482,38 @@ func (m *RepoAppDetailsQuery) Unmarshal(dAtA []byte) error {
}
m.AppName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppProject", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AppProject = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])

View File

@@ -11,11 +11,11 @@ import (
context "context"
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
empty "github.com/golang/protobuf/ptypes/empty"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
emptypb "google.golang.org/protobuf/types/known/emptypb"
io "io"
math "math"
math_bits "math/bits"
@@ -225,7 +225,7 @@ const _ = grpc.SupportPackageIsVersion4
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type VersionServiceClient interface {
// Version returns version information of the API server
Version(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*VersionMessage, error)
Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*VersionMessage, error)
}
type versionServiceClient struct {
@@ -236,7 +236,7 @@ func NewVersionServiceClient(cc *grpc.ClientConn) VersionServiceClient {
return &versionServiceClient{cc}
}
func (c *versionServiceClient) Version(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*VersionMessage, error) {
func (c *versionServiceClient) Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*VersionMessage, error) {
out := new(VersionMessage)
err := c.cc.Invoke(ctx, "/version.VersionService/Version", in, out, opts...)
if err != nil {
@@ -248,14 +248,14 @@ func (c *versionServiceClient) Version(ctx context.Context, in *empty.Empty, opt
// VersionServiceServer is the server API for VersionService service.
type VersionServiceServer interface {
// Version returns version information of the API server
Version(context.Context, *empty.Empty) (*VersionMessage, error)
Version(context.Context, *emptypb.Empty) (*VersionMessage, error)
}
// UnimplementedVersionServiceServer can be embedded to have forward compatible implementations.
type UnimplementedVersionServiceServer struct {
}
func (*UnimplementedVersionServiceServer) Version(ctx context.Context, req *empty.Empty) (*VersionMessage, error) {
func (*UnimplementedVersionServiceServer) Version(ctx context.Context, req *emptypb.Empty) (*VersionMessage, error) {
return nil, status.Errorf(codes.Unimplemented, "method Version not implemented")
}
@@ -264,7 +264,7 @@ func RegisterVersionServiceServer(s *grpc.Server, srv VersionServiceServer) {
}
func _VersionService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(empty.Empty)
in := new(emptypb.Empty)
if err := dec(in); err != nil {
return nil, err
}
@@ -276,7 +276,7 @@ func _VersionService_Version_Handler(srv interface{}, ctx context.Context, dec f
FullMethod: "/version.VersionService/Version",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VersionServiceServer).Version(ctx, req.(*empty.Empty))
return srv.(VersionServiceServer).Version(ctx, req.(*emptypb.Empty))
}
return interceptor(ctx, in, info, handler)
}

View File

@@ -15,7 +15,6 @@ import (
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/empty"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
@@ -23,6 +22,7 @@ import (
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
)
// Suppress "imported and not used" errors
@@ -35,7 +35,7 @@ var _ = descriptor.ForMessage
var _ = metadata.Join
func request_VersionService_Version_0(ctx context.Context, marshaler runtime.Marshaler, client VersionServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.Version(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
@@ -44,7 +44,7 @@ func request_VersionService_Version_0(ctx context.Context, marshaler runtime.Mar
}
func local_request_VersionService_Version_0(ctx context.Context, marshaler runtime.Marshaler, server VersionServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.Version(ctx, &protoReq)

View File

@@ -27,6 +27,7 @@ API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/ap
API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Command,Args
API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Command,Command
API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ExecProviderConfig,Args
API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,HelmOptions,ValuesFileSchemes
API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,HostInfo,ResourcesInfo
API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTTokens,Items
API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Operation,Info
@@ -63,6 +64,7 @@ API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/ap
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,TLAs
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ClusterCacheInfo,APIsCount
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ConnectionState,ModifiedAt
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,HelmOptions,ValuesFileSchemes
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTToken,ExpiresAt
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTToken,IssuedAt
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,KustomizeOptions,BinaryPath

View File

@@ -1,8 +1,10 @@
package v1alpha1
import (
"os"
"strconv"
"math"
"time"
"github.com/argoproj/argo-cd/v2/util/env"
)
const (
@@ -19,39 +21,44 @@ const (
// EnvK8sClientMaxIdleConnections is the number of max idle connections in K8s REST client HTTP transport (default: 500)
EnvK8sClientMaxIdleConnections = "ARGOCD_K8S_CLIENT_MAX_IDLE_CONNECTIONS"
// EnvK8sTCPTimeout is the duration for TCP timeouts when communicating with K8s API servers
EnvK8sTCPTimeout = "ARGOCD_K8S_TCP_TIMEOUT"
// EnvK8sTCPKeepalive is the interval for TCP keep alive probes to be sent when communicating with K8s API servers
EnvK8sTCPKeepAlive = "ARGOCD_K8S_TCP_KEEPALIVE"
// EnvK8sTLSHandshakeTimeout is the duration for TLS handshake timeouts when establishing connections to K8s API servers
EnvK8sTLSHandshakeTimeout = "ARGOCD_K8S_TLS_HANDSHAKE_TIMEOUT"
// EnvK8sTCPIdleConnTimeout is the duration when idle TCP connection to the K8s API servers should timeout
EnvK8sTCPIdleConnTimeout = "ARGOCD_K8S_TCP_IDLE_TIMEOUT"
)
// Constants associated with the Cluster API
// Configuration variables associated with the Cluster API
var (
// K8sClientConfigQPS controls the QPS to be used in K8s REST client configs
K8sClientConfigQPS float32 = 50
K8sClientConfigQPS float32 = env.ParseFloatFromEnv(EnvK8sClientQPS, 50, 0, math.MaxFloat32)
// K8sClientConfigBurst controls the burst to be used in K8s REST client configs
K8sClientConfigBurst int = 100
K8sClientConfigBurst int = env.ParseNumFromEnv(EnvK8sClientBurst, int(2*K8sClientConfigQPS), 0, math.MaxInt32)
// K8sMaxIdleConnections controls the number of max idle connections in K8s REST client HTTP transport
K8sMaxIdleConnections = 500
K8sMaxIdleConnections = env.ParseNumFromEnv(EnvK8sClientMaxIdleConnections, 500, 0, math.MaxInt32)
// K8sTLSHandshakeTimeout defines the maximum duration to wait for a TLS handshake to complete
K8sTLSHandshakeTimeout = env.ParseDurationFromEnv(EnvK8sTLSHandshakeTimeout, 10*time.Second, 0, math.MaxInt32)
// K8sTCPTimeout defines the TCP timeout to use when performing K8s API requests
K8sTCPTimeout = env.ParseDurationFromEnv(EnvK8sTCPTimeout, 30*time.Second, 0, math.MaxInt32)
// K8sTCPKeepAlive defines the interval for sending TCP keep alive to K8s API server
K8sTCPKeepAlive = env.ParseDurationFromEnv(EnvK8sTCPKeepAlive, 30*time.Second, 0, math.MaxInt32)
// K8sTCPIdleConnTimeout defines the duration for keeping idle TCP connections to the K8s API server
K8sTCPIdleConnTimeout = env.ParseDurationFromEnv(EnvK8sTCPIdleConnTimeout, 5*time.Minute, 0, math.MaxInt32)
// K8sServerSideTimeout defines which server side timeout to send with each API request
K8sServerSideTimeout = env.ParseDurationFromEnv(EnvK8sTCPTimeout, 32*time.Second, 0, math.MaxInt32)
)
func init() {
if envQPS := os.Getenv(EnvK8sClientQPS); envQPS != "" {
if qps, err := strconv.ParseFloat(envQPS, 32); err == nil {
K8sClientConfigQPS = float32(qps)
}
}
if envBurst := os.Getenv(EnvK8sClientBurst); envBurst != "" {
if burst, err := strconv.Atoi(envBurst); err == nil {
K8sClientConfigBurst = burst
}
} else {
K8sClientConfigBurst = 2 * int(K8sClientConfigQPS)
}
if envMaxConn := os.Getenv(EnvK8sClientMaxIdleConnections); envMaxConn != "" {
if maxConn, err := strconv.Atoi(envMaxConn); err == nil {
K8sMaxIdleConnections = maxConn
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -608,6 +608,11 @@ message HelmFileParameter {
optional string path = 2;
}
// HelmOptions holds helm options
message HelmOptions {
repeated string valuesFileSchemes = 1;
}
// HelmParameter is a parameter that's passed to helm template during manifest generation
message HelmParameter {
// Name is the name of the Helm parameter

View File

@@ -52,6 +52,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GnuPGPublicKeyList": schema_pkg_apis_application_v1alpha1_GnuPGPublicKeyList(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus": schema_pkg_apis_application_v1alpha1_HealthStatus(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmFileParameter": schema_pkg_apis_application_v1alpha1_HelmFileParameter(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmOptions": schema_pkg_apis_application_v1alpha1_HelmOptions(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HelmParameter": schema_pkg_apis_application_v1alpha1_HelmParameter(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostInfo": schema_pkg_apis_application_v1alpha1_HostInfo(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HostResourceInfo": schema_pkg_apis_application_v1alpha1_HostResourceInfo(ref),
@@ -2119,6 +2120,34 @@ func schema_pkg_apis_application_v1alpha1_HelmFileParameter(ref common.Reference
}
}
func schema_pkg_apis_application_v1alpha1_HelmOptions(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "HelmOptions holds helm options",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"ValuesFileSchemes": {
SchemaProps: spec.SchemaProps{
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
},
},
},
Required: []string{"ValuesFileSchemes"},
},
},
}
}
func schema_pkg_apis_application_v1alpha1_HelmParameter(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{

View File

@@ -166,18 +166,18 @@ func (repo *Repository) CopyCredentialsFrom(source *RepoCreds) {
}
// GetGitCreds returns the credentials from a repository configuration used to authenticate at a Git repository
func (repo *Repository) GetGitCreds() git.Creds {
func (repo *Repository) GetGitCreds(store git.CredsStore) git.Creds {
if repo == nil {
return git.NopCreds{}
}
if repo.Password != "" {
return git.NewHTTPSCreds(repo.Username, repo.Password, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy)
return git.NewHTTPSCreds(repo.Username, repo.Password, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, store)
}
if repo.SSHPrivateKey != "" {
return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure())
return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure(), store)
}
if repo.GithubAppPrivateKey != "" && repo.GithubAppId != 0 && repo.GithubAppInstallationId != 0 {
return git.NewGitHubAppCreds(repo.GithubAppId, repo.GithubAppInstallationId, repo.GithubAppPrivateKey, repo.GitHubAppEnterpriseBaseURL, repo.Repo, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure())
return git.NewGitHubAppCreds(repo.GithubAppId, repo.GithubAppInstallationId, repo.GithubAppPrivateKey, repo.GitHubAppEnterpriseBaseURL, repo.Repo, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), store)
}
return git.NopCreds{}
}

View File

@@ -1618,10 +1618,18 @@ func validateRoleName(name string) error {
return nil
}
var invalidChars = regexp.MustCompile("[,\n\r\t]")
var invalidChars = regexp.MustCompile("[\"\n\r\t]")
func validateGroupName(name string) error {
if strings.TrimSpace(name) == "" {
name = strings.TrimSpace(name)
if len(name) > 1 && strings.HasPrefix(name, "\"") && strings.HasSuffix(name, "\"") {
// Remove surrounding quotes for further inspection of the group name
name = name[1 : len(name)-1]
} else if strings.Contains(name, ",") {
return status.Errorf(codes.InvalidArgument, "group '%s' must be quoted", name)
}
if name == "" {
return status.Errorf(codes.InvalidArgument, "group '%s' is empty", name)
}
if invalidChars.MatchString(name) {
@@ -2088,6 +2096,11 @@ type ConfigManagementPlugin struct {
LockRepo bool `json:"lockRepo,omitempty" protobuf:"bytes,4,name=lockRepo"`
}
// HelmOptions holds helm options
type HelmOptions struct {
ValuesFileSchemes []string `protobuf:"bytes,1,opt,name=valuesFileSchemes"`
}
// KustomizeOptions are options for kustomize to use when building manifests
type KustomizeOptions struct {
// BuildOptions is a string of build parameters to use when calling `kustomize build`
@@ -2353,18 +2366,19 @@ func SetK8SConfigDefaults(config *rest.Config) error {
}
dial := (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
Timeout: K8sTCPTimeout,
KeepAlive: K8sTCPKeepAlive,
}).DialContext
transport := utilnet.SetTransportDefaults(&http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSHandshakeTimeout: 10 * time.Second,
TLSHandshakeTimeout: K8sTLSHandshakeTimeout,
TLSClientConfig: tlsConfig,
MaxIdleConns: K8sMaxIdleConnections,
MaxIdleConnsPerHost: K8sMaxIdleConnections,
MaxConnsPerHost: K8sMaxIdleConnections,
DialContext: dial,
DisableCompression: config.DisableCompression,
IdleConnTimeout: K8sTCPIdleConnTimeout,
})
tr, err := rest.HTTPWrappersForConfig(config, transport)
if err != nil {
@@ -2376,6 +2390,9 @@ func SetK8SConfigDefaults(config *rest.Config) error {
config.AuthProvider = nil
config.ExecProvider = nil
// Set server-side timeout
config.Timeout = K8sServerSideTimeout
config.Transport = tr
return nil
}
@@ -2459,6 +2476,7 @@ func (c *Cluster) RawRestConfig() *rest.Config {
if err != nil {
panic(fmt.Sprintf("Unable to create K8s REST config: %v", err))
}
config.Timeout = K8sServerSideTimeout
return config
}

View File

@@ -2596,3 +2596,39 @@ func TestEnvsubst(t *testing.T) {
assert.Equal(t, "bar", env.Envsubst("$foo"))
assert.Equal(t, "$foo", env.Envsubst("$$foo"))
}
func Test_validateGroupName(t *testing.T) {
tcs := []struct {
name string
groupname string
isvalid bool
}{
{"Just a double quote", "\"", false},
{"Just two double quotes", "\"\"", false},
{"Normal group name", "foo", true},
{"Quoted with commas", "\"foo,bar,baz\"", true},
{"Quoted without commas", "\"foo\"", true},
{"Quoted with leading and trailing whitespace", " \"foo\" ", true},
{"Empty group name", "", false},
{"Empty group name with quotes", "\"\"", false},
{"Unquoted with comma", "foo,bar,baz", false},
{"Improperly quoted 1", "\"foo,bar,baz", false},
{"Improperly quoted 2", "foo,bar,baz\"", false},
{"Runaway quote in unqouted string", "foo,bar\",baz", false},
{"Runaway quote in quoted string", "\"foo,\"bar,baz\"", false},
{"Invalid characters unqouted", "foo\nbar", false},
{"Invalid characters qouted", "\"foo\nbar\"", false},
{"Runaway quote 1", "\"foo", false},
{"Runaway quote 2", "foo\"", false},
}
for _, tt := range tcs {
t.Run(tt.name, func(t *testing.T) {
err := validateGroupName(tt.groupname)
if tt.isvalid {
assert.NoError(t, err)
} else {
assert.Error(t, err)
}
})
}
}

View File

@@ -1067,6 +1067,27 @@ func (in *HelmFileParameter) DeepCopy() *HelmFileParameter {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmOptions) DeepCopyInto(out *HelmOptions) {
*out = *in
if in.ValuesFileSchemes != nil {
in, out := &in.ValuesFileSchemes, &out.ValuesFileSchemes
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmOptions.
func (in *HelmOptions) DeepCopy() *HelmOptions {
if in == nil {
return nil
}
out := new(HelmOptions)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmParameter) DeepCopyInto(out *HelmParameter) {
*out = *in

View File

@@ -0,0 +1,15 @@
package apiclient
func (q *ManifestRequest) GetValuesFileSchemes() []string {
if q.HelmOptions == nil {
return nil
}
return q.HelmOptions.ValuesFileSchemes
}
func (q *RepoServerAppDetailsQuery) GetValuesFileSchemes() []string {
if q.HelmOptions == nil {
return nil
}
return q.HelmOptions.ValuesFileSchemes
}

View File

@@ -51,6 +51,8 @@ type ManifestRequest struct {
HelmRepoCreds []*v1alpha1.RepoCreds `protobuf:"bytes,17,rep,name=helmRepoCreds,proto3" json:"helmRepoCreds,omitempty"`
NoRevisionCache bool `protobuf:"varint,18,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"`
TrackingMethod string `protobuf:"bytes,19,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"`
EnabledSourceTypes map[string]bool `protobuf:"bytes,20,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,21,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -201,6 +203,20 @@ func (m *ManifestRequest) GetTrackingMethod() string {
return ""
}
func (m *ManifestRequest) GetEnabledSourceTypes() map[string]bool {
if m != nil {
return m.EnabledSourceTypes
}
return nil
}
func (m *ManifestRequest) GetHelmOptions() *v1alpha1.HelmOptions {
if m != nil {
return m.HelmOptions
}
return nil
}
// TestRepositoryRequest is a query to test repository is valid or not and has valid access.
type TestRepositoryRequest struct {
Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"`
@@ -615,6 +631,7 @@ func (m *Refs) GetTags() []string {
type ListAppsRequest struct {
Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"`
Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"`
EnabledSourceTypes map[string]bool `protobuf:"bytes,3,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -667,6 +684,13 @@ func (m *ListAppsRequest) GetRevision() string {
return ""
}
func (m *ListAppsRequest) GetEnabledSourceTypes() map[string]bool {
if m != nil {
return m.EnabledSourceTypes
}
return nil
}
// AppList returns the contents of the repo of a ListApps request
type AppList struct {
Apps map[string]string `protobuf:"bytes,1,rep,name=apps,proto3" json:"apps,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
@@ -725,6 +749,8 @@ type RepoServerAppDetailsQuery struct {
NoCache bool `protobuf:"varint,6,opt,name=noCache,proto3" json:"noCache,omitempty"`
NoRevisionCache bool `protobuf:"varint,7,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"`
TrackingMethod string `protobuf:"bytes,8,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"`
EnabledSourceTypes map[string]bool `protobuf:"bytes,9,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,10,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -819,6 +845,20 @@ func (m *RepoServerAppDetailsQuery) GetTrackingMethod() string {
return ""
}
func (m *RepoServerAppDetailsQuery) GetEnabledSourceTypes() map[string]bool {
if m != nil {
return m.EnabledSourceTypes
}
return nil
}
func (m *RepoServerAppDetailsQuery) GetHelmOptions() *v1alpha1.HelmOptions {
if m != nil {
return m.HelmOptions
}
return nil
}
// RepoAppDetailsResponse application details
type RepoAppDetailsResponse struct {
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
@@ -1476,6 +1516,7 @@ func (m *HelmChartsResponse) GetItems() []*HelmChart {
func init() {
proto.RegisterType((*ManifestRequest)(nil), "repository.ManifestRequest")
proto.RegisterMapType((map[string]bool)(nil), "repository.ManifestRequest.EnabledSourceTypesEntry")
proto.RegisterType((*TestRepositoryRequest)(nil), "repository.TestRepositoryRequest")
proto.RegisterType((*TestRepositoryResponse)(nil), "repository.TestRepositoryResponse")
proto.RegisterType((*ResolveRevisionRequest)(nil), "repository.ResolveRevisionRequest")
@@ -1484,9 +1525,11 @@ func init() {
proto.RegisterType((*ListRefsRequest)(nil), "repository.ListRefsRequest")
proto.RegisterType((*Refs)(nil), "repository.Refs")
proto.RegisterType((*ListAppsRequest)(nil), "repository.ListAppsRequest")
proto.RegisterMapType((map[string]bool)(nil), "repository.ListAppsRequest.EnabledSourceTypesEntry")
proto.RegisterType((*AppList)(nil), "repository.AppList")
proto.RegisterMapType((map[string]string)(nil), "repository.AppList.AppsEntry")
proto.RegisterType((*RepoServerAppDetailsQuery)(nil), "repository.RepoServerAppDetailsQuery")
proto.RegisterMapType((map[string]bool)(nil), "repository.RepoServerAppDetailsQuery.EnabledSourceTypesEntry")
proto.RegisterType((*RepoAppDetailsResponse)(nil), "repository.RepoAppDetailsResponse")
proto.RegisterType((*RepoServerRevisionMetadataRequest)(nil), "repository.RepoServerRevisionMetadataRequest")
proto.RegisterType((*KsonnetAppSpec)(nil), "repository.KsonnetAppSpec")
@@ -1506,101 +1549,107 @@ func init() {
}
var fileDescriptor_dd8723cfcc820480 = []byte{
// 1502 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x18, 0x5b, 0x6f, 0x1b, 0x45,
0x37, 0xeb, 0x38, 0x17, 0x1f, 0xb7, 0x89, 0x33, 0xbd, 0xed, 0xb7, 0x5f, 0x1a, 0xa5, 0x8b, 0xa8,
0x02, 0x6d, 0xd7, 0xaa, 0x5b, 0x41, 0xd5, 0x4a, 0x48, 0x26, 0x6d, 0x53, 0x94, 0xa6, 0x09, 0x9b,
0x82, 0x04, 0x54, 0x54, 0x93, 0xf5, 0x64, 0x3d, 0x78, 0xbd, 0x3b, 0xdd, 0xd9, 0x35, 0x4a, 0x25,
0x1e, 0x78, 0xe2, 0x81, 0x67, 0xf8, 0x3b, 0xbc, 0x70, 0x7b, 0xe4, 0x27, 0xa0, 0xf2, 0x2b, 0x78,
0x43, 0x33, 0x7b, 0x5f, 0xaf, 0x03, 0x92, 0xd3, 0xf4, 0xc5, 0x9e, 0x39, 0xf7, 0x39, 0x73, 0x6e,
0xb3, 0x70, 0xd5, 0x27, 0xcc, 0xe3, 0xc4, 0x1f, 0x11, 0xbf, 0x2d, 0x97, 0x34, 0xf0, 0xfc, 0xa3,
0xdc, 0xd2, 0x60, 0xbe, 0x17, 0x78, 0x08, 0x32, 0x88, 0x76, 0xde, 0xf6, 0x6c, 0x4f, 0x82, 0xdb,
0x62, 0x15, 0x51, 0x68, 0xab, 0xb6, 0xe7, 0xd9, 0x0e, 0x69, 0x63, 0x46, 0xdb, 0xd8, 0x75, 0xbd,
0x00, 0x07, 0xd4, 0x73, 0x79, 0x8c, 0xd5, 0x07, 0x77, 0xb8, 0x41, 0x3d, 0x89, 0xb5, 0x3c, 0x9f,
0xb4, 0x47, 0x37, 0xdb, 0x36, 0x71, 0x89, 0x8f, 0x03, 0xd2, 0x8b, 0x69, 0x1e, 0xdb, 0x34, 0xe8,
0x87, 0x07, 0x86, 0xe5, 0x0d, 0xdb, 0xd8, 0x97, 0x2a, 0xbe, 0x92, 0x8b, 0x1b, 0x56, 0xaf, 0x3d,
0xea, 0xb4, 0xd9, 0xc0, 0x16, 0xfc, 0xbc, 0x8d, 0x19, 0x73, 0xa8, 0x25, 0xe5, 0xb7, 0x47, 0x37,
0xb1, 0xc3, 0xfa, 0x78, 0x4c, 0x9a, 0xfe, 0xf7, 0x02, 0x2c, 0xef, 0x60, 0x97, 0x1e, 0x12, 0x1e,
0x98, 0xe4, 0x45, 0x48, 0x78, 0x80, 0x9e, 0x41, 0x5d, 0x9c, 0x43, 0x55, 0xd6, 0x95, 0x8d, 0x66,
0xe7, 0x91, 0x91, 0x29, 0x34, 0x12, 0x85, 0x72, 0xf1, 0xdc, 0xea, 0x19, 0xa3, 0x8e, 0xc1, 0x06,
0xb6, 0x21, 0x14, 0x1a, 0x39, 0x85, 0x46, 0xa2, 0xd0, 0x30, 0x53, 0x8f, 0x98, 0x52, 0x2a, 0xd2,
0x60, 0xd1, 0x27, 0x23, 0xca, 0xa9, 0xe7, 0xaa, 0xb5, 0x75, 0x65, 0xa3, 0x61, 0xa6, 0x7b, 0xa4,
0xc2, 0x82, 0xeb, 0x6d, 0x62, 0xab, 0x4f, 0xd4, 0xd9, 0x75, 0x65, 0x63, 0xd1, 0x4c, 0xb6, 0x68,
0x1d, 0x9a, 0x98, 0xb1, 0xc7, 0xf8, 0x80, 0x38, 0xdb, 0xe4, 0x48, 0xad, 0x4b, 0xc6, 0x3c, 0x48,
0xf0, 0x62, 0xc6, 0x9e, 0xe0, 0x21, 0x51, 0xe7, 0x24, 0x36, 0xd9, 0xa2, 0x55, 0x68, 0xb8, 0x78,
0x48, 0x38, 0xc3, 0x16, 0x51, 0x17, 0x25, 0x2e, 0x03, 0xa0, 0x6f, 0x60, 0x25, 0x67, 0xf8, 0xbe,
0x17, 0xfa, 0x16, 0x51, 0x41, 0x1e, 0x7d, 0x77, 0xba, 0xa3, 0x77, 0xcb, 0x62, 0xcd, 0x71, 0x4d,
0xe8, 0x4b, 0x98, 0x93, 0x41, 0xa3, 0x36, 0xd7, 0x67, 0x4f, 0xd4, 0xdb, 0x91, 0x58, 0xe4, 0xc2,
0x02, 0x73, 0x42, 0x9b, 0xba, 0x5c, 0x3d, 0x23, 0x35, 0x3c, 0x9d, 0x4e, 0xc3, 0xa6, 0xe7, 0x1e,
0x52, 0x7b, 0x07, 0xbb, 0xd8, 0x26, 0x43, 0xe2, 0x06, 0x7b, 0x52, 0xb8, 0x99, 0x28, 0x41, 0x2f,
0xa1, 0x35, 0x08, 0x79, 0xe0, 0x0d, 0xe9, 0x4b, 0xb2, 0xcb, 0x64, 0x70, 0xab, 0x67, 0xa5, 0x37,
0x9f, 0x4c, 0xa7, 0x78, 0xbb, 0x24, 0xd5, 0x1c, 0xd3, 0x23, 0x82, 0x64, 0x10, 0x1e, 0x90, 0x4f,
0x89, 0x2f, 0xa3, 0x6b, 0x29, 0x0a, 0x92, 0x1c, 0x28, 0x0a, 0x23, 0x1a, 0xef, 0xb8, 0xba, 0xbc,
0x3e, 0x1b, 0x85, 0x51, 0x0a, 0x42, 0x1b, 0xb0, 0x3c, 0x22, 0x3e, 0x3d, 0x3c, 0xda, 0xa7, 0xb6,
0x8b, 0x83, 0xd0, 0x27, 0x6a, 0x4b, 0x86, 0x62, 0x19, 0x8c, 0x86, 0x70, 0xb6, 0x4f, 0x9c, 0xa1,
0x70, 0xf9, 0xa6, 0x4f, 0x7a, 0x5c, 0x5d, 0x91, 0xfe, 0xdd, 0x9a, 0xfe, 0x06, 0xa5, 0x38, 0xb3,
0x28, 0x5d, 0x18, 0xe6, 0x7a, 0x66, 0x9c, 0x29, 0x51, 0x8e, 0xa0, 0xc8, 0xb0, 0x12, 0x18, 0x5d,
0x85, 0xa5, 0xc0, 0xc7, 0xd6, 0x80, 0xba, 0xf6, 0x0e, 0x09, 0xfa, 0x5e, 0x4f, 0x3d, 0x27, 0x3d,
0x51, 0x82, 0xea, 0x21, 0x5c, 0x78, 0x2a, 0xd3, 0x3e, 0x8d, 0x99, 0xd3, 0x28, 0x00, 0xfa, 0x23,
0xb8, 0x58, 0x56, 0xcb, 0x99, 0xe7, 0x72, 0x82, 0x0c, 0x40, 0xd2, 0xc9, 0x94, 0xf4, 0x32, 0xac,
0xb4, 0x62, 0xd1, 0xac, 0xc0, 0xe8, 0xdf, 0xd6, 0xe0, 0xa2, 0x49, 0xb8, 0xe7, 0x8c, 0x48, 0xe2,
0x81, 0xd3, 0xa9, 0x61, 0x5f, 0xc0, 0x2c, 0x66, 0x4c, 0x96, 0xaf, 0x66, 0xe7, 0xa3, 0x13, 0xab,
0x12, 0xa6, 0x90, 0x8a, 0xae, 0xc3, 0x0a, 0x1e, 0x1e, 0x50, 0x3b, 0xf4, 0x42, 0x9e, 0x1c, 0x4b,
0x96, 0xc3, 0x86, 0x39, 0x8e, 0xd0, 0x2d, 0xb8, 0x34, 0xe6, 0x82, 0xd8, 0x9d, 0xf9, 0x4a, 0xab,
0x94, 0x2a, 0x6d, 0xa5, 0x92, 0xda, 0x24, 0x25, 0xbf, 0x2a, 0xd0, 0xca, 0xba, 0x44, 0x2c, 0x7e,
0x15, 0x1a, 0xc3, 0x18, 0xc6, 0x55, 0x45, 0x66, 0x52, 0x06, 0x28, 0x16, 0xdd, 0x5a, 0xb9, 0xe8,
0x5e, 0x84, 0xf9, 0xa8, 0x9d, 0xc6, 0x07, 0x8b, 0x77, 0x05, 0x93, 0xeb, 0x25, 0x93, 0xd7, 0x00,
0xb8, 0xac, 0x99, 0x4f, 0x8f, 0x18, 0x51, 0xe7, 0x25, 0x36, 0x07, 0x41, 0x3a, 0x9c, 0x89, 0x52,
0xd4, 0x24, 0x3c, 0x74, 0x02, 0x75, 0x41, 0x52, 0x14, 0x60, 0xba, 0x07, 0xcb, 0x8f, 0xa9, 0x38,
0xc3, 0x21, 0x3f, 0x9d, 0x60, 0x7f, 0x0f, 0xea, 0x42, 0x99, 0x38, 0xd8, 0x81, 0x8f, 0x5d, 0xab,
0x4f, 0x12, 0x5f, 0xa5, 0x7b, 0x84, 0xa0, 0x1e, 0x60, 0x9b, 0xab, 0x35, 0x09, 0x97, 0x6b, 0xfd,
0x7b, 0x25, 0xb2, 0xb4, 0xcb, 0x18, 0x7f, 0xe3, 0x7d, 0x59, 0x0f, 0x61, 0xa1, 0xcb, 0x98, 0xb0,
0x07, 0xdd, 0x84, 0x3a, 0x66, 0x2c, 0x3a, 0x44, 0xb3, 0x73, 0xd9, 0xc8, 0xcd, 0x40, 0x31, 0x89,
0xf8, 0xe7, 0x0f, 0xdc, 0x40, 0x48, 0x16, 0xa4, 0xda, 0xfb, 0xd0, 0x48, 0x41, 0xa8, 0x05, 0xb3,
0x03, 0x72, 0x14, 0xc7, 0xa3, 0x58, 0xa2, 0xf3, 0x30, 0x37, 0xc2, 0x4e, 0x98, 0x44, 0x49, 0xb4,
0xb9, 0x5b, 0xbb, 0xa3, 0xe8, 0x3f, 0xd7, 0xe1, 0x7f, 0xc2, 0xce, 0x7d, 0x19, 0x1c, 0x5d, 0xc6,
0xee, 0x93, 0x00, 0x53, 0x87, 0x7f, 0x1c, 0x12, 0xff, 0xe8, 0x35, 0xbb, 0xc3, 0x86, 0xf9, 0x28,
0xb6, 0xe2, 0x2c, 0x3f, 0xf1, 0x59, 0x20, 0x16, 0x9f, 0x0d, 0x00, 0xb3, 0xaf, 0x67, 0x00, 0xa8,
0x6a, 0xc8, 0xf5, 0x53, 0x6a, 0xc8, 0x93, 0x67, 0xb2, 0xdc, 0xa4, 0x37, 0x5f, 0x9c, 0xf4, 0x2a,
0xfa, 0xdc, 0xc2, 0x7f, 0xed, 0x73, 0x8b, 0x95, 0x7d, 0xee, 0x3b, 0xd9, 0x26, 0x98, 0x97, 0x05,
0x50, 0x5a, 0xc3, 0x44, 0xea, 0x89, 0x6a, 0x12, 0x85, 0xa3, 0x5c, 0xa3, 0xdb, 0xb0, 0x30, 0xe0,
0x9e, 0xeb, 0x92, 0x20, 0xbe, 0x7a, 0x2d, 0x1f, 0xe4, 0xdb, 0x11, 0xaa, 0xcb, 0xd8, 0x3e, 0x23,
0x96, 0x99, 0x90, 0xa2, 0x6b, 0x50, 0x17, 0xfd, 0x5a, 0xd6, 0xb3, 0x66, 0xe7, 0x52, 0x9e, 0xe5,
0x11, 0x71, 0x86, 0x09, 0xbd, 0x24, 0x42, 0x77, 0xa1, 0x91, 0xfa, 0x2a, 0xbe, 0x8c, 0xd5, 0x82,
0x92, 0x04, 0x99, 0xb0, 0x65, 0xe4, 0x82, 0xb7, 0x47, 0x7d, 0x62, 0xc9, 0xde, 0x38, 0x37, 0xce,
0x7b, 0x3f, 0x41, 0xa6, 0xbc, 0x29, 0xb9, 0xfe, 0x8b, 0x02, 0x57, 0xb2, 0x84, 0x4a, 0xbc, 0xb9,
0x43, 0x02, 0xdc, 0xc3, 0x01, 0x7e, 0xf3, 0xf3, 0xff, 0x55, 0x58, 0xb2, 0xfa, 0xc4, 0x1a, 0x64,
0xb3, 0x57, 0xf4, 0x0c, 0x28, 0x41, 0xf5, 0xdf, 0x6a, 0xb0, 0x54, 0xbc, 0x08, 0x71, 0x93, 0xa2,
0xbd, 0x24, 0x37, 0x29, 0xd6, 0x68, 0x0f, 0xce, 0x10, 0x77, 0x44, 0x7d, 0xcf, 0x15, 0x93, 0x6a,
0x92, 0x61, 0xd7, 0x27, 0x5f, 0xa7, 0xf1, 0x20, 0x47, 0x1e, 0x95, 0xb0, 0x82, 0x04, 0xe4, 0x02,
0x30, 0xec, 0xe3, 0x21, 0x09, 0x88, 0x2f, 0xd2, 0x68, 0xf6, 0x04, 0xd2, 0x28, 0xb2, 0x60, 0x2f,
0x11, 0x6b, 0xe6, 0x34, 0x68, 0xcf, 0x61, 0x65, 0xcc, 0xa4, 0x8a, 0x12, 0x7a, 0x3b, 0x5f, 0x42,
0x9b, 0x9d, 0xb5, 0x8a, 0x13, 0xe6, 0xc4, 0xe4, 0x4b, 0xec, 0x4f, 0x35, 0x68, 0xe6, 0xe2, 0xb3,
0xd2, 0x8d, 0x6b, 0x00, 0x92, 0xe1, 0x21, 0x75, 0x48, 0xe4, 0xc4, 0x86, 0x99, 0x83, 0xa0, 0x41,
0x85, 0x53, 0xb6, 0xa7, 0x73, 0x8a, 0x30, 0xa9, 0xd2, 0x23, 0x62, 0x72, 0x90, 0xaa, 0x79, 0x5c,
0x51, 0xe2, 0x1d, 0xfa, 0x1a, 0x96, 0x0e, 0xa9, 0x43, 0xf6, 0x32, 0x43, 0xe6, 0xa5, 0x21, 0xbb,
0xd3, 0x1b, 0xf2, 0x30, 0x2f, 0xd7, 0x2c, 0xa9, 0xd1, 0xdf, 0x85, 0x56, 0x39, 0x5d, 0x85, 0x91,
0x74, 0x88, 0xed, 0xd4, 0x5b, 0xf1, 0x4e, 0xff, 0x41, 0x01, 0x34, 0x7e, 0x1f, 0x93, 0x9c, 0x3e,
0xb8, 0xc3, 0x93, 0xa7, 0x4c, 0x94, 0x28, 0x39, 0x08, 0xda, 0x86, 0x66, 0x8f, 0xf0, 0x80, 0xba,
0xd2, 0xe0, 0xb8, 0x88, 0xbc, 0x73, 0xfc, 0xc5, 0xdf, 0xcf, 0x18, 0xcc, 0x3c, 0xb7, 0xfe, 0x09,
0x5c, 0x3e, 0x96, 0x3a, 0x37, 0xaf, 0x29, 0x85, 0x79, 0xed, 0xd8, 0x29, 0x4f, 0x47, 0xd0, 0x2a,
0x57, 0x23, 0xfd, 0x05, 0xac, 0x08, 0x9f, 0x6e, 0xf6, 0xb1, 0x1f, 0x9c, 0xd2, 0x0c, 0x76, 0x0f,
0x1a, 0xa9, 0xca, 0x4a, 0x5f, 0x6b, 0xb0, 0x38, 0x4a, 0x9e, 0x84, 0xd1, 0x10, 0x96, 0xee, 0xf5,
0x2e, 0xa0, 0xbc, 0xbd, 0x71, 0xdf, 0xb8, 0x06, 0x73, 0x34, 0x20, 0xc3, 0x64, 0x0c, 0xba, 0x50,
0x2e, 0xf7, 0x92, 0xdc, 0x8c, 0x68, 0x3a, 0x7f, 0xcd, 0xc1, 0x4a, 0x56, 0x75, 0xc5, 0x2f, 0xb5,
0x08, 0xda, 0x85, 0xd6, 0x56, 0xfc, 0x31, 0x26, 0x19, 0xad, 0xd1, 0xff, 0xf3, 0x72, 0x4a, 0x9f,
0x65, 0xb4, 0xd5, 0x6a, 0x64, 0x64, 0x91, 0x3e, 0x83, 0x3e, 0x83, 0xa5, 0xe2, 0xbb, 0x0a, 0x5d,
0xc9, 0x73, 0x54, 0x3e, 0xf5, 0x34, 0xfd, 0x38, 0x92, 0x54, 0xf4, 0x33, 0x58, 0x2e, 0x3d, 0x32,
0x50, 0x81, 0xb1, 0xfa, 0x11, 0xa6, 0xbd, 0x75, 0x2c, 0x4d, 0x2a, 0xfd, 0x1e, 0x2c, 0x26, 0x43,
0x79, 0xd1, 0x03, 0xa5, 0x51, 0x5d, 0x6b, 0x15, 0xe5, 0x1d, 0x72, 0x7d, 0x06, 0x7d, 0x10, 0x31,
0x8b, 0x01, 0x73, 0x9c, 0x39, 0x37, 0x3d, 0x6b, 0xe7, 0x2a, 0x46, 0x55, 0x79, 0xb4, 0xb3, 0x5b,
0xb2, 0xfe, 0xc7, 0xa3, 0x01, 0x7a, 0xbb, 0xa8, 0x64, 0xc2, 0xf4, 0xa9, 0xe9, 0x65, 0xb2, 0xf1,
0xe9, 0x42, 0x9f, 0x41, 0x3f, 0x2a, 0x70, 0x6e, 0x8b, 0x04, 0xe5, 0x4e, 0x8b, 0x6e, 0x54, 0x2b,
0x99, 0xd0, 0x91, 0xb5, 0x27, 0xd3, 0x66, 0x44, 0x51, 0xac, 0x3e, 0x83, 0xf6, 0xe4, 0xb1, 0xb3,
0xc8, 0x46, 0x97, 0x2b, 0x43, 0x38, 0xf5, 0xde, 0xda, 0x24, 0x74, 0x72, 0xd4, 0x0f, 0xbb, 0xbf,
0xbf, 0x5a, 0x53, 0xfe, 0x78, 0xb5, 0xa6, 0xfc, 0xf9, 0x6a, 0x4d, 0xf9, 0xfc, 0xd6, 0xbf, 0x7c,
0xa5, 0xcc, 0x7d, 0x50, 0xc5, 0x8c, 0x5a, 0x0e, 0x25, 0x6e, 0x70, 0x30, 0x2f, 0xbf, 0x49, 0xde,
0xfa, 0x27, 0x00, 0x00, 0xff, 0xff, 0x6e, 0xdf, 0x39, 0x38, 0x6f, 0x15, 0x00, 0x00,
// 1597 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcd, 0x6f, 0x1b, 0x45,
0x14, 0xcf, 0xda, 0x4e, 0x62, 0x3f, 0xb7, 0x89, 0x33, 0xfd, 0x5a, 0x96, 0x34, 0x4a, 0x17, 0x51,
0x05, 0xda, 0xae, 0xd5, 0xb4, 0x82, 0xaa, 0x15, 0x48, 0x21, 0x4d, 0x53, 0x94, 0xa6, 0x09, 0x9b,
0x82, 0x04, 0x54, 0x54, 0x93, 0xf5, 0x64, 0x3d, 0xd8, 0xde, 0x9d, 0xee, 0xac, 0x8d, 0x52, 0x89,
0x03, 0x27, 0xee, 0x48, 0xf0, 0xaf, 0x70, 0xe4, 0xc4, 0xc7, 0x91, 0x3f, 0x01, 0x95, 0x03, 0xff,
0x06, 0x9a, 0xd9, 0xaf, 0xf1, 0x7a, 0x9d, 0x16, 0x39, 0x4d, 0xc5, 0x25, 0x99, 0x79, 0xf3, 0xbe,
0xe7, 0xcd, 0x9b, 0xdf, 0xac, 0xe1, 0x72, 0x40, 0x98, 0xcf, 0x49, 0x30, 0x20, 0x41, 0x53, 0x0e,
0x69, 0xe8, 0x07, 0x87, 0xca, 0xd0, 0x62, 0x81, 0x1f, 0xfa, 0x08, 0x32, 0x8a, 0x71, 0xd6, 0xf5,
0x5d, 0x5f, 0x92, 0x9b, 0x62, 0x14, 0x71, 0x18, 0x8b, 0xae, 0xef, 0xbb, 0x5d, 0xd2, 0xc4, 0x8c,
0x36, 0xb1, 0xe7, 0xf9, 0x21, 0x0e, 0xa9, 0xef, 0xf1, 0x78, 0xd5, 0xec, 0xdc, 0xe2, 0x16, 0xf5,
0xe5, 0xaa, 0xe3, 0x07, 0xa4, 0x39, 0xb8, 0xde, 0x74, 0x89, 0x47, 0x02, 0x1c, 0x92, 0x56, 0xcc,
0xf3, 0xc0, 0xa5, 0x61, 0xbb, 0xbf, 0x6f, 0x39, 0x7e, 0xaf, 0x89, 0x03, 0x69, 0xe2, 0x6b, 0x39,
0xb8, 0xe6, 0xb4, 0x9a, 0x83, 0xd5, 0x26, 0xeb, 0xb8, 0x42, 0x9e, 0x37, 0x31, 0x63, 0x5d, 0xea,
0x48, 0xfd, 0xcd, 0xc1, 0x75, 0xdc, 0x65, 0x6d, 0x3c, 0xa2, 0xcd, 0xfc, 0x01, 0x60, 0x7e, 0x1b,
0x7b, 0xf4, 0x80, 0xf0, 0xd0, 0x26, 0x4f, 0xfb, 0x84, 0x87, 0xe8, 0x31, 0x54, 0x44, 0x1c, 0xba,
0xb6, 0xac, 0xad, 0xd4, 0x57, 0xef, 0x5b, 0x99, 0x41, 0x2b, 0x31, 0x28, 0x07, 0x4f, 0x9c, 0x96,
0x35, 0x58, 0xb5, 0x58, 0xc7, 0xb5, 0x84, 0x41, 0x4b, 0x31, 0x68, 0x25, 0x06, 0x2d, 0x3b, 0xcd,
0x88, 0x2d, 0xb5, 0x22, 0x03, 0xaa, 0x01, 0x19, 0x50, 0x4e, 0x7d, 0x4f, 0x2f, 0x2d, 0x6b, 0x2b,
0x35, 0x3b, 0x9d, 0x23, 0x1d, 0x66, 0x3d, 0x7f, 0x1d, 0x3b, 0x6d, 0xa2, 0x97, 0x97, 0xb5, 0x95,
0xaa, 0x9d, 0x4c, 0xd1, 0x32, 0xd4, 0x31, 0x63, 0x0f, 0xf0, 0x3e, 0xe9, 0x6e, 0x91, 0x43, 0xbd,
0x22, 0x05, 0x55, 0x92, 0x90, 0xc5, 0x8c, 0x3d, 0xc4, 0x3d, 0xa2, 0x4f, 0xcb, 0xd5, 0x64, 0x8a,
0x16, 0xa1, 0xe6, 0xe1, 0x1e, 0xe1, 0x0c, 0x3b, 0x44, 0xaf, 0xca, 0xb5, 0x8c, 0x80, 0xbe, 0x85,
0x05, 0xc5, 0xf1, 0x3d, 0xbf, 0x1f, 0x38, 0x44, 0x07, 0x19, 0xfa, 0xce, 0x64, 0xa1, 0xaf, 0xe5,
0xd5, 0xda, 0xa3, 0x96, 0xd0, 0x57, 0x30, 0x2d, 0x8b, 0x46, 0xaf, 0x2f, 0x97, 0x8f, 0x35, 0xdb,
0x91, 0x5a, 0xe4, 0xc1, 0x2c, 0xeb, 0xf6, 0x5d, 0xea, 0x71, 0xfd, 0x94, 0xb4, 0xf0, 0x68, 0x32,
0x0b, 0xeb, 0xbe, 0x77, 0x40, 0xdd, 0x6d, 0xec, 0x61, 0x97, 0xf4, 0x88, 0x17, 0xee, 0x4a, 0xe5,
0x76, 0x62, 0x04, 0x3d, 0x83, 0x46, 0xa7, 0xcf, 0x43, 0xbf, 0x47, 0x9f, 0x91, 0x1d, 0x26, 0x8b,
0x5b, 0x3f, 0x2d, 0xb3, 0xf9, 0x70, 0x32, 0xc3, 0x5b, 0x39, 0xad, 0xf6, 0x88, 0x1d, 0x51, 0x24,
0x9d, 0xfe, 0x3e, 0xf9, 0x8c, 0x04, 0xb2, 0xba, 0xe6, 0xa2, 0x22, 0x51, 0x48, 0x51, 0x19, 0xd1,
0x78, 0xc6, 0xf5, 0xf9, 0xe5, 0x72, 0x54, 0x46, 0x29, 0x09, 0xad, 0xc0, 0xfc, 0x80, 0x04, 0xf4,
0xe0, 0x70, 0x8f, 0xba, 0x1e, 0x0e, 0xfb, 0x01, 0xd1, 0x1b, 0xb2, 0x14, 0xf3, 0x64, 0xd4, 0x83,
0xd3, 0x6d, 0xd2, 0xed, 0x89, 0x94, 0xaf, 0x07, 0xa4, 0xc5, 0xf5, 0x05, 0x99, 0xdf, 0xcd, 0xc9,
0x77, 0x50, 0xaa, 0xb3, 0x87, 0xb5, 0x0b, 0xc7, 0x3c, 0xdf, 0x8e, 0x4f, 0x4a, 0x74, 0x46, 0x50,
0xe4, 0x58, 0x8e, 0x8c, 0x2e, 0xc3, 0x5c, 0x18, 0x60, 0xa7, 0x43, 0x3d, 0x77, 0x9b, 0x84, 0x6d,
0xbf, 0xa5, 0x9f, 0x91, 0x99, 0xc8, 0x51, 0x91, 0x03, 0x88, 0x78, 0x78, 0xbf, 0x4b, 0x5a, 0x51,
0x2d, 0x3e, 0x3a, 0x64, 0x84, 0xeb, 0x67, 0x65, 0x14, 0x37, 0x2c, 0xa5, 0xb9, 0xe5, 0x1a, 0x84,
0xb5, 0x31, 0x22, 0xb5, 0xe1, 0x85, 0xc1, 0xa1, 0x5d, 0xa0, 0x0e, 0x75, 0xa0, 0x2e, 0xe2, 0x48,
0x4a, 0xe1, 0x9c, 0x2c, 0x85, 0x8f, 0x27, 0xcb, 0xd1, 0xfd, 0x4c, 0xa1, 0xad, 0x6a, 0x37, 0x36,
0xe0, 0xc2, 0x18, 0xdf, 0x50, 0x03, 0xca, 0x1d, 0x72, 0x28, 0x7b, 0x5a, 0xcd, 0x16, 0x43, 0x74,
0x16, 0xa6, 0x07, 0xb8, 0xdb, 0x27, 0xb2, 0x0b, 0x55, 0xed, 0x68, 0x72, 0xbb, 0x74, 0x4b, 0x33,
0xfb, 0x70, 0xee, 0x91, 0x0c, 0x37, 0x3d, 0x4c, 0x27, 0xd1, 0x19, 0xcd, 0xfb, 0x70, 0x3e, 0x6f,
0x96, 0x33, 0xdf, 0xe3, 0x04, 0x59, 0x80, 0x64, 0xf5, 0x51, 0xd2, 0xca, 0x56, 0xa5, 0x17, 0x55,
0xbb, 0x60, 0xc5, 0xfc, 0xae, 0x04, 0xe7, 0x6d, 0xc2, 0xfd, 0xee, 0x80, 0x24, 0xa5, 0x71, 0x32,
0xcd, 0xfd, 0x4b, 0x28, 0x63, 0xc6, 0x64, 0x46, 0x27, 0xde, 0x65, 0xa5, 0x7d, 0xda, 0x42, 0x2b,
0xba, 0x0a, 0x0b, 0xb8, 0xb7, 0x4f, 0xdd, 0xbe, 0xdf, 0xe7, 0x49, 0x58, 0xf2, 0x9e, 0xa8, 0xd9,
0xa3, 0x0b, 0xa6, 0x03, 0x17, 0x46, 0x52, 0x10, 0xa7, 0x53, 0xbd, 0x82, 0xb4, 0xdc, 0x15, 0x54,
0x68, 0xa4, 0x34, 0xce, 0xc8, 0x6f, 0x1a, 0x34, 0xb2, 0xd3, 0x11, 0xab, 0x5f, 0x84, 0x5a, 0x2f,
0xa6, 0x71, 0x5d, 0x93, 0x2d, 0x26, 0x23, 0x0c, 0xdf, 0x46, 0xa5, 0xfc, 0x6d, 0x74, 0x1e, 0x66,
0x22, 0x9c, 0x11, 0x07, 0x16, 0xcf, 0x86, 0x5c, 0xae, 0xe4, 0x5c, 0x5e, 0x02, 0xe0, 0x69, 0xb9,
0xeb, 0x33, 0x72, 0x55, 0xa1, 0x20, 0x13, 0x4e, 0x45, 0xbd, 0xcb, 0x26, 0xbc, 0xdf, 0x0d, 0xf5,
0x59, 0xc9, 0x31, 0x44, 0x33, 0x7d, 0x98, 0x7f, 0x40, 0x45, 0x0c, 0x07, 0xfc, 0x64, 0x8a, 0xfd,
0x3d, 0xa8, 0x08, 0x63, 0x22, 0xb0, 0xfd, 0x00, 0x7b, 0x4e, 0x9b, 0x24, 0xb9, 0x4a, 0xe7, 0x08,
0x41, 0x25, 0xc4, 0x2e, 0xd7, 0x4b, 0x92, 0x2e, 0xc7, 0xe6, 0xcf, 0xa5, 0xc8, 0xd3, 0x35, 0xc6,
0xf8, 0xeb, 0x07, 0x2c, 0xc5, 0x2d, 0xb4, 0x3c, 0xda, 0x42, 0x73, 0x2e, 0xff, 0x97, 0x16, 0x7a,
0x7c, 0x5d, 0x6d, 0x76, 0x8d, 0x31, 0xe1, 0x08, 0xba, 0x0e, 0x15, 0xcc, 0x58, 0x94, 0xf0, 0xfa,
0xea, 0x45, 0xd5, 0xd1, 0x98, 0x45, 0xfc, 0x8f, 0x5d, 0x92, 0xac, 0xc6, 0xfb, 0x50, 0x4b, 0x49,
0x2f, 0x32, 0x5b, 0x53, 0xcd, 0xfe, 0x33, 0x03, 0x6f, 0x88, 0x9c, 0xee, 0xc9, 0x42, 0x5e, 0x63,
0xec, 0x2e, 0x09, 0x31, 0xed, 0xf2, 0x4f, 0xfa, 0x24, 0x38, 0x7c, 0xc5, 0x5b, 0xe7, 0xc2, 0x4c,
0x74, 0x0e, 0xe2, 0x8e, 0x74, 0xec, 0x80, 0x2e, 0x56, 0x9f, 0xa1, 0xb8, 0xf2, 0xab, 0x41, 0x71,
0x45, 0xa8, 0xaa, 0x72, 0x42, 0xa8, 0x6a, 0x3c, 0xb0, 0x56, 0xe0, 0xfa, 0xcc, 0x30, 0x5c, 0x2f,
0x00, 0x2b, 0xb3, 0x2f, 0x0b, 0x56, 0xaa, 0x85, 0x60, 0xa5, 0x57, 0x78, 0xd2, 0x6a, 0x32, 0xdd,
0x1f, 0xa8, 0x05, 0x3c, 0xb6, 0xd6, 0x26, 0x81, 0x2d, 0xf0, 0x7f, 0x80, 0x2d, 0xdf, 0xcb, 0x5b,
0x9f, 0xf9, 0x59, 0xdc, 0xe9, 0x95, 0x24, 0x3a, 0xa9, 0xb8, 0x1c, 0x22, 0x3d, 0x72, 0x8c, 0x6e,
0xc2, 0x6c, 0x87, 0xfb, 0x9e, 0x47, 0xc2, 0xf8, 0x74, 0x18, 0x6a, 0x1a, 0xb7, 0xa2, 0xa5, 0x35,
0xc6, 0xf6, 0x18, 0x71, 0xec, 0x84, 0x15, 0x5d, 0x81, 0x8a, 0x70, 0x5d, 0x5e, 0x4f, 0xf5, 0xd5,
0x0b, 0xaa, 0x88, 0x88, 0x2f, 0xe1, 0x97, 0x4c, 0xe8, 0x36, 0xd4, 0xd2, 0x72, 0x8a, 0xeb, 0x75,
0x71, 0xc8, 0x48, 0xb2, 0x98, 0x88, 0x65, 0xec, 0x42, 0xb6, 0x45, 0x03, 0xe2, 0x48, 0xa8, 0x33,
0x3d, 0x2a, 0x7b, 0x37, 0x59, 0x4c, 0x65, 0x53, 0x76, 0xf3, 0x57, 0x0d, 0x2e, 0x65, 0x75, 0x90,
0x14, 0xdc, 0x36, 0x09, 0x71, 0x0b, 0x87, 0xf8, 0xf5, 0x5f, 0x1b, 0x97, 0x61, 0xce, 0x69, 0x13,
0xa7, 0x93, 0xbd, 0x31, 0xa2, 0xe7, 0x6e, 0x8e, 0x6a, 0xfe, 0x5e, 0x82, 0xb9, 0xe1, 0x8d, 0x10,
0x3b, 0x29, 0xd0, 0x42, 0xb2, 0x93, 0x62, 0x8c, 0x76, 0xe1, 0x14, 0xf1, 0x06, 0x34, 0xf0, 0x3d,
0xf1, 0x22, 0x4b, 0x9a, 0xd0, 0xd5, 0xf1, 0xdb, 0x69, 0x6d, 0x28, 0xec, 0xd1, 0x21, 0x18, 0xd2,
0x80, 0x3c, 0x00, 0x86, 0x03, 0xdc, 0x23, 0x21, 0x09, 0x44, 0xa7, 0x29, 0x1f, 0x43, 0xa7, 0x89,
0x3c, 0xd8, 0x4d, 0xd4, 0xda, 0x8a, 0x05, 0xe3, 0x09, 0x2c, 0x8c, 0xb8, 0x54, 0x50, 0xfb, 0x37,
0xd5, 0xda, 0xaf, 0xaf, 0x2e, 0x15, 0x44, 0xa8, 0xa8, 0x51, 0xcf, 0xc6, 0x2f, 0x25, 0xa8, 0x2b,
0xf5, 0x59, 0x98, 0xc6, 0x25, 0x00, 0x29, 0x70, 0x8f, 0x76, 0xe3, 0x4b, 0xbc, 0x66, 0x2b, 0x14,
0xd4, 0x29, 0x48, 0xca, 0xd6, 0xe4, 0x2d, 0xa1, 0x30, 0x23, 0x02, 0x08, 0x4a, 0xd3, 0x3c, 0x6e,
0xba, 0xf1, 0x0c, 0x7d, 0x03, 0x73, 0x07, 0xb4, 0x4b, 0x76, 0x33, 0x47, 0x66, 0xa4, 0x23, 0x3b,
0x93, 0x3b, 0x72, 0x4f, 0xd5, 0x6b, 0xe7, 0xcc, 0x98, 0xef, 0x42, 0x23, 0x7f, 0x5c, 0x85, 0x93,
0xb4, 0x87, 0xdd, 0x34, 0x5b, 0xf1, 0xcc, 0xfc, 0x51, 0x03, 0x34, 0xba, 0x1f, 0xe3, 0x92, 0xde,
0xb9, 0xc5, 0x93, 0x27, 0x7b, 0x74, 0x50, 0x14, 0x0a, 0xda, 0x82, 0x7a, 0x8b, 0xf0, 0x90, 0x7a,
0xd2, 0xe1, 0xb8, 0x89, 0xbc, 0x73, 0xf4, 0xc6, 0xdf, 0xcd, 0x04, 0x6c, 0x55, 0xda, 0xfc, 0x14,
0x2e, 0x1e, 0xc9, 0xad, 0xc0, 0x6f, 0x6d, 0x08, 0x7e, 0x1f, 0x09, 0xda, 0x4d, 0x04, 0x8d, 0x7c,
0x37, 0x32, 0x9f, 0xc2, 0x82, 0xc8, 0xe9, 0x7a, 0x1b, 0x07, 0xe1, 0x09, 0x41, 0xea, 0x3b, 0x50,
0x4b, 0x4d, 0x16, 0xe6, 0xda, 0x80, 0xea, 0x20, 0xf9, 0xf4, 0x11, 0x61, 0xea, 0x74, 0x6e, 0xae,
0x01, 0x52, 0xfd, 0x8d, 0xef, 0x8d, 0x2b, 0x30, 0x4d, 0x43, 0xd2, 0x4b, 0x90, 0xe2, 0xb9, 0x7c,
0xbb, 0x97, 0xec, 0x76, 0xc4, 0xb3, 0xfa, 0xf7, 0x34, 0x2c, 0x64, 0x5d, 0x57, 0xfc, 0xa5, 0x0e,
0x41, 0x3b, 0xd0, 0xd8, 0x8c, 0x3f, 0x3a, 0x26, 0x2f, 0x25, 0xf4, 0xe6, 0x11, 0x5f, 0x17, 0x8c,
0xc5, 0xe2, 0xc5, 0xc8, 0x23, 0x73, 0x0a, 0x7d, 0x0e, 0x73, 0xc3, 0xcf, 0x64, 0x74, 0x49, 0x95,
0x28, 0x7c, 0xb9, 0x1b, 0xe6, 0x51, 0x2c, 0xa9, 0xea, 0xc7, 0x30, 0x9f, 0x7b, 0x33, 0x22, 0x73,
0x18, 0x5b, 0x14, 0xbd, 0xa9, 0x8d, 0xb7, 0x8e, 0xe4, 0x49, 0xb5, 0xdf, 0x81, 0x6a, 0xf2, 0xc6,
0x1a, 0xce, 0x40, 0xee, 0xe5, 0x65, 0x34, 0x86, 0xf5, 0x1d, 0x70, 0x73, 0x0a, 0x7d, 0x18, 0x09,
0x0b, 0x0c, 0x3e, 0x2a, 0xac, 0xbc, 0x2c, 0x8c, 0x33, 0x05, 0x68, 0x5e, 0x86, 0x76, 0x7a, 0x53,
0xf6, 0xff, 0x18, 0x1a, 0xa0, 0xb7, 0x5f, 0x0a, 0x34, 0x19, 0x66, 0x9e, 0x6d, 0x14, 0x5d, 0x98,
0x53, 0xe8, 0x27, 0x0d, 0xce, 0x6c, 0x92, 0x30, 0x7f, 0xd3, 0xa2, 0x6b, 0xc5, 0x46, 0xc6, 0xdc,
0xc8, 0xc6, 0xc3, 0x49, 0x4f, 0xc4, 0xb0, 0x5a, 0x73, 0x0a, 0xed, 0xca, 0xb0, 0xb3, 0xca, 0x46,
0x17, 0x0b, 0x4b, 0x38, 0xcd, 0xde, 0xd2, 0xb8, 0xe5, 0x24, 0xd4, 0x8f, 0xd6, 0xfe, 0x78, 0xbe,
0xa4, 0xfd, 0xf9, 0x7c, 0x49, 0xfb, 0xeb, 0xf9, 0x92, 0xf6, 0xc5, 0x8d, 0x17, 0x7c, 0x8d, 0x57,
0x7e, 0x38, 0xc0, 0x8c, 0x3a, 0x5d, 0x4a, 0xbc, 0x70, 0x7f, 0x46, 0x7e, 0x7b, 0xbf, 0xf1, 0x6f,
0x00, 0x00, 0x00, 0xff, 0xff, 0x30, 0x2a, 0x03, 0x20, 0x57, 0x18, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -1975,6 +2024,44 @@ func (m *ManifestRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.HelmOptions != nil {
{
size, err := m.HelmOptions.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintRepository(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0xaa
}
if len(m.EnabledSourceTypes) > 0 {
for k := range m.EnabledSourceTypes {
v := m.EnabledSourceTypes[k]
baseI := i
i--
if v {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x10
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarintRepository(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarintRepository(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0xa2
}
}
if len(m.TrackingMethod) > 0 {
i -= len(m.TrackingMethod)
copy(dAtA[i:], m.TrackingMethod)
@@ -2499,6 +2586,28 @@ func (m *ListAppsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.EnabledSourceTypes) > 0 {
for k := range m.EnabledSourceTypes {
v := m.EnabledSourceTypes[k]
baseI := i
i--
if v {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x10
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarintRepository(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarintRepository(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0x1a
}
}
if len(m.Revision) > 0 {
i -= len(m.Revision)
copy(dAtA[i:], m.Revision)
@@ -2591,6 +2700,40 @@ func (m *RepoServerAppDetailsQuery) MarshalToSizedBuffer(dAtA []byte) (int, erro
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.HelmOptions != nil {
{
size, err := m.HelmOptions.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintRepository(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x52
}
if len(m.EnabledSourceTypes) > 0 {
for k := range m.EnabledSourceTypes {
v := m.EnabledSourceTypes[k]
baseI := i
i--
if v {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x10
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarintRepository(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarintRepository(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0x4a
}
}
if len(m.TrackingMethod) > 0 {
i -= len(m.TrackingMethod)
copy(dAtA[i:], m.TrackingMethod)
@@ -3334,6 +3477,18 @@ func (m *ManifestRequest) Size() (n int) {
if l > 0 {
n += 2 + l + sovRepository(uint64(l))
}
if len(m.EnabledSourceTypes) > 0 {
for k, v := range m.EnabledSourceTypes {
_ = k
_ = v
mapEntrySize := 1 + len(k) + sovRepository(uint64(len(k))) + 1 + 1
n += mapEntrySize + 2 + sovRepository(uint64(mapEntrySize))
}
}
if m.HelmOptions != nil {
l = m.HelmOptions.Size()
n += 2 + l + sovRepository(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -3507,6 +3662,14 @@ func (m *ListAppsRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
if len(m.EnabledSourceTypes) > 0 {
for k, v := range m.EnabledSourceTypes {
_ = k
_ = v
mapEntrySize := 1 + len(k) + sovRepository(uint64(len(k))) + 1 + 1
n += mapEntrySize + 1 + sovRepository(uint64(mapEntrySize))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -3571,6 +3734,18 @@ func (m *RepoServerAppDetailsQuery) Size() (n int) {
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
if len(m.EnabledSourceTypes) > 0 {
for k, v := range m.EnabledSourceTypes {
_ = k
_ = v
mapEntrySize := 1 + len(k) + sovRepository(uint64(len(k))) + 1 + 1
n += mapEntrySize + 1 + sovRepository(uint64(mapEntrySize))
}
}
if m.HelmOptions != nil {
l = m.HelmOptions.Size()
n += 1 + l + sovRepository(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -4364,6 +4539,157 @@ func (m *ManifestRequest) Unmarshal(dAtA []byte) error {
}
m.TrackingMethod = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 20:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EnabledSourceTypes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.EnabledSourceTypes == nil {
m.EnabledSourceTypes = make(map[string]bool)
}
var mapkey string
var mapvalue bool
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthRepository
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLengthRepository
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var mapvaluetemp int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapvaluetemp |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
mapvalue = bool(mapvaluetemp != 0)
} else {
iNdEx = entryPreIndex
skippy, err := skipRepository(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthRepository
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.EnabledSourceTypes[mapkey] = mapvalue
iNdEx = postIndex
case 21:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field HelmOptions", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.HelmOptions == nil {
m.HelmOptions = &v1alpha1.HelmOptions{}
}
if err := m.HelmOptions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])
@@ -5356,6 +5682,121 @@ func (m *ListAppsRequest) Unmarshal(dAtA []byte) error {
}
m.Revision = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EnabledSourceTypes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.EnabledSourceTypes == nil {
m.EnabledSourceTypes = make(map[string]bool)
}
var mapkey string
var mapvalue bool
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthRepository
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLengthRepository
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var mapvaluetemp int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapvaluetemp |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
mapvalue = bool(mapvaluetemp != 0)
} else {
iNdEx = entryPreIndex
skippy, err := skipRepository(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthRepository
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.EnabledSourceTypes[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])
@@ -5831,6 +6272,157 @@ func (m *RepoServerAppDetailsQuery) Unmarshal(dAtA []byte) error {
}
m.TrackingMethod = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EnabledSourceTypes", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.EnabledSourceTypes == nil {
m.EnabledSourceTypes = make(map[string]bool)
}
var mapkey string
var mapvalue bool
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthRepository
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLengthRepository
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var mapvaluetemp int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapvaluetemp |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
mapvalue = bool(mapvaluetemp != 0)
} else {
iNdEx = entryPreIndex
skippy, err := skipRepository(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthRepository
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.EnabledSourceTypes[mapkey] = mapvalue
iNdEx = postIndex
case 10:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field HelmOptions", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRepository
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.HelmOptions == nil {
m.HelmOptions = &v1alpha1.HelmOptions{}
}
if err := m.HelmOptions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])

View File

@@ -0,0 +1,646 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: reposerver/askpass/askpass.proto
package askpass
import (
context "context"
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type CredentialsRequest struct {
Nonce string `protobuf:"bytes,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CredentialsRequest) Reset() { *m = CredentialsRequest{} }
func (m *CredentialsRequest) String() string { return proto.CompactTextString(m) }
func (*CredentialsRequest) ProtoMessage() {}
func (*CredentialsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_099f282cab154dba, []int{0}
}
func (m *CredentialsRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CredentialsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_CredentialsRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *CredentialsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CredentialsRequest.Merge(m, src)
}
func (m *CredentialsRequest) XXX_Size() int {
return m.Size()
}
func (m *CredentialsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CredentialsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CredentialsRequest proto.InternalMessageInfo
func (m *CredentialsRequest) GetNonce() string {
if m != nil {
return m.Nonce
}
return ""
}
type CredentialsResponse struct {
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CredentialsResponse) Reset() { *m = CredentialsResponse{} }
func (m *CredentialsResponse) String() string { return proto.CompactTextString(m) }
func (*CredentialsResponse) ProtoMessage() {}
func (*CredentialsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_099f282cab154dba, []int{1}
}
func (m *CredentialsResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CredentialsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_CredentialsResponse.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *CredentialsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CredentialsResponse.Merge(m, src)
}
func (m *CredentialsResponse) XXX_Size() int {
return m.Size()
}
func (m *CredentialsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CredentialsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CredentialsResponse proto.InternalMessageInfo
func (m *CredentialsResponse) GetUsername() string {
if m != nil {
return m.Username
}
return ""
}
func (m *CredentialsResponse) GetPassword() string {
if m != nil {
return m.Password
}
return ""
}
func init() {
proto.RegisterType((*CredentialsRequest)(nil), "askpass.CredentialsRequest")
proto.RegisterType((*CredentialsResponse)(nil), "askpass.CredentialsResponse")
}
func init() { proto.RegisterFile("reposerver/askpass/askpass.proto", fileDescriptor_099f282cab154dba) }
var fileDescriptor_099f282cab154dba = []byte{
// 231 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x28, 0x4a, 0x2d, 0xc8,
0x2f, 0x4e, 0x2d, 0x2a, 0x4b, 0x2d, 0xd2, 0x4f, 0x2c, 0xce, 0x2e, 0x48, 0x2c, 0x2e, 0x86, 0xd1,
0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xec, 0x50, 0xae, 0x92, 0x16, 0x97, 0x90, 0x73, 0x51,
0x6a, 0x4a, 0x6a, 0x5e, 0x49, 0x66, 0x62, 0x4e, 0x71, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89,
0x90, 0x08, 0x17, 0x6b, 0x5e, 0x7e, 0x5e, 0x72, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10,
0x84, 0xa3, 0xe4, 0xcb, 0x25, 0x8c, 0xa2, 0xb6, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0x48, 0x8a,
0x8b, 0xa3, 0xb4, 0x38, 0xb5, 0x28, 0x2f, 0x31, 0x17, 0xa6, 0x1e, 0xce, 0x07, 0xc9, 0x81, 0xac,
0x29, 0xcf, 0x2f, 0x4a, 0x91, 0x60, 0x82, 0xc8, 0xc1, 0xf8, 0x46, 0xf1, 0x5c, 0x7c, 0x8e, 0xc5,
0xd9, 0x01, 0x89, 0xc5, 0xc5, 0xc1, 0xa9, 0x45, 0x65, 0x99, 0xc9, 0xa9, 0x42, 0xbe, 0x5c, 0x7c,
0xee, 0xa9, 0x25, 0x48, 0x76, 0x08, 0x49, 0xeb, 0xc1, 0xdc, 0x8d, 0xe9, 0x4a, 0x29, 0x19, 0xec,
0x92, 0x10, 0x67, 0x29, 0x31, 0x38, 0xd9, 0x9f, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3,
0x83, 0x47, 0x72, 0x8c, 0x51, 0x86, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9,
0xfa, 0x89, 0x45, 0xe9, 0xf9, 0x05, 0x45, 0xf9, 0x59, 0x60, 0x86, 0x6e, 0x72, 0x8a, 0x7e, 0x99,
0x91, 0x3e, 0x66, 0x98, 0x25, 0xb1, 0x81, 0x03, 0xcb, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x5a,
0x1e, 0xa9, 0xaf, 0x50, 0x01, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// AskPassServiceClient is the client API for AskPassService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AskPassServiceClient interface {
GetCredentials(ctx context.Context, in *CredentialsRequest, opts ...grpc.CallOption) (*CredentialsResponse, error)
}
type askPassServiceClient struct {
cc *grpc.ClientConn
}
func NewAskPassServiceClient(cc *grpc.ClientConn) AskPassServiceClient {
return &askPassServiceClient{cc}
}
func (c *askPassServiceClient) GetCredentials(ctx context.Context, in *CredentialsRequest, opts ...grpc.CallOption) (*CredentialsResponse, error) {
out := new(CredentialsResponse)
err := c.cc.Invoke(ctx, "/askpass.AskPassService/GetCredentials", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AskPassServiceServer is the server API for AskPassService service.
type AskPassServiceServer interface {
GetCredentials(context.Context, *CredentialsRequest) (*CredentialsResponse, error)
}
// UnimplementedAskPassServiceServer can be embedded to have forward compatible implementations.
type UnimplementedAskPassServiceServer struct {
}
func (*UnimplementedAskPassServiceServer) GetCredentials(ctx context.Context, req *CredentialsRequest) (*CredentialsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetCredentials not implemented")
}
func RegisterAskPassServiceServer(s *grpc.Server, srv AskPassServiceServer) {
s.RegisterService(&_AskPassService_serviceDesc, srv)
}
func _AskPassService_GetCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CredentialsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AskPassServiceServer).GetCredentials(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/askpass.AskPassService/GetCredentials",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AskPassServiceServer).GetCredentials(ctx, req.(*CredentialsRequest))
}
return interceptor(ctx, in, info, handler)
}
var _AskPassService_serviceDesc = grpc.ServiceDesc{
ServiceName: "askpass.AskPassService",
HandlerType: (*AskPassServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetCredentials",
Handler: _AskPassService_GetCredentials_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "reposerver/askpass/askpass.proto",
}
func (m *CredentialsRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *CredentialsRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *CredentialsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Nonce) > 0 {
i -= len(m.Nonce)
copy(dAtA[i:], m.Nonce)
i = encodeVarintAskpass(dAtA, i, uint64(len(m.Nonce)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *CredentialsResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *CredentialsResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *CredentialsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Password) > 0 {
i -= len(m.Password)
copy(dAtA[i:], m.Password)
i = encodeVarintAskpass(dAtA, i, uint64(len(m.Password)))
i--
dAtA[i] = 0x12
}
if len(m.Username) > 0 {
i -= len(m.Username)
copy(dAtA[i:], m.Username)
i = encodeVarintAskpass(dAtA, i, uint64(len(m.Username)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintAskpass(dAtA []byte, offset int, v uint64) int {
offset -= sovAskpass(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *CredentialsRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Nonce)
if l > 0 {
n += 1 + l + sovAskpass(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *CredentialsResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Username)
if l > 0 {
n += 1 + l + sovAskpass(uint64(l))
}
l = len(m.Password)
if l > 0 {
n += 1 + l + sovAskpass(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovAskpass(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozAskpass(x uint64) (n int) {
return sovAskpass(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *CredentialsRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAskpass
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: CredentialsRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CredentialsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Nonce", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAskpass
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthAskpass
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthAskpass
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Nonce = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAskpass(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthAskpass
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *CredentialsResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAskpass
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: CredentialsResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CredentialsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAskpass
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthAskpass
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthAskpass
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Username = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAskpass
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthAskpass
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthAskpass
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Password = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAskpass(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthAskpass
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipAskpass(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowAskpass
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowAskpass
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowAskpass
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthAskpass
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupAskpass
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthAskpass
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthAskpass = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowAskpass = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupAskpass = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,20 @@
syntax = "proto3";
option go_package = "github.com/argoproj/argo-cd/v2/reposerver/askpass";
package askpass;
message CredentialsRequest {
string nonce = 1;
}
message CredentialsResponse {
string username = 1;
string password = 2;
}
// AskPassService
service AskPassService {
rpc GetCredentials(CredentialsRequest) returns (CredentialsResponse) {
}
}

View File

@@ -0,0 +1,10 @@
package askpass
var (
SocketPath = "/tmp/reposerver-ask-pass.sock"
)
type Creds struct {
Username string
Password string
}

View File

@@ -0,0 +1,90 @@
package askpass
import (
"context"
"net"
"os"
"sync"
"github.com/google/uuid"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/argoproj/argo-cd/v2/util/git"
"github.com/argoproj/argo-cd/v2/util/io"
)
type Server interface {
git.CredsStore
AskPassServiceServer
Run(path string) error
}
type server struct {
lock sync.Mutex
creds map[string]Creds
}
// NewServer returns a new server
func NewServer() *server {
return &server{
creds: make(map[string]Creds),
}
}
func (s *server) GetCredentials(_ context.Context, q *CredentialsRequest) (*CredentialsResponse, error) {
if q.Nonce == "" {
return nil, status.Errorf(codes.InvalidArgument, "missing nonce")
}
creds, ok := s.getCreds(q.Nonce)
if !ok {
return nil, status.Errorf(codes.NotFound, "unknown nonce")
}
return &CredentialsResponse{Username: creds.Username, Password: creds.Password}, nil
}
func (s *server) Start(path string) (io.Closer, error) {
_ = os.Remove(path)
listener, err := net.Listen("unix", path)
if err != nil {
return nil, err
}
server := grpc.NewServer()
RegisterAskPassServiceServer(server, s)
go func() {
_ = server.Serve(listener)
}()
return io.NewCloser(listener.Close), nil
}
func (s *server) Run(path string) error {
_, err := s.Start(path)
return err
}
// Add adds a new credential to the server and returns associated id
func (s *server) Add(username string, password string) string {
s.lock.Lock()
defer s.lock.Unlock()
id := uuid.New().String()
s.creds[id] = Creds{
Username: username,
Password: password,
}
return id
}
// Remove removes the credential with the given id
func (s *server) Remove(id string) {
s.lock.Lock()
defer s.lock.Unlock()
delete(s.creds, id)
}
func (s *server) getCreds(id string) (*Creds, bool) {
s.lock.Lock()
defer s.lock.Unlock()
creds, ok := s.creds[id]
return &creds, ok
}

View File

@@ -0,0 +1,25 @@
package askpass
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAdd(t *testing.T) {
s := NewServer()
nonce := s.Add("foo", "bar")
assert.Equal(t, "foo", s.creds[nonce].Username)
assert.Equal(t, "bar", s.creds[nonce].Password)
}
func TestRemove(t *testing.T) {
s := NewServer()
s.creds["some-id"] = Creds{Username: "foo"}
s.Remove("some-id")
_, ok := s.creds["some-id"]
assert.False(t, ok)
}

View File

@@ -17,7 +17,7 @@ type repositoryLock struct {
}
// Lock acquires lock unless lock is already acquired with the same commit and allowConcurrent is set to true
func (r *repositoryLock) Lock(path string, revision string, allowConcurrent bool, init func() error) (io.Closer, error) {
func (r *repositoryLock) Lock(path string, revision string, allowConcurrent bool, init func() (io.Closer, error)) (io.Closer, error) {
r.lock.Lock()
state, ok := r.stateByKey[path]
if !ok {
@@ -30,26 +30,30 @@ func (r *repositoryLock) Lock(path string, revision string, allowConcurrent bool
state.cond.L.Lock()
notify := false
state.processCount--
var err error
if state.processCount == 0 {
notify = true
state.revision = ""
err = state.initCloser.Close()
}
state.cond.L.Unlock()
if notify {
state.cond.Broadcast()
}
return nil
return err
})
for {
state.cond.L.Lock()
if state.revision == "" {
// no in progress operation for that repo. Go ahead.
if err := init(); err != nil {
initCloser, err := init()
if err != nil {
state.cond.L.Unlock()
return nil, err
}
state.initCloser = initCloser
state.revision = revision
state.processCount = 1
state.allowConcurrent = allowConcurrent
@@ -71,6 +75,7 @@ func (r *repositoryLock) Lock(path string, revision string, allowConcurrent bool
type repositoryState struct {
cond *sync.Cond
revision string
initCloser io.Closer
processCount int
allowConcurrent bool
}

View File

@@ -26,10 +26,10 @@ func lockQuickly(action func() (io.Closer, error)) (io.Closer, bool) {
}
}
func numberOfInits(initializedTimes *int) func() error {
return func() error {
func numberOfInits(initializedTimes *int) func() (io.Closer, error) {
return func() (io.Closer, error) {
*initializedTimes++
return nil
return util.NopCloser, nil
}
}
@@ -120,8 +120,8 @@ func TestLock_FailedInitialization(t *testing.T) {
lock := NewRepositoryLock()
closer1, done := lockQuickly(func() (io.Closer, error) {
return lock.Lock("myRepo", "1", true, func() error {
return errors.New("failed")
return lock.Lock("myRepo", "1", true, func() (io.Closer, error) {
return util.NopCloser, errors.New("failed")
})
})
@@ -132,8 +132,8 @@ func TestLock_FailedInitialization(t *testing.T) {
assert.Nil(t, closer1)
closer2, done := lockQuickly(func() (io.Closer, error) {
return lock.Lock("myRepo", "1", true, func() error {
return nil
return lock.Lock("myRepo", "1", true, func() (io.Closer, error) {
return util.NopCloser, nil
})
})

View File

@@ -6,6 +6,8 @@ import (
"encoding/json"
"errors"
"fmt"
goio "io"
"io/fs"
"io/ioutil"
"net/url"
"os"
@@ -16,10 +18,6 @@ import (
"strings"
"time"
"github.com/google/go-jsonnet"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/Masterminds/semver/v3"
"github.com/TomOnTime/utfutil"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
@@ -27,6 +25,9 @@ import (
"github.com/argoproj/pkg/sync"
jsonpatch "github.com/evanphx/json-patch"
"github.com/ghodss/yaml"
gogit "github.com/go-git/go-git/v5"
"github.com/google/go-jsonnet"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"golang.org/x/sync/semaphore"
"google.golang.org/grpc/codes"
@@ -44,15 +45,17 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/metrics"
"github.com/argoproj/argo-cd/v2/util/app/discovery"
argopath "github.com/argoproj/argo-cd/v2/util/app/path"
"github.com/argoproj/argo-cd/v2/util/argo"
executil "github.com/argoproj/argo-cd/v2/util/exec"
"github.com/argoproj/argo-cd/v2/util/git"
"github.com/argoproj/argo-cd/v2/util/glob"
"github.com/argoproj/argo-cd/v2/util/gpg"
"github.com/argoproj/argo-cd/v2/util/grpc"
"github.com/argoproj/argo-cd/v2/util/helm"
"github.com/argoproj/argo-cd/v2/util/io"
pathutil "github.com/argoproj/argo-cd/v2/util/io/path"
"github.com/argoproj/argo-cd/v2/util/ksonnet"
"github.com/argoproj/argo-cd/v2/util/kustomize"
"github.com/argoproj/argo-cd/v2/util/security"
"github.com/argoproj/argo-cd/v2/util/text"
)
@@ -68,12 +71,17 @@ const (
// Service implements ManifestService interface
type Service struct {
gitCredsStore git.CredsStore
rootDir string
gitRepoPaths *io.TempPaths
chartPaths *io.TempPaths
gitRepoInitializer func(rootPath string) goio.Closer
repoLock *repositoryLock
cache *reposervercache.Cache
parallelismLimitSemaphore *semaphore.Weighted
metricsServer *metrics.MetricsServer
resourceTracking argo.ResourceTracking
newGitClient func(rawRepoURL string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (git.Client, error)
newGitClient func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (git.Client, error)
newHelmClient func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client
initConstants RepoServerInitConstants
// now is usually just time.Now, but may be replaced by unit tests for testing purposes
@@ -85,10 +93,11 @@ type RepoServerInitConstants struct {
PauseGenerationAfterFailedGenerationAttempts int
PauseGenerationOnFailureForMinutes int
PauseGenerationOnFailureForRequests int
SubmoduleEnabled bool
}
// NewService returns a new instance of the Manifest service
func NewService(metricsServer *metrics.MetricsServer, cache *reposervercache.Cache, initConstants RepoServerInitConstants, resourceTracking argo.ResourceTracking) *Service {
func NewService(metricsServer *metrics.MetricsServer, cache *reposervercache.Cache, initConstants RepoServerInitConstants, resourceTracking argo.ResourceTracking, gitCredsStore git.CredsStore, rootDir string) *Service {
var parallelismLimitSemaphore *semaphore.Weighted
if initConstants.ParallelismLimit > 0 {
parallelismLimitSemaphore = semaphore.NewWeighted(initConstants.ParallelismLimit)
@@ -99,16 +108,56 @@ func NewService(metricsServer *metrics.MetricsServer, cache *reposervercache.Cac
repoLock: repoLock,
cache: cache,
metricsServer: metricsServer,
newGitClient: git.NewClient,
newGitClient: git.NewClientExt,
resourceTracking: resourceTracking,
newHelmClient: func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client {
return helm.NewClientWithLock(repoURL, creds, sync.NewKeyLock(), enableOci, proxy, opts...)
},
initConstants: initConstants,
now: time.Now,
initConstants: initConstants,
now: time.Now,
gitCredsStore: gitCredsStore,
gitRepoPaths: io.NewTempPaths(rootDir),
chartPaths: io.NewTempPaths(rootDir),
gitRepoInitializer: directoryPermissionInitializer,
rootDir: rootDir,
}
}
func (s *Service) Init() error {
_, err := os.Stat(s.rootDir)
if os.IsNotExist(err) {
return os.MkdirAll(s.rootDir, 0300)
}
if err == nil {
// give itself read permissions to list previously written directories
err = os.Chmod(s.rootDir, 0700)
}
var files []fs.FileInfo
if err == nil {
files, err = ioutil.ReadDir(s.rootDir)
}
if err != nil {
log.Warnf("Failed to restore cloned repositories paths: %v", err)
return nil
}
for _, file := range files {
if !file.IsDir() {
continue
}
fullPath := filepath.Join(s.rootDir, file.Name())
closer := s.gitRepoInitializer(fullPath)
if repo, err := gogit.PlainOpen(fullPath); err == nil {
if remotes, err := repo.Remotes(); err == nil && len(remotes) > 0 && len(remotes[0].Config().URLs) > 0 {
s.gitRepoPaths.Add(git.NormalizeGitURL(remotes[0].Config().URLs[0]), fullPath)
}
}
io.Close(closer)
}
// remove read permissions since no-one should be able to list the directories
return os.Chmod(s.rootDir, 0300)
}
// List a subset of the refs (currently, branches and tags) of a git repo
func (s *Service) ListRefs(ctx context.Context, q *apiclient.ListRefsRequest) (*apiclient.Refs, error) {
gitClient, err := s.newClient(q.Repo)
@@ -146,8 +195,8 @@ func (s *Service) ListApps(ctx context.Context, q *apiclient.ListAppsRequest) (*
s.metricsServer.IncPendingRepoRequest(q.Repo.Repo)
defer s.metricsServer.DecPendingRepoRequest(q.Repo.Repo)
closer, err := s.repoLock.Lock(gitClient.Root(), commitSHA, true, func() error {
return checkoutRevision(gitClient, commitSHA)
closer, err := s.repoLock.Lock(gitClient.Root(), commitSHA, true, func() (goio.Closer, error) {
return s.checkoutRevision(gitClient, commitSHA, s.initConstants.SubmoduleEnabled)
})
if err != nil {
@@ -155,7 +204,7 @@ func (s *Service) ListApps(ctx context.Context, q *apiclient.ListAppsRequest) (*
}
defer io.Close(closer)
apps, err := discovery.Discover(ctx, gitClient.Root())
apps, err := discovery.Discover(ctx, gitClient.Root(), q.EnabledSourceTypes)
if err != nil {
return nil, err
}
@@ -205,6 +254,11 @@ func (s *Service) runRepoOperation(
operation func(repoRoot, commitSHA, cacheKey string, ctxSrc operationContextSrc) error,
settings operationSettings) error {
if sanitizer, ok := grpc.SanitizerFromContext(ctx); ok {
// make sure randomized path replaced with '.' in the error message
sanitizer.AddRegexReplacement(regexp.MustCompile(`(`+s.rootDir+`/.*?)/`), ".")
}
var gitClient git.Client
var helmClient helm.Client
var err error
@@ -258,8 +312,8 @@ func (s *Service) runRepoOperation(
return &operationContext{chartPath, ""}, nil
})
} else {
closer, err := s.repoLock.Lock(gitClient.Root(), revision, settings.allowConcurrent, func() error {
return checkoutRevision(gitClient, revision)
closer, err := s.repoLock.Lock(gitClient.Root(), revision, settings.allowConcurrent, func() (goio.Closer, error) {
return s.checkoutRevision(gitClient, revision, s.initConstants.SubmoduleEnabled)
})
if err != nil {
@@ -329,7 +383,7 @@ func (s *Service) runManifestGen(ctx context.Context, repoRoot, commitSHA, cache
var manifestGenResult *apiclient.ManifestResponse
opContext, err := opContextSrc()
if err == nil {
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false)
manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore)
}
if err != nil {
@@ -568,7 +622,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
APIVersions: q.ApiVersions,
Set: map[string]string{},
SetString: map[string]string{},
SetFile: map[string]string{},
SetFile: map[string]pathutil.ResolvedFilePath{},
}
appHelm := q.ApplicationSource.Helm
@@ -583,32 +637,15 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
}
for _, val := range appHelm.ValueFiles {
// If val is not a URL, run it against the directory enforcer. If it is a URL, use it without checking
// If val does not exist, warn. If IgnoreMissingValueFiles, do not append, else let Helm handle it.
if _, err := url.ParseRequestURI(val); err != nil {
// Ensure that the repo root provided is absolute
absRepoPath, err := filepath.Abs(repoRoot)
if err != nil {
return nil, err
}
// This will resolve val to an absolute path (or an URL)
path, isRemote, err := pathutil.ResolveFilePath(appPath, repoRoot, val, q.GetValuesFileSchemes())
if err != nil {
return nil, err
}
// If the path to the file is relative, join it with the current working directory (appPath)
path := val
if !filepath.IsAbs(path) {
absWorkDir, err := filepath.Abs(appPath)
if err != nil {
return nil, err
}
path = filepath.Join(absWorkDir, path)
}
_, err = security.EnforceToCurrentRoot(absRepoPath, path)
if err != nil {
return nil, err
}
_, err = os.Stat(path)
if !isRemote {
_, err = os.Stat(string(path))
if os.IsNotExist(err) {
if appHelm.IgnoreMissingValueFiles {
log.Debugf(" %s values file does not exist", path)
@@ -616,22 +653,22 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
}
}
}
templateOpts.Values = append(templateOpts.Values, val)
templateOpts.Values = append(templateOpts.Values, path)
}
if appHelm.Values != "" {
file, err := ioutil.TempFile("", "values-*.yaml")
rand, err := uuid.NewRandom()
if err != nil {
return nil, err
}
p := file.Name()
p := path.Join(os.TempDir(), rand.String())
defer func() { _ = os.RemoveAll(p) }()
err = ioutil.WriteFile(p, []byte(appHelm.Values), 0644)
if err != nil {
return nil, err
}
defer file.Close()
templateOpts.Values = append(templateOpts.Values, p)
templateOpts.Values = append(templateOpts.Values, pathutil.ResolvedFilePath(p))
}
for _, p := range appHelm.Parameters {
@@ -642,7 +679,11 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
}
}
for _, p := range appHelm.FileParameters {
templateOpts.SetFile[p.Name] = p.Path
resolvedPath, _, err := pathutil.ResolveFilePath(appPath, repoRoot, env.Envsubst(p.Path), q.GetValuesFileSchemes())
if err != nil {
return nil, err
}
templateOpts.SetFile[p.Name] = resolvedPath
}
passCredentials = appHelm.PassCredentials
templateOpts.SkipCrds = appHelm.SkipCrds
@@ -656,9 +697,6 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
for i, j := range templateOpts.SetString {
templateOpts.SetString[i] = env.Envsubst(j)
}
for i, j := range templateOpts.SetFile {
templateOpts.SetFile[i] = env.Envsubst(j)
}
repos, err := getHelmDependencyRepos(appPath)
if err != nil {
@@ -731,12 +769,12 @@ func getRepoCredential(repoCredentials []*v1alpha1.RepoCreds, repoURL string) *v
}
// GenerateManifests generates manifests from a path
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool) (*apiclient.ManifestResponse, error) {
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore) (*apiclient.ManifestResponse, error) {
var targetObjs []*unstructured.Unstructured
var dest *v1alpha1.ApplicationDestination
resourceTracking := argo.NewResourceTracking()
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName)
appSourceType, err := GetAppSourceType(ctx, q.ApplicationSource, appPath, q.AppName, q.EnabledSourceTypes)
if err != nil {
return nil, err
}
@@ -756,22 +794,15 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
if q.KustomizeOptions != nil {
kustomizeBinary = q.KustomizeOptions.BinaryPath
}
k := kustomize.NewKustomizeApp(appPath, q.Repo.GetGitCreds(), repoURL, kustomizeBinary)
k := kustomize.NewKustomizeApp(appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary)
targetObjs, _, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env)
case v1alpha1.ApplicationSourceTypePlugin:
if q.ApplicationSource.Plugin != nil && q.ApplicationSource.Plugin.Name != "" {
targetObjs, err = runConfigManagementPlugin(appPath, repoRoot, env, q, q.Repo.GetGitCreds())
targetObjs, err = runConfigManagementPlugin(appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore))
} else {
var cmpManifests []string
var cmpErr error
cmpManifests, cmpErr = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds())
if cmpErr == nil {
return &apiclient.ManifestResponse{
Manifests: cmpManifests,
SourceType: string(appSourceType),
}, nil
} else {
err = fmt.Errorf("plugin sidecar failed. %s", cmpErr.Error())
targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, env, q, q.Repo.GetGitCreds(gitCredsStore))
if err != nil {
err = fmt.Errorf("plugin sidecar failed. %s", err.Error())
}
}
case v1alpha1.ApplicationSourceTypeDirectory:
@@ -779,7 +810,7 @@ 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)
targetObjs, err = findManifests(appPath, repoRoot, env, *directory, q.EnabledSourceTypes)
}
if err != nil {
return nil, err
@@ -902,7 +933,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) (v1alpha1.ApplicationSourceType, error) {
func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, path, appName string, enableGenerateManifests map[string]bool) (v1alpha1.ApplicationSourceType, error) {
err := mergeSourceParameters(source, path, appName)
if err != nil {
return "", fmt.Errorf("error while parsing source parameters: %v", err)
@@ -913,9 +944,13 @@ func GetAppSourceType(ctx context.Context, source *v1alpha1.ApplicationSource, p
return "", err
}
if appSourceType != nil {
if !discovery.IsManifestGenerationEnabled(*appSourceType, enableGenerateManifests) {
log.Debugf("Manifest generation is disabled for '%s'. Assuming plain YAML manifest.", *appSourceType)
return v1alpha1.ApplicationSourceTypeDirectory, nil
}
return *appSourceType, nil
}
appType, err := discovery.AppType(ctx, path)
appType, err := discovery.AppType(ctx, path, enableGenerateManifests)
if err != nil {
return "", err
}
@@ -977,7 +1012,7 @@ func ksShow(appLabelKey, appPath string, ksonnetOpts *v1alpha1.ApplicationSource
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) ([]*unstructured.Unstructured, error) {
func findManifests(appPath string, repoRoot string, env *v1alpha1.Env, directory v1alpha1.ApplicationSourceDirectory, enabledManifestGeneration map[string]bool) ([]*unstructured.Unstructured, error) {
var objs []*unstructured.Unstructured
err := filepath.Walk(appPath, func(path string, f os.FileInfo, err error) error {
if err != nil {
@@ -1008,6 +1043,9 @@ func findManifests(appPath string, repoRoot string, env *v1alpha1.Env, directory
}
if strings.HasSuffix(f.Name(), ".jsonnet") {
if !discovery.IsManifestGenerationEnabled(v1alpha1.ApplicationSourceTypeDirectory, enabledManifestGeneration) {
return nil
}
vm, err := makeJsonnetVm(appPath, repoRoot, directory.Jsonnet, env)
if err != nil {
return err
@@ -1098,11 +1136,11 @@ func makeJsonnetVm(appPath string, repoRoot string, sourceJsonnet v1alpha1.Appli
// Jsonnet Imports relative to the repository path
jpaths := []string{appPath}
for _, p := range sourceJsonnet.Libs {
jpath := path.Join(repoRoot, p)
if !strings.HasPrefix(jpath, repoRoot) {
return nil, status.Errorf(codes.FailedPrecondition, "%s: referenced library points outside the repository", p)
jpath, _, err := pathutil.ResolveFilePath(appPath, repoRoot, p, nil)
if err != nil {
return nil, err
}
jpaths = append(jpaths, jpath)
jpaths = append(jpaths, string(jpath))
}
vm.Importer(&jsonnet.FileImporter{
@@ -1200,7 +1238,7 @@ func getPluginEnvs(envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds gi
return env, nil
}
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds) ([]string, error) {
func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds) ([]*unstructured.Unstructured, error) {
// detect config management plugin server (sidecar)
conn, cmpClient, err := discovery.DetectConfigManagementPlugin(ctx, appPath)
if err != nil {
@@ -1234,7 +1272,15 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath st
if err != nil {
return nil, err
}
return cmpManifests.Manifests, nil
var manifests []*unstructured.Unstructured
for _, manifestString := range cmpManifests.Manifests {
manifestObjs, err := kube.SplitYAML([]byte(manifestString))
if err != nil {
return nil, fmt.Errorf("failed to convert CMP manifests to unstructured objects: %s", err.Error())
}
manifests = append(manifests, manifestObjs...)
}
return manifests, nil
}
func toEnvEntry(envVars []string) []*pluginclient.EnvEntry {
@@ -1259,7 +1305,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
return err
}
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName)
appSourceType, err := GetAppSourceType(ctx, q.Source, opContext.appPath, q.AppName, q.EnabledSourceTypes)
if err != nil {
return err
}
@@ -1272,11 +1318,11 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD
return err
}
case v1alpha1.ApplicationSourceTypeHelm:
if err := populateHelmAppDetails(res, opContext.appPath, q); err != nil {
if err := populateHelmAppDetails(res, opContext.appPath, repoRoot, q); err != nil {
return err
}
case v1alpha1.ApplicationSourceTypeKustomize:
if err := populateKustomizeAppDetails(res, q, opContext.appPath, commitSHA); err != nil {
if err := populateKustomizeAppDetails(res, q, opContext.appPath, commitSHA, s.gitCredsStore); err != nil {
return err
}
}
@@ -1334,7 +1380,7 @@ func populateKsonnetAppDetails(res *apiclient.RepoAppDetailsResponse, appPath st
return nil
}
func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, q *apiclient.RepoServerAppDetailsQuery) error {
func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery) error {
var selectedValueFiles []string
if q.Source.Helm != nil {
@@ -1368,7 +1414,16 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin
if err := loadFileIntoIfExists(filepath.Join(appPath, "values.yaml"), &res.Helm.Values); err != nil {
return err
}
params, err := h.GetParameters(selectedValueFiles)
var resolvedSelectedValueFiles []pathutil.ResolvedFilePath
// drop not allowed values files
for _, file := range selectedValueFiles {
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)
}
}
params, err := h.GetParameters(resolvedSelectedValueFiles)
if err != nil {
return err
}
@@ -1423,13 +1478,13 @@ func findHelmValueFilesInPath(path string) ([]string, error) {
return result, nil
}
func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apiclient.RepoServerAppDetailsQuery, appPath string, reversion string) error {
func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apiclient.RepoServerAppDetailsQuery, appPath string, reversion string, credsStore git.CredsStore) error {
res.Kustomize = &apiclient.KustomizeAppSpec{}
kustomizeBinary := ""
if q.KustomizeOptions != nil {
kustomizeBinary = q.KustomizeOptions.BinaryPath
}
k := kustomize.NewKustomizeApp(appPath, q.Repo.GetGitCreds(), q.Repo.Repo, kustomizeBinary)
k := kustomize.NewKustomizeApp(appPath, q.Repo.GetGitCreds(credsStore), q.Repo.Repo, kustomizeBinary)
fakeManifestRequest := apiclient.ManifestRequest{
AppName: q.AppName,
Namespace: "", // FIXME: omit it for now
@@ -1481,8 +1536,8 @@ func (s *Service) GetRevisionMetadata(ctx context.Context, q *apiclient.RepoServ
s.metricsServer.IncPendingRepoRequest(q.Repo.Repo)
defer s.metricsServer.DecPendingRepoRequest(q.Repo.Repo)
closer, err := s.repoLock.Lock(gitClient.Root(), q.Revision, true, func() error {
return checkoutRevision(gitClient, q.Revision)
closer, err := s.repoLock.Lock(gitClient.Root(), q.Revision, true, func() (goio.Closer, error) {
return s.checkoutRevision(gitClient, q.Revision, s.initConstants.SubmoduleEnabled)
})
if err != nil {
@@ -1530,8 +1585,12 @@ func fileParameters(q *apiclient.RepoServerAppDetailsQuery) []v1alpha1.HelmFileP
}
func (s *Service) newClient(repo *v1alpha1.Repository, opts ...git.ClientOpts) (git.Client, error) {
repoPath, err := s.gitRepoPaths.GetPath(git.NormalizeGitURL(repo.Repo))
if err != nil {
return nil, err
}
opts = append(opts, git.WithEventHandlers(metrics.NewGitClientEventHandlers(s.metricsServer)))
return s.newGitClient(repo.Repo, repo.GetGitCreds(), repo.IsInsecure(), repo.EnableLFS, repo.Proxy, opts...)
return s.newGitClient(repo.Repo, repoPath, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.EnableLFS, repo.Proxy, opts...)
}
// newClientResolveRevision is a helper to perform the common task of instantiating a git client
@@ -1550,7 +1609,7 @@ func (s *Service) newClientResolveRevision(repo *v1alpha1.Repository, revision s
func (s *Service) newHelmClientResolveRevision(repo *v1alpha1.Repository, revision string, chart string, noRevisionCache bool) (helm.Client, string, error) {
enableOCI := repo.EnableOCI || helm.IsHelmOciRepo(repo.Repo)
helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), enableOCI, repo.Proxy, helm.WithIndexCache(s.cache))
helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), enableOCI, repo.Proxy, helm.WithIndexCache(s.cache), helm.WithChartPaths(s.chartPaths))
// OCI helm registers don't support semver ranges. Assuming that given revision is exact version
if helm.IsVersion(revision) || enableOCI {
return helmClient, revision, nil
@@ -1574,13 +1633,35 @@ func (s *Service) newHelmClientResolveRevision(repo *v1alpha1.Repository, revisi
return helmClient, version.String(), nil
}
// directoryPermissionInitializer ensures the directory has read/write/execute permissions and returns
// a function that can be used to remove all permissions.
func directoryPermissionInitializer(rootPath string) goio.Closer {
if _, err := os.Stat(rootPath); err == nil {
if err := os.Chmod(rootPath, 0700); err != nil {
log.Warnf("Failed to restore read/write/execute permissions on %s: %v", rootPath, err)
} else {
log.Debugf("Successfully restored read/write/execute permissions on %s", rootPath)
}
}
return io.NewCloser(func() error {
if err := os.Chmod(rootPath, 0000); err != nil {
log.Warnf("Failed to remove permissions on %s: %v", rootPath, err)
} else {
log.Debugf("Successfully removed permissions on %s", rootPath)
}
return nil
})
}
// checkoutRevision is a convenience function to initialize a repo, fetch, and checkout a revision
// Returns the 40 character commit SHA after the checkout has been performed
// nolint:unparam
func checkoutRevision(gitClient git.Client, revision string) error {
func (s *Service) checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bool) (goio.Closer, error) {
closer := s.gitRepoInitializer(gitClient.Root())
err := gitClient.Init()
if err != nil {
return status.Errorf(codes.Internal, "Failed to initialize git repo: %v", err)
return closer, status.Errorf(codes.Internal, "Failed to initialize git repo: %v", err)
}
err = gitClient.Fetch(revision)
@@ -1590,25 +1671,25 @@ func checkoutRevision(gitClient git.Client, revision string) error {
log.Infof("Fallback to fetch default")
err = gitClient.Fetch("")
if err != nil {
return status.Errorf(codes.Internal, "Failed to fetch default: %v", err)
return closer, status.Errorf(codes.Internal, "Failed to fetch default: %v", err)
}
err = gitClient.Checkout(revision)
err = gitClient.Checkout(revision, submoduleEnabled)
if err != nil {
return status.Errorf(codes.Internal, "Failed to checkout revision %s: %v", revision, err)
return closer, status.Errorf(codes.Internal, "Failed to checkout revision %s: %v", revision, err)
}
return err
return closer, err
}
err = gitClient.Checkout("FETCH_HEAD")
err = gitClient.Checkout("FETCH_HEAD", submoduleEnabled)
if err != nil {
return status.Errorf(codes.Internal, "Failed to checkout FETCH_HEAD: %v", err)
return closer, status.Errorf(codes.Internal, "Failed to checkout FETCH_HEAD: %v", err)
}
return err
return closer, err
}
func (s *Service) GetHelmCharts(ctx context.Context, q *apiclient.HelmChartsRequest) (*apiclient.HelmChartsResponse, error) {
index, err := s.newHelmClient(q.Repo.Repo, q.Repo.GetHelmCreds(), q.Repo.EnableOCI, q.Repo.Proxy).GetIndex(true)
index, err := s.newHelmClient(q.Repo.Repo, q.Repo.GetHelmCreds(), q.Repo.EnableOCI, q.Repo.Proxy, helm.WithChartPaths(s.chartPaths)).GetIndex(true)
if err != nil {
return nil, err
}
@@ -1633,7 +1714,7 @@ func (s *Service) TestRepository(ctx context.Context, q *apiclient.TestRepositor
}
checks := map[string]func() error{
"git": func() error {
return git.TestRepo(repo.Repo, repo.GetGitCreds(), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy)
return git.TestRepo(repo.Repo, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy)
},
"helm": func() error {
if repo.EnableOCI {
@@ -1669,7 +1750,7 @@ func (s *Service) ResolveRevision(ctx context.Context, q *apiclient.ResolveRevis
if helm.IsVersion(ambiguousRevision) {
return &apiclient.ResolveRevisionResponse{Revision: ambiguousRevision, AmbiguousRevision: ambiguousRevision}, nil
}
client := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI || app.Spec.Source.IsHelmOci(), repo.Proxy)
client := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI || app.Spec.Source.IsHelmOci(), repo.Proxy, helm.WithChartPaths(s.chartPaths))
index, err := client.GetIndex(false)
if err != nil {
return &apiclient.ResolveRevisionResponse{Revision: "", AmbiguousRevision: ""}, err
@@ -1691,7 +1772,7 @@ func (s *Service) ResolveRevision(ctx context.Context, q *apiclient.ResolveRevis
AmbiguousRevision: fmt.Sprintf("%v (%v)", ambiguousRevision, version.String()),
}, nil
} else {
gitClient, err := git.NewClient(repo.Repo, repo.GetGitCreds(), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy)
gitClient, err := git.NewClient(repo.Repo, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy)
if err != nil {
return &apiclient.ResolveRevisionResponse{Revision: "", AmbiguousRevision: ""}, err
}

View File

@@ -29,6 +29,8 @@ message ManifestRequest {
repeated github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds helmRepoCreds = 17;
bool noRevisionCache = 18;
string trackingMethod = 19;
map<string, bool> enabledSourceTypes = 20;
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 21;
}
// TestRepositoryRequest is a query to test repository is valid or not and has valid access.
@@ -81,6 +83,7 @@ message Refs {
message ListAppsRequest {
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1;
string revision = 2;
map<string, bool> enabledSourceTypes = 3;
}
// AppList returns the contents of the repo of a ListApps request
@@ -98,6 +101,8 @@ message RepoServerAppDetailsQuery {
bool noCache = 6;
bool noRevisionCache = 7;
string trackingMethod = 8;
map<string, bool> enabledSourceTypes = 9;
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 10;
}
// RepoAppDetailsResponse application details

View File

@@ -5,17 +5,17 @@ import (
"encoding/json"
"errors"
"fmt"
goio "io"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"strings"
"testing"
"time"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -29,6 +29,7 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/cache"
"github.com/argoproj/argo-cd/v2/reposerver/metrics"
fileutil "github.com/argoproj/argo-cd/v2/test/fixture/path"
"github.com/argoproj/argo-cd/v2/util/argo"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
"github.com/argoproj/argo-cd/v2/util/git"
gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks"
@@ -52,7 +53,7 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client)
return newServiceWithOpt(func(gitClient *gitmocks.Client) {
gitClient.On("Init").Return(nil)
gitClient.On("Fetch", mock.Anything).Return(nil)
gitClient.On("Checkout", mock.Anything).Return(nil)
gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil)
gitClient.On("LsRemote", mock.Anything).Return(mock.Anything, nil)
gitClient.On("CommitSHA").Return(mock.Anything, nil)
gitClient.On("Root").Return(root)
@@ -72,7 +73,7 @@ func newServiceWithOpt(cf clientFunc) (*Service, *gitmocks.Client) {
cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Minute)),
1*time.Minute,
1*time.Minute,
), RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking())
), RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, os.TempDir())
chart := "my-chart"
version := "1.1.0"
@@ -82,12 +83,15 @@ func newServiceWithOpt(cf clientFunc) (*Service, *gitmocks.Client) {
helmClient.On("ExtractChart", chart, version).Return("./testdata/my-chart", io.NopCloser, nil)
helmClient.On("CleanChartCache", chart, version).Return(nil)
service.newGitClient = func(rawRepoURL string, creds git.Creds, insecure bool, enableLfs bool, prosy string, opts ...git.ClientOpts) (client git.Client, e error) {
service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, prosy string, opts ...git.ClientOpts) (client git.Client, e error) {
return gitClient, nil
}
service.newHelmClient = func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client {
return helmClient
}
service.gitRepoInitializer = func(rootPath string) goio.Closer {
return io.NopCloser
}
return service, gitClient
}
@@ -112,13 +116,13 @@ func newServiceWithCommitSHA(root, revision string) *Service {
service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client) {
gitClient.On("Init").Return(nil)
gitClient.On("Fetch", mock.Anything).Return(nil)
gitClient.On("Checkout", mock.Anything).Return(nil)
gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil)
gitClient.On("LsRemote", revision).Return(revision, revisionErr)
gitClient.On("CommitSHA").Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil)
gitClient.On("Root").Return(root)
})
service.newGitClient = func(rawRepoURL string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) {
service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) {
return gitClient, nil
}
@@ -132,7 +136,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) {
q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src}
// update this value if we add/remove manifests
const countOfManifests = 47
const countOfManifests = 41
res1, err := service.GenerateManifest(context.Background(), &q)
@@ -140,7 +144,7 @@ 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)
res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{})
assert.NoError(t, err)
assert.Equal(t, 3, len(res2.Manifests))
}
@@ -250,7 +254,7 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) {
Jsonnet: argoappv1.ApplicationSourceJsonnet{
ExtVars: []argoappv1.JsonnetVar{{Name: "extVarString", Value: "extVarString"}, {Name: "extVarCode", Value: "\"extVarCode\"", Code: true}},
TLAs: []argoappv1.JsonnetVar{{Name: "tlaString", Value: "tlaString"}, {Name: "tlaCode", Value: "\"tlaCode\"", Code: true}},
Libs: []string{"testdata/jsonnet/vendor"},
Libs: []string{"./vendor"},
},
},
},
@@ -260,6 +264,25 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) {
assert.Equal(t, 2, len(res1.Manifests))
}
func TestGenerateJsonnetLibOutside(t *testing.T) {
service := newService(".")
q := apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
ApplicationSource: &argoappv1.ApplicationSource{
Path: "./testdata/jsonnet",
Directory: &argoappv1.ApplicationSourceDirectory{
Jsonnet: argoappv1.ApplicationSourceJsonnet{
Libs: []string{"../../../testdata/jsonnet/vendor"},
},
},
},
}
_, err := service.GenerateManifest(context.Background(), &q)
require.Error(t, err)
require.Contains(t, err.Error(), "value file '../../../testdata/jsonnet/vendor' resolved to outside repository root")
}
func TestGenerateKsonnetManifest(t *testing.T) {
service := newService("../..")
@@ -754,7 +777,37 @@ func TestHelmManifestFromChartRepoWithValueFileOutsideRepo(t *testing.T) {
}
request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true}
_, err := service.GenerateManifest(context.Background(), request)
assert.Error(t, err, "should be on or under current directory")
assert.Error(t, err)
}
func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) {
t.Run("Valid symlink", func(t *testing.T) {
service := newService("../..")
source := &argoappv1.ApplicationSource{
Chart: "my-chart",
TargetRevision: ">= 1.0.0",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"my-chart-link.yaml"},
},
}
request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true}
_, err := service.GenerateManifest(context.Background(), request)
assert.NoError(t, err)
})
t.Run("Symlink pointing to outside", func(t *testing.T) {
service := newService("../..")
source := &argoappv1.ApplicationSource{
Chart: "my-chart",
TargetRevision: ">= 1.0.0",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"my-chart-outside-link.yaml"},
},
}
request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true}
_, err := service.GenerateManifest(context.Background(), request)
assert.Error(t, err)
assert.Contains(t, err.Error(), "outside repository root")
})
}
func TestGenerateHelmWithURL(t *testing.T) {
@@ -770,6 +823,7 @@ func TestGenerateHelmWithURL(t *testing.T) {
Values: `cluster: {slaveCount: 2}`,
},
},
HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"https"}},
})
assert.NoError(t, err)
}
@@ -777,38 +831,108 @@ func TestGenerateHelmWithURL(t *testing.T) {
// The requested value file (`../../../../../minio/values.yaml`) is outside the repo directory
// (`~/go/src/github.com/argoproj/argo-cd`), so it is blocked
func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) {
service := newService("../..")
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: "./util/helm/testdata/redis",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"../../../../../minio/values.yaml"},
Values: `cluster: {slaveCount: 2}`,
t.Run("Values file with relative path pointing outside repo root", func(t *testing.T) {
service := newService("../..")
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: "./util/helm/testdata/redis",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"../../../../../minio/values.yaml"},
Values: `cluster: {slaveCount: 2}`,
},
},
},
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "outside repository root")
})
assert.Error(t, err, "should be on or under current directory")
service = newService("./testdata/my-chart")
_, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: ".",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"../my-chart-2/values.yaml"},
Values: `cluster: {slaveCount: 2}`,
t.Run("Values file with relative path pointing inside repo root", func(t *testing.T) {
service := newService("./testdata/my-chart")
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: ".",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"../my-chart/my-chart-values.yaml"},
Values: `cluster: {slaveCount: 2}`,
},
},
},
})
assert.NoError(t, err)
})
t.Run("Values file with absolute path stays within repo root", func(t *testing.T) {
service := newService("./testdata/my-chart")
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: ".",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"/my-chart-values.yaml"},
Values: `cluster: {slaveCount: 2}`,
},
},
})
assert.NoError(t, err)
})
t.Run("Values file with absolute path using back-references outside repo root", func(t *testing.T) {
service := newService("./testdata/my-chart")
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: ".",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"/../../../my-chart-values.yaml"},
Values: `cluster: {slaveCount: 2}`,
},
},
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "outside repository root")
})
t.Run("Remote values file from forbidden protocol", func(t *testing.T) {
service := newService("./testdata/my-chart")
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: ".",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"file://../../../../my-chart-values.yaml"},
Values: `cluster: {slaveCount: 2}`,
},
},
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "is not allowed")
})
t.Run("Remote values file from custom allowed protocol", func(t *testing.T) {
service := newService("./testdata/my-chart")
_, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{
Repo: &argoappv1.Repository{},
AppName: "test",
ApplicationSource: &argoappv1.ApplicationSource{
Path: ".",
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"s3://my-bucket/my-chart-values.yaml"},
},
},
HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"s3"}},
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "s3://my-bucket/my-chart-values.yaml: no such file or directory")
})
assert.Error(t, err, "should be on or under current directory")
}
// The requested file parameter (`/tmp/external-secret.txt`) is outside the app path
// (`./util/helm/testdata/redis`), and outside the repo directory. It is used as a means
// of providing direct content to a helm chart via a specific key.
// File parameter should not allow traversal outside of the repository root
func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) {
service := newService("../..")
@@ -830,16 +954,14 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) {
Helm: &argoappv1.ApplicationSourceHelm{
ValueFiles: []string{"values-production.yaml"},
Values: `cluster: {slaveCount: 2}`,
FileParameters: []argoappv1.HelmFileParameter{
argoappv1.HelmFileParameter{
Name: "passwordContent",
Path: externalSecretPath,
},
},
FileParameters: []argoappv1.HelmFileParameter{{
Name: "passwordContent",
Path: externalSecretPath,
}},
},
},
})
assert.NoError(t, err)
assert.Error(t, err)
}
// The requested file parameter (`../external/external-secret.txt`) is outside the app path
@@ -897,15 +1019,15 @@ func TestGenerateNullList(t *testing.T) {
}
func TestIdentifyAppSourceTypeByAppDirWithKustomizations(t *testing.T) {
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp")
sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "testapp", map[string]bool{})
assert.Nil(t, err)
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp")
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "testapp", map[string]bool{})
assert.Nil(t, err)
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp")
sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "testapp", map[string]bool{})
assert.Nil(t, err)
assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType)
}
@@ -947,9 +1069,8 @@ func TestRunCustomTool(t *testing.T) {
assert.Equal(t, obj.GetName(), "test-app")
assert.Equal(t, obj.GetNamespace(), "test-namespace")
assert.Equal(t, "git-ask-pass.sh", obj.GetAnnotations()["GIT_ASKPASS"])
assert.Equal(t, "foo", obj.GetAnnotations()["GIT_USERNAME"])
assert.Equal(t, "bar", obj.GetAnnotations()["GIT_PASSWORD"])
assert.Empty(t, obj.GetAnnotations()["GIT_USERNAME"])
assert.Empty(t, obj.GetAnnotations()["GIT_PASSWORD"])
// Git client is mocked, so the revision is always mock.Anything
assert.Equal(t, map[string]string{"revision": "prefix-mock.Anything"}, obj.GetLabels())
}
@@ -959,7 +1080,7 @@ func TestGenerateFromUTF16(t *testing.T) {
Repo: &argoappv1.Repository{},
ApplicationSource: &argoappv1.ApplicationSource{},
}
res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false)
res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{})
assert.Nil(t, err)
assert.Equal(t, 2, len(res1.Manifests))
}
@@ -1524,7 +1645,7 @@ func TestFindResources(t *testing.T) {
Recurse: true,
Include: tc.include,
Exclude: tc.exclude,
})
}, map[string]bool{})
if !assert.NoError(t, err) {
return
}
@@ -1541,7 +1662,7 @@ func TestFindManifests_Exclude(t *testing.T) {
objs, err := findManifests("testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
Recurse: true,
Exclude: "subdir/deploymentSub.yaml",
})
}, map[string]bool{})
if !assert.NoError(t, err) || !assert.Len(t, objs, 1) {
return
@@ -1554,7 +1675,7 @@ func TestFindManifests_Exclude_NothingMatches(t *testing.T) {
objs, err := findManifests("testdata/app-include-exclude", ".", nil, argoappv1.ApplicationSourceDirectory{
Recurse: true,
Exclude: "nothing.yaml",
})
}, map[string]bool{})
if !assert.NoError(t, err) || !assert.Len(t, objs, 2) {
return
@@ -1631,3 +1752,67 @@ func TestResolveRevisionNegativeScenarios(t *testing.T) {
assert.Equal(t, expectedResolveRevisionResponse, resolveRevisionResponse)
}
func TestDirectoryPermissionInitializer(t *testing.T) {
dir, err := ioutil.TempDir("", "")
require.NoError(t, err)
defer func() {
_ = os.RemoveAll(dir)
}()
file, err := ioutil.TempFile(dir, "")
require.NoError(t, err)
io.Close(file)
// remove read permissions
assert.NoError(t, os.Chmod(dir, 0000))
closer := directoryPermissionInitializer(dir)
// make sure permission are restored
_, err = ioutil.ReadFile(file.Name())
require.NoError(t, err)
// make sure permission are removed by closer
io.Close(closer)
_, err = ioutil.ReadFile(file.Name())
require.Error(t, err)
}
func initGitRepo(repoPath string, remote string) error {
if err := os.Mkdir(repoPath, 0755); err != nil {
return err
}
cmd := exec.Command("git", "init", repoPath)
cmd.Dir = repoPath
if err := cmd.Run(); err != nil {
return err
}
cmd = exec.Command("git", "remote", "add", "origin", remote)
cmd.Dir = repoPath
return cmd.Run()
}
func TestInit(t *testing.T) {
dir, err := ioutil.TempDir("", "")
require.NoError(t, err)
defer func() {
_ = os.RemoveAll(dir)
}()
repoPath := path.Join(dir, "repo1")
require.NoError(t, initGitRepo(repoPath, "https://github.com/argo-cd/test-repo1"))
service := newService(".")
service.rootDir = dir
require.NoError(t, service.Init())
repo1Path, err := service.gitRepoPaths.GetPath(git.NormalizeGitURL("https://github.com/argo-cd/test-repo1"))
assert.NoError(t, err)
assert.Equal(t, repoPath, repo1Path)
_, err = ioutil.ReadDir(dir)
require.Error(t, err)
require.NoError(t, initGitRepo(path.Join(dir, "repo2"), "https://github.com/argo-cd/test-repo2"))
}

View File

@@ -0,0 +1 @@
my-chart-values.yaml

View File

@@ -0,0 +1 @@
../my-chart-2/my-chart-2-values.yaml

View File

@@ -4,8 +4,7 @@ import (
"crypto/tls"
"fmt"
"os"
"github.com/argoproj/argo-cd/v2/util/argo"
"path/filepath"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
@@ -24,7 +23,9 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/metrics"
"github.com/argoproj/argo-cd/v2/reposerver/repository"
"github.com/argoproj/argo-cd/v2/server/version"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/env"
"github.com/argoproj/argo-cd/v2/util/git"
grpc_util "github.com/argoproj/argo-cd/v2/util/grpc"
tlsutil "github.com/argoproj/argo-cd/v2/util/tls"
)
@@ -32,7 +33,9 @@ import (
// ArgoCDRepoServer is the repo server implementation
type ArgoCDRepoServer struct {
log *log.Entry
repoService *repository.Service
metricsServer *metrics.MetricsServer
gitCredsStore git.CredsStore
cache *reposervercache.Cache
opts []grpc.ServerOption
initConstants repository.RepoServerInitConstants
@@ -42,7 +45,7 @@ type ArgoCDRepoServer struct {
var tlsHostList []string = []string{"localhost", "reposerver"}
// NewServer returns a new instance of the Argo CD Repo server
func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cache, tlsConfCustomizer tlsutil.ConfigCustomizer, initConstants repository.RepoServerInitConstants) (*ArgoCDRepoServer, error) {
func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cache, tlsConfCustomizer tlsutil.ConfigCustomizer, initConstants repository.RepoServerInitConstants, gitCredsStore git.CredsStore) (*ArgoCDRepoServer, error) {
var tlsConfig *tls.Config
// Generate or load TLS server certificates to use with this instance of
@@ -64,7 +67,12 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach
serverLog := log.NewEntry(log.StandardLogger())
streamInterceptors := []grpc.StreamServerInterceptor{grpc_logrus.StreamServerInterceptor(serverLog), grpc_prometheus.StreamServerInterceptor, grpc_util.PanicLoggerStreamServerInterceptor(serverLog)}
unaryInterceptors := []grpc.UnaryServerInterceptor{grpc_logrus.UnaryServerInterceptor(serverLog), grpc_prometheus.UnaryServerInterceptor, grpc_util.PanicLoggerUnaryServerInterceptor(serverLog)}
unaryInterceptors := []grpc.UnaryServerInterceptor{
grpc_logrus.UnaryServerInterceptor(serverLog),
grpc_prometheus.UnaryServerInterceptor,
grpc_util.PanicLoggerUnaryServerInterceptor(serverLog),
grpc_util.ErrorSanitizerUnaryServerInterceptor(),
}
serverOpts := []grpc.ServerOption{
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(unaryInterceptors...)),
@@ -78,6 +86,10 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach
if tlsConfig != nil {
serverOpts = append(serverOpts, grpc.Creds(credentials.NewTLS(tlsConfig)))
}
repoService := repository.NewService(metricsServer, cache, initConstants, argo.NewResourceTracking(), gitCredsStore, filepath.Join(os.TempDir(), "_argocd-repo"))
if err := repoService.Init(); err != nil {
return nil, err
}
return &ArgoCDRepoServer{
log: serverLog,
@@ -85,6 +97,8 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach
cache: cache,
initConstants: initConstants,
opts: serverOpts,
gitCredsStore: gitCredsStore,
repoService: repoService,
}, nil
}
@@ -94,8 +108,7 @@ func (a *ArgoCDRepoServer) CreateGRPC() *grpc.Server {
versionpkg.RegisterVersionServiceServer(server, version.NewServer(nil, func() (bool, error) {
return true, nil
}))
manifestService := repository.NewService(a.metricsServer, a.cache, a.initConstants, argo.NewResourceTracking())
apiclient.RegisterRepoServerServiceServer(server, manifestService)
apiclient.RegisterRepoServerServiceServer(server, a.repoService)
healthService := health.NewServer()
grpc_health_v1.RegisterHealthServer(server, healthService)

View File

@@ -1,13 +1,13 @@
health_check = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
if obj.status.conditions ~= nil and obj.status.replicas ~= nil then
numTrue = 0
for i, condition in pairs(obj.status.conditions) do
if (condition.type == "Available" or condition.type == "Progressing") and condition.status == "True" then
numTrue = numTrue + 1
end
end
if numTrue == 2 then
if numTrue == 2 or obj.status.replicas == 0 then
health_check.status = "Healthy"
health_check.message = "replication controller successfully rolled out"
return health_check

View File

@@ -10,4 +10,8 @@ tests:
- healthStatus:
status: Healthy
message: "replication controller successfully rolled out"
inputPath: testdata/healthy.yaml
inputPath: testdata/healthy.yaml
- healthStatus:
status: Healthy
message: "replication controller successfully rolled out"
inputPath: testdata/healthy_zero_replicas.yaml

View File

@@ -133,10 +133,10 @@ spec:
status:
latestVersion: 1
observedGeneration: 1
replicas: 0
updatedReplicas: 0
replicas: 10
updatedReplicas: 10
availableReplicas: 0
unavailableReplicas: 0
unavailableReplicas: 10
details:
message: config change
causes:

View File

@@ -0,0 +1,68 @@
kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
name: example
namespace: default
spec:
strategy:
type: Rolling
rollingParams:
updatePeriodSeconds: 1
intervalSeconds: 1
timeoutSeconds: 600
maxUnavailable: 25%
maxSurge: 25%
resources: {}
activeDeadlineSeconds: 21600
triggers:
- type: ConfigChange
replicas: 3
revisionHistoryLimit: 10
test: false
selector:
app: httpd
template:
metadata:
creationTimestamp: null
labels:
app: httpd
spec:
containers:
- name: httpd
image: >-
image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: Always
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
schedulerName: default-scheduler
status:
availableReplicas: 0
conditions:
- lastTransitionTime: '2022-02-02T12:22:22Z'
lastUpdateTime: '2022-02-02T12:23:53Z'
message: replication controller "jenkins-1" successfully rolled out
reason: NewReplicationControllerAvailable
status: 'True'
type: Progressing
- lastTransitionTime: '2022-02-02T14:11:11Z'
lastUpdateTime: '2022-02-02T14:11:11Z'
message: Deployment config does not have minimum availability.
status: 'False'
type: Available
details:
causes:
- type: ConfigChange
message: config change
latestVersion: 1
observedGeneration: 5
replicas: 0
unavailableReplicas: 0
updatedReplicas: 0

View File

@@ -2,6 +2,11 @@ hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Issuing" and condition.status == "True" then
hs.status = "Progressing"
hs.message = condition.message
return hs
end
if condition.type == "Ready" and condition.status == "False" then
hs.status = "Degraded"
hs.message = condition.message

View File

@@ -3,6 +3,10 @@ tests:
status: Progressing
message: Waiting for certificate
inputPath: testdata/progressing_noStatus.yaml
- healthStatus:
status: Progressing
message: Issuing certificate as Secret does not exist
inputPath: testdata/progressing_issuing.yaml
- healthStatus:
status: Degraded
message: 'Resource validation failed: spec.acme.config: Required value: no ACME

View File

@@ -0,0 +1,37 @@
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
creationTimestamp: '2018-11-07T00:06:12Z'
generation: 1
name: test-cert
namespace: argocd
resourceVersion: '64763033'
selfLink: /apis/cert-manager.io/v1alpha2/namespaces/argocd/certificates/test-cert
uid: e6cfba50-314d-11e9-be3f-42010a800011
spec:
acme:
config:
- domains:
- cd.apps.argoproj.io
http01:
ingress: http01
commonName: cd.apps.argoproj.io
dnsNames:
- cd.apps.argoproj.io
issuerRef:
kind: Issuer
name: argo-cd-issuer
secretName: test-secret
status:
conditions:
- lastTransitionTime: '2021-09-15T02:10:00Z'
message: Issuing certificate as Secret does not exist
reason: DoesNotExist
status: 'True'
type: Issuing
- lastTransitionTime: '2021-09-15T02:10:00Z'
message: Issuing certificate as Secret does not exist
reason: DoesNotExist
status: 'False'
type: Ready

View File

@@ -229,7 +229,9 @@ func (s *Server) queryRepoServer(ctx context.Context, a *v1alpha1.Application, a
repo *appv1.Repository,
helmRepos []*appv1.Repository,
helmCreds []*v1alpha1.RepoCreds,
helmOptions *v1alpha1.HelmOptions,
kustomizeOptions *v1alpha1.KustomizeOptions,
enabledSourceTypes map[string]bool,
) error) error {
closer, client, err := s.repoClientset.NewRepoServerClient()
@@ -270,11 +272,19 @@ func (s *Server) queryRepoServer(ctx context.Context, a *v1alpha1.Application, a
if err != nil {
return err
}
helmOptions, err := s.settingsMgr.GetHelmSettings()
if err != nil {
return err
}
permittedHelmCredentials, err := argo.GetPermittedReposCredentials(proj, helmRepositoryCredentials)
if err != nil {
return err
}
return action(client, repo, permittedHelmRepos, permittedHelmCredentials, kustomizeOptions)
enabledSourceTypes, err := s.settingsMgr.GetEnabledSourceTypes()
if err != nil {
return err
}
return action(client, repo, permittedHelmRepos, permittedHelmCredentials, helmOptions, kustomizeOptions, enabledSourceTypes)
}
// GetManifests returns application manifests
@@ -289,7 +299,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
var manifestInfo *apiclient.ManifestResponse
err = s.queryRepoServer(ctx, a, func(
client apiclient.RepoServerServiceClient, repo *appv1.Repository, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, kustomizeOptions *appv1.KustomizeOptions) error {
client apiclient.RepoServerServiceClient, repo *appv1.Repository, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, helmOptions *appv1.HelmOptions, kustomizeOptions *appv1.KustomizeOptions, enableGenerateManifests map[string]bool) error {
revision := a.Spec.Source.TargetRevision
if q.Revision != "" {
revision = q.Revision
@@ -319,19 +329,21 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
}
manifestInfo, err = client.GenerateManifest(ctx, &apiclient.ManifestRequest{
Repo: repo,
Revision: revision,
AppLabelKey: appInstanceLabelKey,
AppName: a.Name,
Namespace: a.Spec.Destination.Namespace,
ApplicationSource: &a.Spec.Source,
Repos: helmRepos,
Plugins: plugins,
KustomizeOptions: kustomizeOptions,
KubeVersion: serverVersion,
ApiVersions: argo.APIResourcesToStrings(apiResources, true),
HelmRepoCreds: helmCreds,
TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)),
Repo: repo,
Revision: revision,
AppLabelKey: appInstanceLabelKey,
AppName: a.Name,
Namespace: a.Spec.Destination.Namespace,
ApplicationSource: &a.Spec.Source,
Repos: helmRepos,
Plugins: plugins,
KustomizeOptions: kustomizeOptions,
KubeVersion: serverVersion,
ApiVersions: argo.APIResourcesToStrings(apiResources, true),
HelmRepoCreds: helmCreds,
HelmOptions: helmOptions,
TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)),
EnabledSourceTypes: enableGenerateManifests,
})
return err
})
@@ -406,16 +418,20 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app
repo *appv1.Repository,
helmRepos []*appv1.Repository,
_ []*appv1.RepoCreds,
helmOptions *appv1.HelmOptions,
kustomizeOptions *appv1.KustomizeOptions,
enabledSourceTypes map[string]bool,
) error {
_, err := client.GetAppDetails(ctx, &apiclient.RepoServerAppDetailsQuery{
Repo: repo,
Source: &app.Spec.Source,
AppName: app.Name,
KustomizeOptions: kustomizeOptions,
Repos: helmRepos,
NoCache: true,
TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)),
Repo: repo,
Source: &app.Spec.Source,
AppName: app.Name,
KustomizeOptions: kustomizeOptions,
Repos: helmRepos,
NoCache: true,
TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)),
EnabledSourceTypes: enabledSourceTypes,
HelmOptions: helmOptions,
})
return err
}); err != nil {

View File

@@ -4,22 +4,24 @@ import (
"fmt"
"reflect"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/text"
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
apierr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/argoproj/argo-cd/v2/common"
repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
servercache "github.com/argoproj/argo-cd/v2/server/cache"
"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/errors"
"github.com/argoproj/argo-cd/v2/util/io"
@@ -33,6 +35,8 @@ type Server struct {
repoClientset apiclient.Clientset
enf *rbac.Enforcer
cache *servercache.Cache
appLister applisters.ApplicationNamespaceLister
projLister applisters.AppProjectNamespaceLister
settings *settings.SettingsManager
}
@@ -42,6 +46,8 @@ func NewServer(
db db.ArgoDB,
enf *rbac.Enforcer,
cache *servercache.Cache,
appLister applisters.ApplicationNamespaceLister,
projLister applisters.AppProjectNamespaceLister,
settings *settings.SettingsManager,
) *Server {
return &Server{
@@ -49,14 +55,20 @@ func NewServer(
repoClientset: repoClientset,
enf: enf,
cache: cache,
appLister: appLister,
projLister: projLister,
settings: settings,
}
}
var (
errPermissionDenied = status.Error(codes.PermissionDenied, "permission denied")
)
func (s *Server) getRepo(ctx context.Context, url string) (*appsv1.Repository, error) {
repo, err := s.db.GetRepository(ctx, url)
if err != nil {
return nil, status.Error(codes.PermissionDenied, "permission denied")
return nil, errPermissionDenied
}
return repo, nil
}
@@ -213,14 +225,29 @@ func (s *Server) ListRefs(ctx context.Context, q *repositorypkg.RepoQuery) (*api
})
}
// ListApps returns list of apps in the repo
// ListApps performs discovery of a git repository for potential sources of applications. Used
// as a convenience to the UI for auto-complete.
func (s *Server) ListApps(ctx context.Context, q *repositorypkg.RepoAppsQuery) (*repositorypkg.RepoAppsResponse, error) {
repo, err := s.getRepo(ctx, q.Repo)
if err != nil {
return nil, err
}
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, createRBACObject(repo.Project, repo.Repo)); err != nil {
claims := ctx.Value("claims")
if err := s.enf.EnforceErr(claims, rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, createRBACObject(repo.Project, repo.Repo)); err != nil {
return nil, err
}
// This endpoint causes us to clone git repos & invoke config management tooling for the purposes
// of app discovery. Only allow this to happen if user has privileges to create or update the
// application which it wants to retrieve these details for.
appRBACresource := fmt.Sprintf("%s/%s", q.AppProject, q.AppName)
if !s.enf.Enforce(claims, rbacpolicy.ResourceApplications, rbacpolicy.ActionCreate, appRBACresource) &&
!s.enf.Enforce(claims, rbacpolicy.ResourceApplications, rbacpolicy.ActionUpdate, appRBACresource) {
return nil, errPermissionDenied
}
// Also ensure the repo is actually allowed in the project in question
if err := s.isRepoPermittedInProject(q.Repo, q.AppProject); err != nil {
return nil, err
}
@@ -245,6 +272,9 @@ func (s *Server) ListApps(ctx context.Context, q *repositorypkg.RepoAppsQuery) (
return &repositorypkg.RepoAppsResponse{Items: items}, nil
}
// GetAppDetails shows parameter values to various config tools (e.g. helm/kustomize values)
// This is used by UI for parameter form fields during app create & edit pages.
// It is also used when showing history of parameters used in previous syncs in the app history.
func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDetailsQuery) (*apiclient.RepoAppDetailsResponse, error) {
if q.Source == nil {
return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
@@ -253,9 +283,38 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta
if err != nil {
return nil, err
}
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, createRBACObject(repo.Project, repo.Repo)); err != nil {
claims := ctx.Value("claims")
if err := s.enf.EnforceErr(claims, rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, createRBACObject(repo.Project, repo.Repo)); err != nil {
return nil, err
}
app, err := s.appLister.Get(q.AppName)
appRBACObj := createRBACObject(q.AppProject, q.AppName)
// ensure caller has read privileges to app
if err := s.enf.EnforceErr(claims, rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACObj); err != nil {
return nil, err
}
if apierr.IsNotFound(err) {
// app doesn't exist since it still is being formulated. verify they can create the app
// before we reveal repo details
if err := s.enf.EnforceErr(claims, rbacpolicy.ResourceApplications, rbacpolicy.ActionCreate, appRBACObj); err != nil {
return nil, err
}
} else {
// if we get here we are returning repo details of an existing app
if q.AppProject != app.Spec.Project {
return nil, errPermissionDenied
}
// verify caller is not making a request with arbitrary source values which were not in our history
if !isSourceInHistory(app, *q.Source) {
return nil, errPermissionDenied
}
}
// Ensure the repo is actually allowed in the project in question
if err := s.isRepoPermittedInProject(q.Source.RepoURL, q.AppProject); err != nil {
return nil, err
}
conn, repoClient, err := s.repoClientset.NewRepoServerClient()
if err != nil {
return nil, err
@@ -273,11 +332,16 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta
if err != nil {
return nil, err
}
helmOptions, err := s.settings.GetHelmSettings()
if err != nil {
return nil, err
}
return repoClient.GetAppDetails(ctx, &apiclient.RepoServerAppDetailsQuery{
Repo: repo,
Source: q.Source,
Repos: helmRepos,
KustomizeOptions: kustomizeOptions,
HelmOptions: helmOptions,
AppName: q.AppName,
})
}
@@ -473,3 +537,33 @@ func (s *Server) testRepo(ctx context.Context, repo *appsv1.Repository) error {
})
return err
}
func (s *Server) isRepoPermittedInProject(repo string, projName string) error {
proj, err := s.projLister.Get(projName)
if err != nil {
return err
}
if !proj.IsSourcePermitted(appsv1.ApplicationSource{RepoURL: repo}) {
return status.Errorf(codes.PermissionDenied, "repository '%s' not permitted in project '%s'", repo, projName)
}
return nil
}
// isSourceInHistory checks if the supplied application source is either our current application
// source, or was something which we synced to previously.
func isSourceInHistory(app *v1alpha1.Application, source v1alpha1.ApplicationSource) bool {
if source.Equals(app.Spec.Source) {
return true
}
// Iterate history. When comparing items in our history, use the actual synced revision to
// compare with the supplied source.targetRevision in the request. This is because
// history[].source.targetRevision is ambiguous (e.g. HEAD), whereas
// history[].revision will contain the explicit SHA
for _, h := range app.Status.History {
h.Source.TargetRevision = h.Revision
if source.Equals(h.Source) {
return true
}
}
return false
}

View File

@@ -16,6 +16,8 @@ import "github.com/argoproj/argo-cd/v2/reposerver/repository/repository.proto";
message RepoAppsQuery {
string repo = 1;
string revision = 2;
string appName = 3;
string appProject = 4;
}
@@ -29,6 +31,7 @@ message AppInfo {
message RepoAppDetailsQuery {
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSource source = 1;
string appName = 2;
string appProject = 3;
}
// RepoAppsResponse contains applications of specified repository

View File

@@ -6,43 +6,141 @@ import (
"testing"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/server/cache"
"github.com/stretchr/testify/mock"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
"github.com/argoproj/argo-cd/v2/util/db"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/fake"
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/util/assets"
"github.com/argoproj/argo-cd/v2/util/rbac"
"github.com/argoproj/argo-cd/v2/util/settings"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
fakeapps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake"
appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions"
applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks"
"github.com/stretchr/testify/assert"
"github.com/golang-jwt/jwt/v4"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/argoproj/argo-cd/v2/server/cache"
"github.com/argoproj/argo-cd/v2/util/assets"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/argo-cd/v2/util/db"
dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks"
"github.com/argoproj/argo-cd/v2/util/rbac"
"github.com/argoproj/argo-cd/v2/util/settings"
)
const testNamespace = "default"
var (
argocdCM = corev1.ConfigMap{
ObjectMeta: v1.ObjectMeta{
Namespace: testNamespace,
Name: "argocd-cm",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
}
argocdSecret = corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Name: "argocd-secret",
Namespace: testNamespace,
},
Data: map[string][]byte{
"admin.password": []byte("test"),
"server.secretkey": []byte("test"),
},
}
defaultProj = &appsv1.AppProject{
TypeMeta: metav1.TypeMeta{
Kind: "AppProject",
APIVersion: "argoproj.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: testNamespace,
},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
},
}
defaultProjNoSources = &appsv1.AppProject{
TypeMeta: metav1.TypeMeta{
Kind: "AppProject",
APIVersion: "argoproj.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: testNamespace,
},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
},
}
guestbookApp = &appsv1.Application{
TypeMeta: metav1.TypeMeta{
Kind: "Application",
APIVersion: "argoproj.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "guestbook",
Namespace: testNamespace,
},
Spec: appsv1.ApplicationSpec{
Project: "default",
Source: appsv1.ApplicationSource{
RepoURL: "https://test",
TargetRevision: "HEAD",
Helm: &appsv1.ApplicationSourceHelm{
ValueFiles: []string{"values.yaml"},
},
},
},
Status: appsv1.ApplicationStatus{
History: appsv1.RevisionHistories{
{
Revision: "abcdef123567",
Source: appsv1.ApplicationSource{
RepoURL: "https://test",
TargetRevision: "HEAD",
Helm: &appsv1.ApplicationSourceHelm{
ValueFiles: []string{"values-old.yaml"},
},
},
},
},
},
}
)
func newAppAndProjLister(objects ...runtime.Object) (applisters.ApplicationNamespaceLister, applisters.AppProjectNamespaceLister) {
fakeAppsClientset := fakeapps.NewSimpleClientset(objects...)
factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {}))
projInformer := factory.Argoproj().V1alpha1().AppProjects()
appsInformer := factory.Argoproj().V1alpha1().Applications()
for _, obj := range objects {
switch obj.(type) {
case *appsv1.AppProject:
_ = projInformer.Informer().GetStore().Add(obj)
case *appsv1.Application:
_ = appsInformer.Informer().GetStore().Add(obj)
}
}
appLister := appsInformer.Lister().Applications(testNamespace)
projLister := projInformer.Lister().AppProjects(testNamespace)
return appLister, projLister
}
func Test_createRBACObject(t *testing.T) {
object := createRBACObject("test-prj", "test-repo")
assert.Equal(t, "test-prj/test-repo", object)
@@ -51,34 +149,17 @@ func Test_createRBACObject(t *testing.T) {
}
func TestRepositoryServer(t *testing.T) {
kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{
ObjectMeta: v1.ObjectMeta{
Namespace: testNamespace,
Name: "argocd-cm",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
}, &corev1.Secret{
ObjectMeta: v1.ObjectMeta{
Name: "argocd-secret",
Namespace: testNamespace,
},
Data: map[string][]byte{
"admin.password": []byte("test"),
"server.secretkey": []byte("test"),
},
})
kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret)
settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace)
enforcer := newEnforcer(kubeclientset)
appLister, projLister := newAppAndProjLister(defaultProj)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
t.Run("Test_getRepo", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
s := NewServer(&repoServerClientset, argoDB, enforcer, nil, settingsMgr)
s := NewServer(&repoServerClientset, argoDB, enforcer, nil, appLister, projLister, settingsMgr)
url := "https://test"
repo, _ := s.getRepo(context.TODO(), url)
assert.Equal(t, repo.Repo, url)
@@ -89,7 +170,7 @@ func TestRepositoryServer(t *testing.T) {
repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil)
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
s := NewServer(&repoServerClientset, argoDB, enforcer, nil, settingsMgr)
s := NewServer(&repoServerClientset, argoDB, enforcer, nil, appLister, projLister, settingsMgr)
url := "https://test"
_, err := s.ValidateAccess(context.TODO(), &repository.RepoAccessQuery{
Repo: url,
@@ -104,10 +185,10 @@ func TestRepositoryServer(t *testing.T) {
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&v1alpha1.Repository{Repo: url}, nil)
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
db.On("RepositoryExists", context.TODO(), url).Return(true, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, settingsMgr)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
repo, err := s.Get(context.TODO(), &repository.RepoQuery{
Repo: url,
})
@@ -124,12 +205,12 @@ func TestRepositoryServer(t *testing.T) {
db.On("GetRepository", context.TODO(), url).Return(nil, errors.New("some error"))
db.On("RepositoryExists", context.TODO(), url).Return(true, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, settingsMgr)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
repo, err := s.Get(context.TODO(), &repository.RepoQuery{
Repo: url,
})
assert.Nil(t, repo)
assert.Equal(t, err.Error(), "rpc error: code = PermissionDenied desc = permission denied")
assert.Equal(t, err, errPermissionDenied)
})
t.Run("Test_GetWithNotExistRepoShouldReturn404", func(t *testing.T) {
@@ -138,15 +219,15 @@ func TestRepositoryServer(t *testing.T) {
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&v1alpha1.Repository{Repo: url}, nil)
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
db.On("RepositoryExists", context.TODO(), url).Return(false, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, settingsMgr)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
repo, err := s.Get(context.TODO(), &repository.RepoQuery{
Repo: url,
})
assert.Nil(t, repo)
assert.Equal(t, err.Error(), "rpc error: code = NotFound desc = repo 'https://test' not found")
assert.Equal(t, "rpc error: code = NotFound desc = repo 'https://test' not found", err.Error())
})
t.Run("Test_CreateRepositoryWithoutUpsert", func(t *testing.T) {
@@ -156,14 +237,14 @@ func TestRepositoryServer(t *testing.T) {
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), "test").Return(nil, errors.New("not found"))
db.On("CreateRepository", context.TODO(), mock.Anything).Return(&apiclient.TestRepositoryResponse{}).Return(&v1alpha1.Repository{
db.On("CreateRepository", context.TODO(), mock.Anything).Return(&apiclient.TestRepositoryResponse{}).Return(&appsv1.Repository{
Repo: "repo",
Project: "proj",
}, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, settingsMgr)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
repo, err := s.CreateRepository(context.TODO(), &repository.RepoCreateRequest{
Repo: &v1alpha1.Repository{
Repo: &appsv1.Repository{
Repo: "test",
Username: "test",
},
@@ -178,16 +259,16 @@ func TestRepositoryServer(t *testing.T) {
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), "test").Return(&v1alpha1.Repository{
db.On("GetRepository", context.TODO(), "test").Return(&appsv1.Repository{
Repo: "test",
Username: "test",
}, nil)
db.On("CreateRepository", context.TODO(), mock.Anything).Return(nil, status.Errorf(codes.AlreadyExists, "repository already exists"))
db.On("UpdateRepository", context.TODO(), mock.Anything).Return(nil, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, settingsMgr)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
repo, err := s.CreateRepository(context.TODO(), &repository.RepoCreateRequest{
Repo: &v1alpha1.Repository{
Repo: &appsv1.Repository{
Repo: "test",
Username: "test",
},
@@ -200,6 +281,295 @@ func TestRepositoryServer(t *testing.T) {
}
func TestRepositoryServerListApps(t *testing.T) {
kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret)
settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace)
t.Run("Test_WithoutAppCreateUpdatePrivileges", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
enforcer.SetDefaultRole("role:readonly")
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
appLister, projLister := newAppAndProjLister(defaultProj)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{
Repo: "https://test",
Revision: "HEAD",
AppName: "foo",
AppProject: "default",
})
assert.Nil(t, resp)
assert.Equal(t, err, errPermissionDenied)
})
t.Run("Test_WithAppCreateUpdatePrivileges", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
enforcer.SetDefaultRole("role:admin")
appLister, projLister := newAppAndProjLister(defaultProj)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
repoServerClient.On("ListApps", context.TODO(), mock.Anything).Return(&apiclient.AppList{
Apps: map[string]string{
"path/to/dir": "Kustomize",
},
}, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{
Repo: "https://test",
Revision: "HEAD",
AppName: "foo",
AppProject: "default",
})
assert.NoError(t, err)
assert.Len(t, resp.Items, 1)
assert.Equal(t, "path/to/dir", resp.Items[0].Path)
assert.Equal(t, "Kustomize", resp.Items[0].Type)
})
t.Run("Test_WithAppCreateUpdatePrivilegesRepoNotAllowed", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
enforcer.SetDefaultRole("role:admin")
appLister, projLister := newAppAndProjLister(defaultProjNoSources)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
repoServerClient.On("ListApps", context.TODO(), mock.Anything).Return(&apiclient.AppList{
Apps: map[string]string{
"path/to/dir": "Kustomize",
},
}, nil)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{
Repo: "https://test",
Revision: "HEAD",
AppName: "foo",
AppProject: "default",
})
assert.Nil(t, resp)
assert.Error(t, err, "repository 'https://test' not permitted in project 'default'")
})
}
func TestRepositoryServerGetAppDetails(t *testing.T) {
kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret)
settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace)
t.Run("Test_WithoutRepoReadPrivileges", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
enforcer.SetDefaultRole("")
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
appLister, projLister := newAppAndProjLister(defaultProj)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: &appsv1.ApplicationSource{
RepoURL: url,
},
AppName: "newapp",
AppProject: "default",
})
assert.Nil(t, resp)
assert.Error(t, err, "rpc error: code = PermissionDenied desc = permission denied: repositories, get, https://test")
})
t.Run("Test_WithoutAppReadPrivileges", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
_ = enforcer.SetUserPolicy("p, role:readrepos, repositories, get, *, allow")
enforcer.SetDefaultRole("role:readrepos")
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
appLister, projLister := newAppAndProjLister(defaultProj)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: &appsv1.ApplicationSource{
RepoURL: url,
},
AppName: "newapp",
AppProject: "default",
})
assert.Nil(t, resp)
assert.Error(t, err, "rpc error: code = PermissionDenied desc = permission denied: applications, get, default/newapp")
})
t.Run("Test_WithoutCreatePrivileges", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
enforcer.SetDefaultRole("role:readonly")
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
appLister, projLister := newAppAndProjLister(defaultProj)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: &appsv1.ApplicationSource{
RepoURL: url,
},
AppName: "newapp",
AppProject: "default",
})
assert.Nil(t, resp)
assert.Error(t, err, "rpc error: code = PermissionDenied desc = permission denied: applications, create, default/newapp")
})
t.Run("Test_WithCreatePrivileges", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil)
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"}
repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil)
appLister, projLister := newAppAndProjLister(defaultProj)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: &appsv1.ApplicationSource{
RepoURL: url,
},
AppName: "newapp",
AppProject: "default",
})
assert.NoError(t, err)
assert.Equal(t, expectedResp, *resp)
})
t.Run("Test_RepoNotPermitted", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"}
repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil)
appLister, projLister := newAppAndProjLister(defaultProjNoSources)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: &appsv1.ApplicationSource{
RepoURL: url,
},
AppName: "newapp",
AppProject: "default",
})
assert.Error(t, err, "repository 'https://test' not permitted in project 'default'")
assert.Nil(t, resp)
})
t.Run("Test_ExistingApp", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil)
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"}
repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil)
appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: &guestbookApp.Spec.Source,
AppName: "guestbook",
AppProject: "default",
})
assert.NoError(t, err)
assert.Equal(t, expectedResp, *resp)
})
t.Run("Test_ExistingAppMismatchedProjectName", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: &guestbookApp.Spec.Source,
AppName: "guestbook",
AppProject: "mismatch",
})
assert.Equal(t, errPermissionDenied, err)
assert.Nil(t, resp)
})
t.Run("Test_ExistingAppSourceNotInHistory", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp)
differentSource := guestbookApp.Spec.Source.DeepCopy()
differentSource.Helm.ValueFiles = []string{"/etc/passwd"}
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: differentSource,
AppName: "guestbook",
AppProject: "default",
})
assert.Equal(t, errPermissionDenied, err)
assert.Nil(t, resp)
})
t.Run("Test_ExistingAppSourceInHistory", func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
url := "https://test"
db := &dbmocks.ArgoDB{}
db.On("GetRepository", context.TODO(), url).Return(&appsv1.Repository{Repo: url}, nil)
db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil)
expectedResp := apiclient.RepoAppDetailsResponse{Type: "Directory"}
repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil)
appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp)
previousSource := guestbookApp.Status.History[0].Source.DeepCopy()
previousSource.TargetRevision = guestbookApp.Status.History[0].Revision
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: previousSource,
AppName: "guestbook",
AppProject: "default",
})
assert.NoError(t, err)
assert.Equal(t, expectedResp, *resp)
})
}
type fixtures struct {
*cache.Cache
}

View File

@@ -11,6 +11,7 @@ import (
"net/url"
"os"
"os/exec"
"reflect"
"regexp"
go_runtime "runtime"
"strings"
@@ -155,6 +156,7 @@ type ArgoCDServer struct {
settingsMgr *settings_util.SettingsManager
enf *rbac.Enforcer
projInformer cache.SharedIndexInformer
projLister applisters.AppProjectNamespaceLister
policyEnforcer *rbacpolicy.RBACPolicyEnforcer
appInformer cache.SharedIndexInformer
appLister applisters.ApplicationNamespaceLister
@@ -249,6 +251,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer {
settingsMgr: settingsMgr,
enf: enf,
projInformer: projInformer,
projLister: projLister,
appInformer: appInformer,
appLister: appLister,
policyEnforcer: policyEnf,
@@ -406,6 +409,22 @@ func (a *ArgoCDServer) Shutdown() {
}
}
func checkOIDCConfigChange(currentOIDCConfig *settings_util.OIDCConfig, newArgoCDSettings *settings_util.ArgoCDSettings) bool {
newOIDCConfig := newArgoCDSettings.OIDCConfig()
if (currentOIDCConfig != nil && newOIDCConfig == nil) || (currentOIDCConfig == nil && newOIDCConfig != nil) {
return true
}
if currentOIDCConfig != nil && newOIDCConfig != nil {
if !reflect.DeepEqual(*currentOIDCConfig, *newOIDCConfig) {
return true
}
}
return false
}
// watchSettings watches the configmap and secret for any setting updates that would warrant a
// restart of the API server.
func (a *ArgoCDServer) watchSettings() {
@@ -413,7 +432,7 @@ func (a *ArgoCDServer) watchSettings() {
a.settingsMgr.Subscribe(updateCh)
prevURL := a.settings.URL
prevOIDCConfig := a.settings.OIDCConfigRAW
prevOIDCConfig := a.settings.OIDCConfig()
prevDexCfgBytes, err := dex.GenerateDexConfigYAML(a.settings)
errors.CheckError(err)
prevGitHubSecret := a.settings.WebhookGitHubSecret
@@ -435,7 +454,7 @@ func (a *ArgoCDServer) watchSettings() {
log.Infof("dex config modified. restarting")
break
}
if prevOIDCConfig != a.settings.OIDCConfigRAW {
if checkOIDCConfigChange(prevOIDCConfig, a.settings) {
log.Infof("oidc config modified. restarting")
break
}
@@ -563,7 +582,7 @@ func (a *ArgoCDServer) newGRPCServer() *grpc.Server {
db := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset)
kubectl := kubeutil.NewKubectl()
clusterService := cluster.NewServer(db, a.enf, a.Cache, kubectl)
repoService := repository.NewServer(a.RepoClientset, db, a.enf, a.Cache, a.settingsMgr)
repoService := repository.NewServer(a.RepoClientset, db, a.enf, a.Cache, a.appLister, a.projLister, a.settingsMgr)
repoCredsService := repocreds.NewServer(a.RepoClientset, db, a.enf, a.settingsMgr)
var loginRateLimiter func() (io.Closer, error)
if maxConcurrentLoginRequestsCount > 0 {

View File

@@ -8,6 +8,7 @@ import (
"testing"
"time"
"github.com/ghodss/yaml"
"github.com/golang-jwt/jwt/v4"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
@@ -27,6 +28,7 @@ import (
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/argo-cd/v2/util/rbac"
settings_util "github.com/argoproj/argo-cd/v2/util/settings"
)
func fakeServer() (*ArgoCDServer, func()) {
@@ -545,3 +547,128 @@ func TestInitializeDefaultProject_ProjectAlreadyInitialized(t *testing.T) {
assert.Equal(t, proj.Spec, existingDefaultProject.Spec)
}
func TestOIDCConfigChangeDetection_SecretsChanged(t *testing.T) {
//Given
rawOIDCConfig, err := yaml.Marshal(&settings_util.OIDCConfig{
ClientID: "$k8ssecret:clientid",
ClientSecret: "$k8ssecret:clientsecret"})
assert.NoError(t, err, "no error expected when marshalling OIDC config")
originalSecrets := map[string]string{"k8ssecret:clientid": "argocd", "k8ssecret:clientsecret": "sharedargooauthsecret"}
argoSettings := settings_util.ArgoCDSettings{OIDCConfigRAW: string(rawOIDCConfig), Secrets: originalSecrets}
originalOIDCConfig := argoSettings.OIDCConfig()
assert.Equal(t, originalOIDCConfig.ClientID, originalSecrets["k8ssecret:clientid"], "expected ClientID be replaced by secret value")
assert.Equal(t, originalOIDCConfig.ClientSecret, originalSecrets["k8ssecret:clientsecret"], "expected ClientSecret be replaced by secret value")
//When
newSecrets := map[string]string{"k8ssecret:clientid": "argocd", "k8ssecret:clientsecret": "a!Better!Secret"}
argoSettings.Secrets = newSecrets
result := checkOIDCConfigChange(originalOIDCConfig, &argoSettings)
//Then
assert.Equal(t, result, true, "secrets have changed, expect interpolated OIDCConfig to change")
}
func TestOIDCConfigChangeDetection_ConfigChanged(t *testing.T) {
//Given
rawOIDCConfig, err := yaml.Marshal(&settings_util.OIDCConfig{
Name: "argocd",
ClientID: "$k8ssecret:clientid",
ClientSecret: "$k8ssecret:clientsecret"})
assert.NoError(t, err, "no error expected when marshalling OIDC config")
originalSecrets := map[string]string{"k8ssecret:clientid": "argocd", "k8ssecret:clientsecret": "sharedargooauthsecret"}
argoSettings := settings_util.ArgoCDSettings{OIDCConfigRAW: string(rawOIDCConfig), Secrets: originalSecrets}
originalOIDCConfig := argoSettings.OIDCConfig()
assert.Equal(t, originalOIDCConfig.ClientID, originalSecrets["k8ssecret:clientid"], "expected ClientID be replaced by secret value")
assert.Equal(t, originalOIDCConfig.ClientSecret, originalSecrets["k8ssecret:clientsecret"], "expected ClientSecret be replaced by secret value")
//When
newRawOICDConfig, err := yaml.Marshal(&settings_util.OIDCConfig{
Name: "cat",
ClientID: "$k8ssecret:clientid",
ClientSecret: "$k8ssecret:clientsecret"})
assert.NoError(t, err, "no error expected when marshalling OIDC config")
argoSettings.OIDCConfigRAW = string(newRawOICDConfig)
result := checkOIDCConfigChange(originalOIDCConfig, &argoSettings)
//Then
assert.Equal(t, result, true, "no error expected since OICD config created")
}
func TestOIDCConfigChangeDetection_ConfigCreated(t *testing.T) {
//Given
argoSettings := settings_util.ArgoCDSettings{OIDCConfigRAW: ""}
originalOIDCConfig := argoSettings.OIDCConfig()
//When
newRawOICDConfig, err := yaml.Marshal(&settings_util.OIDCConfig{
Name: "cat",
ClientID: "$k8ssecret:clientid",
ClientSecret: "$k8ssecret:clientsecret"})
assert.NoError(t, err, "no error expected when marshalling OIDC config")
newSecrets := map[string]string{"k8ssecret:clientid": "argocd", "k8ssecret:clientsecret": "sharedargooauthsecret"}
argoSettings.OIDCConfigRAW = string(newRawOICDConfig)
argoSettings.Secrets = newSecrets
result := checkOIDCConfigChange(originalOIDCConfig, &argoSettings)
//Then
assert.Equal(t, result, true, "no error expected since new OICD config created")
}
func TestOIDCConfigChangeDetection_ConfigDeleted(t *testing.T) {
//Given
rawOIDCConfig, err := yaml.Marshal(&settings_util.OIDCConfig{
ClientID: "$k8ssecret:clientid",
ClientSecret: "$k8ssecret:clientsecret"})
assert.NoError(t, err, "no error expected when marshalling OIDC config")
originalSecrets := map[string]string{"k8ssecret:clientid": "argocd", "k8ssecret:clientsecret": "sharedargooauthsecret"}
argoSettings := settings_util.ArgoCDSettings{OIDCConfigRAW: string(rawOIDCConfig), Secrets: originalSecrets}
originalOIDCConfig := argoSettings.OIDCConfig()
assert.Equal(t, originalOIDCConfig.ClientID, originalSecrets["k8ssecret:clientid"], "expected ClientID be replaced by secret value")
assert.Equal(t, originalOIDCConfig.ClientSecret, originalSecrets["k8ssecret:clientsecret"], "expected ClientSecret be replaced by secret value")
//When
argoSettings.OIDCConfigRAW = ""
argoSettings.Secrets = make(map[string]string)
result := checkOIDCConfigChange(originalOIDCConfig, &argoSettings)
//Then
assert.Equal(t, result, true, "no error expected since OICD config deleted")
}
func TestOIDCConfigChangeDetection_NoChange(t *testing.T) {
//Given
rawOIDCConfig, err := yaml.Marshal(&settings_util.OIDCConfig{
ClientID: "$k8ssecret:clientid",
ClientSecret: "$k8ssecret:clientsecret"})
assert.NoError(t, err, "no error expected when marshalling OIDC config")
originalSecrets := map[string]string{"k8ssecret:clientid": "argocd", "k8ssecret:clientsecret": "sharedargooauthsecret"}
argoSettings := settings_util.ArgoCDSettings{OIDCConfigRAW: string(rawOIDCConfig), Secrets: originalSecrets}
originalOIDCConfig := argoSettings.OIDCConfig()
assert.Equal(t, originalOIDCConfig.ClientID, originalSecrets["k8ssecret:clientid"], "expected ClientID be replaced by secret value")
assert.Equal(t, originalOIDCConfig.ClientSecret, originalSecrets["k8ssecret:clientsecret"], "expected ClientSecret be replaced by secret value")
//When
result := checkOIDCConfigChange(originalOIDCConfig, &argoSettings)
//Then
assert.Equal(t, result, false, "no error since no config change")
}

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